@marimo-team/frontend 0.21.2-dev5 → 0.21.2-dev52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/dist/assets/{CellStatus-CDSBsjjF.js → CellStatus-DX8MnBMk.js} +1 -1
  2. package/dist/assets/{ConnectedDataExplorerComponent-Buaffg3u.js → ConnectedDataExplorerComponent-7yXYooWG.js} +1 -1
  3. package/dist/assets/{DeferredRequestRegistry-O6RDJKs0.js → DeferredRequestRegistry-B8jPCuU1.js} +1 -1
  4. package/dist/assets/{ImperativeModal-qEtcJ95s.js → ImperativeModal-C3CD5-Aq.js} +1 -1
  5. package/dist/assets/JsonOutput-DqjAyzM8.js +46 -0
  6. package/dist/assets/{LazyAnyLanguageCodeMirror-m8w66E4s.js → LazyAnyLanguageCodeMirror-CcCHIX38.js} +2 -2
  7. package/dist/assets/{MarimoErrorOutput-az74f3Mp.js → MarimoErrorOutput-Dat_S09q.js} +5 -5
  8. package/dist/assets/RenderHTML-C7XM39M2.js +1 -0
  9. package/dist/assets/{add-cell-with-ai-DUn4LN4W.js → add-cell-with-ai-y2xroEGf.js} +9 -9
  10. package/dist/assets/{add-connection-dialog-CBz0AUVX.js → add-connection-dialog-QDBOmil3.js} +23 -23
  11. package/dist/assets/{agent-panel-u83dsDsM.js → agent-panel-DziFrEjJ.js} +6 -6
  12. package/dist/assets/ai-model-dropdown-CiJpv5wN.js +5 -0
  13. package/dist/assets/{alert-dialog-9WfvUF7e.js → alert-dialog-ebk_-wsU.js} +1 -1
  14. package/dist/assets/{any-language-editor-DwQMnAM3.js → any-language-editor-DZYnKlJB.js} +1 -1
  15. package/dist/assets/{app-config-button-rDu-lCIB.js → app-config-button-CpAv9Tiu.js} +1 -1
  16. package/dist/assets/{architectureDiagram-VXUJARFQ-DfMHHFZ3.js → architectureDiagram-VXUJARFQ-DKmk99ac.js} +1 -1
  17. package/dist/assets/{azure-BTXHztTw.js → azure-Dw5gKmUz.js} +1 -1
  18. package/dist/assets/{blockDiagram-VD42YOAC-CuEDwbg7.js → blockDiagram-VD42YOAC-TpAhP5OQ.js} +1 -1
  19. package/dist/assets/{c4Diagram-YG6GDRKO-CD9uz7WG.js → c4Diagram-YG6GDRKO-Dg8hCyKf.js} +1 -1
  20. package/dist/assets/{cache-panel-qIxnndwr.js → cache-panel-D0OsHk_D.js} +1 -1
  21. package/dist/assets/cell-editor-RbAVpSFb.js +22 -0
  22. package/dist/assets/{cell-link-Q_UEP94Z.js → cell-link-CNgO3c-T.js} +1 -1
  23. package/dist/assets/{cells-fq1RMGX_.js → cells-39RE4UzS.js} +77 -76
  24. package/dist/assets/channel-D1wPYhc9.js +1 -0
  25. package/dist/assets/{chat-display-D_Fuuy6r.js → chat-display-BPUVrlA6.js} +1 -1
  26. package/dist/assets/{chat-panel-BO-JoQSp.js → chat-panel-esz5TfF-.js} +2 -2
  27. package/dist/assets/{chunk-5FQGJX7Z-CM1a_K7I.js → chunk-5FQGJX7Z-sGWxL7Ey.js} +3 -3
  28. package/dist/assets/{chunk-ABZYJK2D-D_Wumzom.js → chunk-ABZYJK2D-DXJ7hnjx.js} +1 -1
  29. package/dist/assets/{chunk-ATLVNIR6-BZ0lTgIn.js → chunk-ATLVNIR6-CTEqcLEc.js} +1 -1
  30. package/dist/assets/{chunk-B4BG7PRW-Dw1S6osV.js → chunk-B4BG7PRW-CkAIqtPf.js} +1 -1
  31. package/dist/assets/{chunk-DI55MBZ5-Q63FTCPP.js → chunk-DI55MBZ5-C4F9vu8o.js} +1 -1
  32. package/dist/assets/{chunk-EXTU4WIE-CfkJ_R7W.js → chunk-EXTU4WIE-BT0Py-4P.js} +1 -1
  33. package/dist/assets/{chunk-JA3XYJ7Z-B41fGeoj.js → chunk-JA3XYJ7Z-CGd7jja_.js} +1 -1
  34. package/dist/assets/{chunk-JZLCHNYA-D43EJxQw.js → chunk-JZLCHNYA-CqY-RYTj.js} +1 -1
  35. package/dist/assets/{chunk-N4CR4FBY-DCtw0-ni.js → chunk-N4CR4FBY-aUDjVzN7.js} +2 -2
  36. package/dist/assets/{chunk-QN33PNHL-CLA2rsaS.js → chunk-QN33PNHL-DHnCb5-U.js} +1 -1
  37. package/dist/assets/{chunk-QXUST7PY-De1DpbnL.js → chunk-QXUST7PY-CRO5kYCE.js} +1 -1
  38. package/dist/assets/{chunk-S3R3BYOJ-qrwvlUdq.js → chunk-S3R3BYOJ-CSHQgcuP.js} +1 -1
  39. package/dist/assets/{chunk-TZMSLE5B-C4KcThb0.js → chunk-TZMSLE5B-CE7o9asH.js} +1 -1
  40. package/dist/assets/classDiagram-2ON5EDUG-BDIQSKYv.js +1 -0
  41. package/dist/assets/classDiagram-v2-WZHVMYZB-Cdh4cVOB.js +1 -0
  42. package/dist/assets/{code-block-37QAKDTI-D4FF4cnN.js → code-block-37QAKDTI-DMpe1jNG.js} +1 -1
  43. package/dist/assets/{column-preview-WsubyItX.js → column-preview-BUKHsglA.js} +1 -1
  44. package/dist/assets/{command-rfxSsiHU.js → command-DmzEbs6L.js} +1 -1
  45. package/dist/assets/{command-palette-Bez4BqJF.js → command-palette-BX5gNpUr.js} +1 -1
  46. package/dist/assets/{common-BYwO983A.js → common-B4yshY-H.js} +1 -1
  47. package/dist/assets/{components-Ozq0825a.js → components-DCqJqyys.js} +1 -1
  48. package/dist/assets/{components-Bpgzv_5_.js → components-oKCjx6cN.js} +1 -1
  49. package/dist/assets/{config-3Aq84phF.js → config-DqxNMQDN.js} +1 -1
  50. package/dist/assets/{context-CIAP2NOh.js → context-CRmPPhx9.js} +1 -1
  51. package/dist/assets/{context-aware-panel-CfsfBlhO.js → context-aware-panel-DC0Te9Hj.js} +2 -2
  52. package/dist/assets/copy-KjcPgPw9.js +1 -0
  53. package/dist/assets/{copy-icon-BgmMM9Zg.js → copy-icon-P0kzz1Pr.js} +1 -1
  54. package/dist/assets/{dagre-6UL2VRFP-BhMnPhuU.js → dagre-6UL2VRFP-XqoNLMQ3.js} +1 -1
  55. package/dist/assets/{data-grid-overlay-editor-kbv73SQ7.js → data-grid-overlay-editor-Cus1-BFN.js} +1 -1
  56. package/dist/assets/{datasource-F9sJtuof.js → datasource-DKHG39NV.js} +2 -2
  57. package/dist/assets/{dates-CHaNfieI.js → dates-CTqMeMGY.js} +1 -1
  58. package/dist/assets/{dependency-graph-panel-AOBcX2tP.js → dependency-graph-panel-7GKT3dyD.js} +4 -4
  59. package/dist/assets/{diagram-PSM6KHXK-Cr2t4zul.js → diagram-PSM6KHXK-BuzKNNcN.js} +1 -1
  60. package/dist/assets/{diagram-QEK2KX5R-DLU_hSO4.js → diagram-QEK2KX5R-A5LBQS11.js} +1 -1
  61. package/dist/assets/{diagram-S2PKOQOG-C7EkNAO3.js → diagram-S2PKOQOG-dkJE8SA0.js} +1 -1
  62. package/dist/assets/{dialog-CVN1lcMF.js → dialog-1_jIyAb_.js} +1 -1
  63. package/dist/assets/{dist-DJBpXGro.js → dist-6P6vjf93.js} +1 -1
  64. package/dist/assets/dist-BWGxTsTP.js +1 -0
  65. package/dist/assets/{dist-CblX3KGI.js → dist-B_buFm3B.js} +1 -1
  66. package/dist/assets/{dist-CXLJUPFl.js → dist-BatEf-0f.js} +1 -1
  67. package/dist/assets/dist-C3AnARPE.js +1 -0
  68. package/dist/assets/{dist-BNC_tnlW.js → dist-C6ohaMKU.js} +1 -1
  69. package/dist/assets/{dist-BoDHthoc.js → dist-CO9Pg2Rc.js} +1 -1
  70. package/dist/assets/{dist-By6zhkxZ.js → dist-CSV6H5w_.js} +1 -1
  71. package/dist/assets/{dist-6FIAeDIu.js → dist-CYs1oP7g.js} +1 -1
  72. package/dist/assets/{dist-DbK_4_qo.js → dist-DD9ZJMK5.js} +1 -1
  73. package/dist/assets/{dist-DlTbNRBn.js → dist-DReDpc2z.js} +1 -1
  74. package/dist/assets/dist-DSlq5ZeQ.js +1 -0
  75. package/dist/assets/{dist-DrceDAhM.js → dist-DXyIIB32.js} +1 -1
  76. package/dist/assets/{dist-CcGcwrUD.js → dist-DkaderFA.js} +1 -1
  77. package/dist/assets/{dist-BiZQlfhr.js → dist-Dq3BlK4R.js} +1 -1
  78. package/dist/assets/{dist-ClzRAVN-.js → dist-Dxov2ltb.js} +1 -1
  79. package/dist/assets/{dist-BXXPfIam.js → dist-EtGG9C1A.js} +1 -1
  80. package/dist/assets/{dist-C3MmXcLA.js → dist-NjId5Gdz.js} +1 -1
  81. package/dist/assets/dist-ZM59OWYL.js +1 -0
  82. package/dist/assets/dist-_TwZ4tIe.js +1 -0
  83. package/dist/assets/dist-f9b2H4q_.js +1 -0
  84. package/dist/assets/{dist-mxGLXOFm.js → dist-feWVQ4dq.js} +1 -1
  85. package/dist/assets/{documentation-panel-D28MpqbI.js → documentation-panel-D5d_BbHV.js} +1 -1
  86. package/dist/assets/{download-B9_ToVd4.js → download-B1vXaivj.js} +4 -4
  87. package/dist/assets/{dropdown-menu-DdPu5Kfu.js → dropdown-menu-BehqiLFL.js} +1 -1
  88. package/dist/assets/{edit-page-otS-QvnC.js → edit-page-B5cAZdO7.js} +7 -7
  89. package/dist/assets/{en-US-BO8E69bZ.js → en-US-f8tajDx1.js} +1 -1
  90. package/dist/assets/{erDiagram-Q2GNP2WA-DqlEo_Us.js → erDiagram-Q2GNP2WA-CgH6udOW.js} +1 -1
  91. package/dist/assets/{error-banner-BRG6IPhC.js → error-banner-J5F3weEj.js} +1 -1
  92. package/dist/assets/{error-panel-RRoj_iOR.js → error-panel-DnhKJ5Ou.js} +1 -1
  93. package/dist/assets/{es-CzkousWe.js → es-DYI7U61K.js} +1 -1
  94. package/dist/assets/{esm-CBkHtTOV.js → esm-BC1J92im.js} +1 -1
  95. package/dist/assets/{esm-DhTsVMLM.js → esm-DKLLCu3N.js} +1 -1
  96. package/dist/assets/{field-B1jGbQlH.js → field-B08lvxnl.js} +1 -1
  97. package/dist/assets/file-explorer-panel-BUk69TND.js +26 -0
  98. package/dist/assets/{file-icons-CWLHDa1J.js → file-icons-3DTS8ZM7.js} +1 -1
  99. package/dist/assets/{floating-outline-BvQKiC0F.js → floating-outline-DmugATcB.js} +1 -1
  100. package/dist/assets/{flowDiagram-NV44I4VS-CQlIJ12H.js → flowDiagram-NV44I4VS-D85BL4rA.js} +1 -1
  101. package/dist/assets/{focus-DYwTiH9-.js → focus-DlJH7sfh.js} +1 -1
  102. package/dist/assets/{form-CrQYrsUC.js → form-760_EqmF.js} +2 -2
  103. package/dist/assets/{formats-rhOJovGE.js → formats-wYuh1bqp.js} +1 -1
  104. package/dist/assets/{formatting-B4ZCH3ol.js → formatting-CraOPe94.js} +1 -1
  105. package/dist/assets/{gallery-page-eRea0yic.js → gallery-page--paiPvYX.js} +1 -1
  106. package/dist/assets/{ganttDiagram-JELNMOA3-B3EGIuZL.js → ganttDiagram-JELNMOA3-DzCOXWlF.js} +1 -1
  107. package/dist/assets/{gitGraphDiagram-V2S2FVAM-h5SlguJK.js → gitGraphDiagram-V2S2FVAM-BUHURX6t.js} +1 -1
  108. package/dist/assets/{glide-data-editor-xt5xNZeV.js → glide-data-editor-DYdoQTO5.js} +4 -4
  109. package/dist/assets/{globals-BsV5fVR-.js → globals-7M5DRsIb.js} +1 -1
  110. package/dist/assets/home-page-CxQ1e98h.js +4 -0
  111. package/dist/assets/{hooks-CHx5dUUq.js → hooks-C3jEff2O.js} +1 -1
  112. package/dist/assets/html-to-image-DTFXm6_Z.js +2 -0
  113. package/dist/assets/{index-GjXovVsl.css → index-BmoocKR0.css} +1 -1
  114. package/dist/assets/index-DNchElHl.js +38 -0
  115. package/dist/assets/{infoDiagram-HS3SLOUP-pzpClObZ.js → infoDiagram-HS3SLOUP-GG5r0Y5G.js} +1 -1
  116. package/dist/assets/{input-CUwqpKjd.js → input-CN1ZeRYm.js} +1 -1
  117. package/dist/assets/{isValid-BGe7pJXT.js → isValid-DY4Mgbr7.js} +1 -1
  118. package/dist/assets/{journeyDiagram-XKPGCS4Q-BrdRi92v.js → journeyDiagram-XKPGCS4Q-B1dvnV4D.js} +1 -1
  119. package/dist/assets/{kanban-definition-3W4ZIXB7-B6WqgFqh.js → kanban-definition-3W4ZIXB7-CefbrXQv.js} +1 -1
  120. package/dist/assets/{kiosk-mode-DNjEnIWb.js → kiosk-mode-CyTnrzwK.js} +1 -1
  121. package/dist/assets/{layout-CwFtCyW8.js → layout-3b3tzmbb.js} +3 -3
  122. package/dist/assets/{linear-BP9rwmWK.js → linear-BDnrHGYO.js} +1 -1
  123. package/dist/assets/{links-CIQwYQ48.js → links-CptYD1FP.js} +1 -1
  124. package/dist/assets/{logs-panel-BU1tNEVc.js → logs-panel-C4k_2IHW.js} +1 -1
  125. package/dist/assets/{markdown-renderer-MR9df58W.js → markdown-renderer-DSy5IuAx.js} +1 -1
  126. package/dist/assets/{menu-items-UxKrm8hS.js → menu-items-BpHXKv51.js} +1 -1
  127. package/dist/assets/mermaid-4DMBBIKO-g7AL4SLJ.js +1 -0
  128. package/dist/assets/{mermaid-Djr3jUAB.js → mermaid-C43VbdrM.js} +3 -3
  129. package/dist/assets/{mermaid-parser.core-DR82IMb2.js → mermaid-parser.core-CdM8D_p_.js} +1 -1
  130. package/dist/assets/{mindmap-definition-VGOIOE7T-DAmJpbPM.js → mindmap-definition-VGOIOE7T-CcV7D-wF.js} +1 -1
  131. package/dist/assets/{mode-AcL8c6qH.js → mode-D-iRbN9x.js} +1 -1
  132. package/dist/assets/{multi-map-Pp1P2DOX.js → multi-map-C8RbwBrw.js} +1 -1
  133. package/dist/assets/{name-cell-input-DVFEv_aO.js → name-cell-input-Dyb0ZO4X.js} +1 -1
  134. package/dist/assets/{number-overlay-editor-D__AflXQ.js → number-overlay-editor-BBJO1mf8.js} +1 -1
  135. package/dist/assets/{outline-panel-CP0oIuiU.js → outline-panel-D7CJwO8u.js} +1 -1
  136. package/dist/assets/{packages-panel-CzRELimG.js → packages-panel-Bp1SYjgc.js} +1 -1
  137. package/dist/assets/{panels-wTweRyIv.js → panels-D0aw6jdc.js} +1 -1
  138. package/dist/assets/{pieDiagram-ADFJNKIX-DbGIFRoq.js → pieDiagram-ADFJNKIX-C1fBf15W.js} +1 -1
  139. package/dist/assets/{popover-BPGG2gPG.js → popover-Bvoif-Mg.js} +1 -1
  140. package/dist/assets/{precisionRound-BOmLQIKI.js → precisionRound-CCOoIlcP.js} +1 -1
  141. package/dist/assets/{process-output-CTVsT--B.js → process-output-BxPWHcIi.js} +1 -1
  142. package/dist/assets/{quadrantDiagram-AYHSOK5B-CLAtyple.js → quadrantDiagram-AYHSOK5B-RVooN-fX.js} +1 -1
  143. package/dist/assets/{react-vega-BZav_-2n.js → react-vega-BKRQSy0g.js} +1 -1
  144. package/dist/assets/react-vega-DXESF7qN.js +1 -0
  145. package/dist/assets/{readonly-python-code-DH-1xZGq.js → readonly-python-code-D95oshJa.js} +1 -1
  146. package/dist/assets/{renderShortcut-CnD1Dah5.js → renderShortcut-BYvKm38e.js} +1 -1
  147. package/dist/assets/{request-registry-B-7cIM_I.js → request-registry-XB2EzJHm.js} +1 -1
  148. package/dist/assets/{requirementDiagram-UZGBJVZJ-DDDTB1LD.js → requirementDiagram-UZGBJVZJ-DtqOYJpH.js} +1 -1
  149. package/dist/assets/{run-page-FCvGnICa.js → run-page-B7CASued.js} +1 -1
  150. package/dist/assets/{sankeyDiagram-TZEHDZUN-DAWPOfBw.js → sankeyDiagram-TZEHDZUN-DmcooLA8.js} +1 -1
  151. package/dist/assets/{scratchpad-panel-k9lrm-rC.js → scratchpad-panel-BIVRgYOU.js} +1 -1
  152. package/dist/assets/{secrets-panel-B1Z-6dmz.js → secrets-panel-C24hZEiO.js} +1 -1
  153. package/dist/assets/{select-CxT2Geqr.js → select-Cnd3vm9n.js} +1 -1
  154. package/dist/assets/{sequenceDiagram-WL72ISMW-D_qAidD2.js → sequenceDiagram-WL72ISMW-S2qeLb7J.js} +1 -1
  155. package/dist/assets/{session-panel-WhN0qilM.js → session-panel-CNabBHQm.js} +1 -1
  156. package/dist/assets/{share-BdH_5I58.js → share-NjpZ54PJ.js} +1 -1
  157. package/dist/assets/{snippets-panel-BCDHUuku.js → snippets-panel-D1JAeJj1.js} +1 -1
  158. package/dist/assets/{spec-DbmSqx09.js → spec-DnVBmJUh.js} +1 -1
  159. package/dist/assets/{state-Ce7CVShi.js → state-BagvlaEz.js} +1 -1
  160. package/dist/assets/{state-3V5UxC3B.js → state-Cz_wrzCz.js} +1 -1
  161. package/dist/assets/{state-CBmCYWFH.js → state-DMQXxemS.js} +1 -1
  162. package/dist/assets/{stateDiagram-FKZM4ZOC-C7qgDrGA.js → stateDiagram-FKZM4ZOC-uuQ60pIl.js} +1 -1
  163. package/dist/assets/stateDiagram-v2-4FDKWEC3-D-GWhQTG.js +1 -0
  164. package/dist/assets/stex-CruVQx-P.js +1 -0
  165. package/dist/assets/{switch-CVKxYu_0.js → switch-Bwpd2AFq.js} +1 -1
  166. package/dist/assets/{terminal-Cr7wbEjz.js → terminal-Gl8Fi44y.js} +1 -1
  167. package/dist/assets/{time-D2GKc0U6.js → time-Bw8f15NM.js} +1 -1
  168. package/dist/assets/{timeline-definition-IT6M3QCI-hd6uJKGs.js → timeline-definition-IT6M3QCI-TKWeDnSQ.js} +1 -1
  169. package/dist/assets/{toggle-RCwU-rnE.js → toggle-C_gNjXg8.js} +1 -1
  170. package/dist/assets/{tooltip-D9723Brr.js → tooltip-CR_izE8Q.js} +1 -1
  171. package/dist/assets/tracing-DwAC7DWN.js +1 -0
  172. package/dist/assets/tracing-panel-D1iNgclL.js +2 -0
  173. package/dist/assets/{tree-Ch2-GuhG.js → tree-WVrWjdwv.js} +3 -3
  174. package/dist/assets/{useAddCell-YC7rpcmD.js → useAddCell-D6Q7JziZ.js} +1 -1
  175. package/dist/assets/{useBoolean-m1e6E3Ao.js → useBoolean-CrltYVhE.js} +1 -1
  176. package/dist/assets/{useCellActionButton-GUb2fXU8.js → useCellActionButton-B2G9OaX9.js} +1 -1
  177. package/dist/assets/{useDateFormatter-CpE7XQLs.js → useDateFormatter-DOoVZUts.js} +1 -1
  178. package/dist/assets/{useDeleteCell-DRUDRiy0.js → useDeleteCell-d8veThW7.js} +1 -1
  179. package/dist/assets/{useDependencyPanelTab-nFVMlEx0.js → useDependencyPanelTab-B3iIj3MO.js} +1 -1
  180. package/dist/assets/{useInstallPackage-C9V-on2J.js → useInstallPackage-CQEr5429.js} +1 -1
  181. package/dist/assets/{useNotebookActions-ChLHy-0O.js → useNotebookActions-SAEOWcBo.js} +1 -1
  182. package/dist/assets/{useNumberFormatter-DbDKSvEd.js → useNumberFormatter-BXZcbTzH.js} +1 -1
  183. package/dist/assets/{usePress-BHGkpw8X.js → usePress-alQ5Crny.js} +1 -1
  184. package/dist/assets/{useRunCells-5m6jCnyo.js → useRunCells-Dhl8ZTGh.js} +1 -1
  185. package/dist/assets/{useSplitCell-DGD9smMq.js → useSplitCell-BSnFazbH.js} +1 -1
  186. package/dist/assets/{utils-CdjCA1J8.js → utils-C24l2A1T.js} +1 -1
  187. package/dist/assets/{vega-component-CRbeDmeM.js → vega-component-9Pf4pVZL.js} +1 -1
  188. package/dist/assets/{vega-loader.browser-CZV6_g2i.js → vega-loader.browser-BJ9oKrvH.js} +1 -1
  189. package/dist/assets/{write-secret-modal-BCvuRAFb.js → write-secret-modal-BFCsWMoW.js} +1 -1
  190. package/dist/assets/{xychartDiagram-PRI3JC2R-CXlUBSbQ.js → xychartDiagram-PRI3JC2R-CIp-yeSa.js} +1 -1
  191. package/dist/index.html +125 -125
  192. package/package.json +1 -1
  193. package/src/__mocks__/notebook.ts +9 -9
  194. package/src/__tests__/branded.ts +20 -0
  195. package/src/components/app-config/user-config-form.tsx +5 -4
  196. package/src/components/data-table/__tests__/utils.test.ts +138 -1
  197. package/src/components/data-table/charts/__tests__/storage.test.ts +7 -7
  198. package/src/components/data-table/context-menu.tsx +9 -5
  199. package/src/components/data-table/data-table.tsx +3 -0
  200. package/src/components/data-table/range-focus/__tests__/atoms.test.ts +8 -2
  201. package/src/components/data-table/range-focus/__tests__/test-utils.ts +2 -0
  202. package/src/components/data-table/range-focus/__tests__/utils.test.ts +82 -8
  203. package/src/components/data-table/range-focus/atoms.ts +2 -2
  204. package/src/components/data-table/range-focus/utils.ts +50 -12
  205. package/src/components/data-table/types.ts +7 -0
  206. package/src/components/data-table/utils.ts +87 -0
  207. package/src/components/editor/__tests__/data-attributes.test.tsx +8 -8
  208. package/src/components/editor/ai/__tests__/completion-utils.test.ts +15 -15
  209. package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -2
  210. package/src/components/editor/navigation/__tests__/selection.test.ts +7 -6
  211. package/src/components/editor/navigation/__tests__/state.test.ts +8 -7
  212. package/src/components/editor/output/MarimoErrorOutput.tsx +7 -7
  213. package/src/components/editor/output/__tests__/traceback.test.tsx +4 -4
  214. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +4 -4
  215. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +8 -1
  216. package/src/components/storage/storage-file-viewer.tsx +35 -1
  217. package/src/components/storage/storage-inspector.tsx +9 -4
  218. package/src/components/storage/storage-snippets.ts +3 -3
  219. package/src/components/tracing/tracing.tsx +3 -1
  220. package/src/components/ui/range-slider.tsx +108 -1
  221. package/src/core/ai/__tests__/staged-cells.test.ts +9 -8
  222. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +31 -31
  223. package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -3
  224. package/src/core/ai/context/providers/__tests__/tables.test.ts +3 -2
  225. package/src/core/ai/context/providers/__tests__/variable.test.ts +84 -63
  226. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +10 -9
  227. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +6 -6
  228. package/src/core/ai/tools/edit-notebook-tool.ts +3 -3
  229. package/src/core/cells/__tests__/add-missing-import.test.ts +3 -3
  230. package/src/core/cells/__tests__/cells.test.ts +192 -135
  231. package/src/core/cells/__tests__/focus.test.ts +5 -4
  232. package/src/core/cells/__tests__/logs.test.ts +13 -12
  233. package/src/core/cells/__tests__/pending-delete-service.test.tsx +3 -3
  234. package/src/core/cells/__tests__/runs.test.ts +22 -21
  235. package/src/core/cells/__tests__/scrollCellIntoView.test.ts +8 -7
  236. package/src/core/cells/__tests__/session.test.ts +23 -22
  237. package/src/core/cells/cells.ts +1 -1
  238. package/src/core/cells/ids.ts +5 -5
  239. package/src/core/cells/logs.ts +2 -2
  240. package/src/core/cells/runs.ts +6 -8
  241. package/src/core/codemirror/__tests__/format.test.ts +34 -36
  242. package/src/core/codemirror/__tests__/setup.test.ts +2 -2
  243. package/src/core/codemirror/cells/__tests__/extensions.test.ts +114 -0
  244. package/src/core/codemirror/cells/__tests__/traceback-decorations.test.ts +33 -32
  245. package/src/core/codemirror/cells/extensions.ts +66 -23
  246. package/src/core/codemirror/completion/__tests__/keymap.test.ts +15 -35
  247. package/src/core/codemirror/completion/keymap.ts +14 -4
  248. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +12 -13
  249. package/src/core/codemirror/language/__tests__/utils.test.ts +3 -3
  250. package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +7 -8
  251. package/src/core/codemirror/language/languages/python.ts +4 -0
  252. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +4 -3
  253. package/src/core/codemirror/lsp/notebook-lsp.ts +28 -2
  254. package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +7 -6
  255. package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
  256. package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +52 -0
  257. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  258. package/src/core/datasets/__tests__/data-source.test.ts +5 -6
  259. package/src/core/datasets/state.ts +1 -1
  260. package/src/core/errors/__tests__/errors.test.ts +2 -1
  261. package/src/core/export/__tests__/hooks.test.ts +37 -36
  262. package/src/core/islands/main.ts +2 -7
  263. package/src/core/kernel/__tests__/handlers.test.ts +5 -4
  264. package/src/core/kernel/handlers.ts +7 -4
  265. package/src/core/network/DeferredRequestRegistry.ts +2 -2
  266. package/src/core/network/__tests__/CachingRequestRegistry.test.ts +9 -10
  267. package/src/core/network/__tests__/DeferredRequestRegistry.test.ts +4 -6
  268. package/src/core/static/__tests__/virtual-file-tracker.test.ts +8 -8
  269. package/src/core/static/virtual-file-tracker.ts +1 -1
  270. package/src/core/storage/__tests__/state.test.ts +31 -21
  271. package/src/core/storage/state.ts +1 -1
  272. package/src/core/variables/__tests__/state.test.ts +6 -6
  273. package/src/core/variables/types.ts +2 -2
  274. package/src/core/wasm/__tests__/state.test.ts +8 -8
  275. package/src/core/websocket/useMarimoKernelConnection.tsx +12 -15
  276. package/src/css/md-tooltip.css +4 -39
  277. package/src/css/md.css +7 -0
  278. package/src/plugins/core/RenderHTML.tsx +17 -0
  279. package/src/plugins/core/__test__/RenderHTML.test.ts +45 -0
  280. package/src/plugins/core/sanitize-html.ts +25 -18
  281. package/src/plugins/impl/DataTablePlugin.tsx +23 -2
  282. package/src/plugins/impl/SliderPlugin.tsx +1 -3
  283. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +120 -0
  284. package/src/plugins/impl/anywidget/model.ts +1 -2
  285. package/src/stories/cell.stories.tsx +8 -8
  286. package/src/stories/layout/vertical/one-column.stories.tsx +9 -8
  287. package/src/stories/log-viewer.stories.tsx +8 -8
  288. package/src/stories/variables.stories.tsx +2 -2
  289. package/src/utils/__tests__/download.test.tsx +21 -20
  290. package/src/utils/copy.ts +18 -5
  291. package/src/utils/download.ts +4 -3
  292. package/src/utils/html-to-image.ts +6 -0
  293. package/src/utils/json/base64.ts +3 -3
  294. package/src/utils/traceback.ts +5 -3
  295. package/dist/assets/JsonOutput-DKXKGKvX.js +0 -46
  296. package/dist/assets/RenderHTML-DJ8khuob.js +0 -1
  297. package/dist/assets/ai-model-dropdown-DPTa_EpU.js +0 -5
  298. package/dist/assets/cell-editor-DX7IcqNr.js +0 -23
  299. package/dist/assets/channel-CkT8Qdo2.js +0 -1
  300. package/dist/assets/classDiagram-2ON5EDUG-BhMT_rTz.js +0 -1
  301. package/dist/assets/classDiagram-v2-WZHVMYZB-D-F4WEyb.js +0 -1
  302. package/dist/assets/copy-YwM0Pd7v.js +0 -1
  303. package/dist/assets/dist-BTqMkf4j.js +0 -1
  304. package/dist/assets/dist-DHw9sXeN.js +0 -1
  305. package/dist/assets/dist-Du0qZeXz.js +0 -1
  306. package/dist/assets/dist-a0FfbvMD.js +0 -1
  307. package/dist/assets/dist-cfkfP0ni.js +0 -1
  308. package/dist/assets/dist-pzQ9JG-p.js +0 -1
  309. package/dist/assets/file-explorer-panel-CB8vF5ob.js +0 -26
  310. package/dist/assets/home-page-itW0tRmv.js +0 -4
  311. package/dist/assets/html-to-image-BnSc-Wa0.js +0 -2
  312. package/dist/assets/index-0n92c_W7.js +0 -38
  313. package/dist/assets/mermaid-4DMBBIKO-PoHnhmy8.js +0 -1
  314. package/dist/assets/react-vega-Da-Ps9UW.js +0 -1
  315. package/dist/assets/stateDiagram-v2-4FDKWEC3-CEqeIlM0.js +0 -1
  316. package/dist/assets/stex-BBWVYm-R.js +0 -1
  317. package/dist/assets/tracing-DUVd0jtl.js +0 -1
  318. package/dist/assets/tracing-panel-CuTxPn_x.js +0 -2
  319. /package/dist/assets/{Combination-Cs9nbinQ.js → Combination-CSPK4t6z.js} +0 -0
  320. /package/dist/assets/{Deferred-BMfCOLaw.js → Deferred-CfyqLOPG.js} +0 -0
  321. /package/dist/assets/{SSRProvider-DC7ElCZZ.js → SSRProvider-CwqN9FWV.js} +0 -0
  322. /package/dist/assets/{badge-hTpPIsMT.js → badge-DImLVznf.js} +0 -0
  323. /package/dist/assets/{blob-CObhN-9g.js → blob-DgooIGjS.js} +0 -0
  324. /package/dist/assets/{bot-message-square-CK6eoGWy.js → bot-message-square-Dw41U6lL.js} +0 -0
  325. /package/dist/assets/{chart-no-axes-column-DV8gdCvH.js → chart-no-axes-column-a9XtWmzk.js} +0 -0
  326. /package/dist/assets/{check-BE0hEwVo.js → check-DZA_bRpw.js} +0 -0
  327. /package/dist/assets/{chevron-right-D0GQBpTb.js → chevron-right-CvVxySQk.js} +0 -0
  328. /package/dist/assets/{circle-check-gLIOLu8x.js → circle-check-CbaVeozR.js} +0 -0
  329. /package/dist/assets/{circle-play-DYGULlKZ.js → circle-play-DYn5nR6N.js} +0 -0
  330. /package/dist/assets/{circle-plus-CGG-gArM.js → circle-plus-nCze0-py.js} +0 -0
  331. /package/dist/assets/{clipboard-paste-DoYSN8Sv.js → clipboard-paste-EHXeKq9D.js} +0 -0
  332. /package/dist/assets/{code-xml-DwHPF_nL.js → code-xml-BlrJCgNZ.js} +0 -0
  333. /package/dist/assets/{copy-CkudG0Ej.js → copy-D6N1-xc1.js} +0 -0
  334. /package/dist/assets/{database-zap-DTWCDKdn.js → database-zap-BIGMFOfP.js} +0 -0
  335. /package/dist/assets/{defaultLocale-DK1MWd7f.js → defaultLocale-CGfP-Ye3.js} +0 -0
  336. /package/dist/assets/{defaultLocale-OkOxlkkM.js → defaultLocale-CuYNS33t.js} +0 -0
  337. /package/dist/assets/{dist-8UD0A5sU.js → dist-BF9S272t.js} +0 -0
  338. /package/dist/assets/{dist-apDpadc4.js → dist-Bk1itfBD.js} +0 -0
  339. /package/dist/assets/{dist-CQqv2gQL.js → dist-Dm11d0_A.js} +0 -0
  340. /package/dist/assets/{download-DBW9RXtT.js → download-nLboiTtW.js} +0 -0
  341. /package/dist/assets/{ellipsis-0_zJdF6H.js → ellipsis-d7eaKIFn.js} +0 -0
  342. /package/dist/assets/{ellipsis-vertical-CAB7tdza.js → ellipsis-vertical-DBQ5kWTo.js} +0 -0
  343. /package/dist/assets/{emotion-is-prop-valid.esm-D1keIaYa.js → emotion-is-prop-valid.esm-D7FeWASw.js} +0 -0
  344. /package/dist/assets/{errors-Bfogio62.js → errors-0IrrdfSG.js} +0 -0
  345. /package/dist/assets/{extends-DRbCSry7.js → extends-aq1t6BkR.js} +0 -0
  346. /package/dist/assets/{eye-off-vwi9L975.js → eye-off-CF3GmvXV.js} +0 -0
  347. /package/dist/assets/{file-DzHkbIdO.js → file-C-yMeaec.js} +0 -0
  348. /package/dist/assets/{file-headphone-B5q2Ow55.js → file-headphone-CPAP8asn.js} +0 -0
  349. /package/dist/assets/{file-plus-corner-lLQw9OnR.js → file-plus-corner-ks__N1mr.js} +0 -0
  350. /package/dist/assets/{github-BVtI-3F1.js → github-CRD4USKm.js} +0 -0
  351. /package/dist/assets/{image-DXfkah9d.js → image-CfyJzBP9.js} +0 -0
  352. /package/dist/assets/{link-Cf10mh3t.js → link-_dbp0XNB.js} +0 -0
  353. /package/dist/assets/{maps-OKerBHH8.js → maps-DQsjfyTy.js} +0 -0
  354. /package/dist/assets/{numbers-CYnquDho.js → numbers-Cno6K0UF.js} +0 -0
  355. /package/dist/assets/{objectWithoutPropertiesLoose-DP4vAkvg.js → objectWithoutPropertiesLoose-Dxmp_Bd_.js} +0 -0
  356. /package/dist/assets/{ordinal-BjO5SoTk.js → ordinal-CMAUv8ku.js} +0 -0
  357. /package/dist/assets/{paths-D2lG83Oh.js → paths-BVwhPRFT.js} +0 -0
  358. /package/dist/assets/{play-DKSqmedg.js → play-Bu_0ogGD.js} +0 -0
  359. /package/dist/assets/{plus-dVmh0yTy.js → plus-DJ99CUbx.js} +0 -0
  360. /package/dist/assets/{preload-helper-BW0IMuFq.js → preload-helper-y72bE5iF.js} +0 -0
  361. /package/dist/assets/{prop-types-RrUi-pOT.js → prop-types-DRf51_gT.js} +0 -0
  362. /package/dist/assets/{purify.es-BBn8CPhf.js → purify.es-Cf8RQecB.js} +0 -0
  363. /package/dist/assets/{range-DNqFcYmr.js → range-ClqUI25v.js} +0 -0
  364. /package/dist/assets/{refresh-ccw-DLpfIr8v.js → refresh-ccw-DQ6SJ8UC.js} +0 -0
  365. /package/dist/assets/{refresh-cw-CHAHPgkx.js → refresh-cw-Dg9tCj4k.js} +0 -0
  366. /package/dist/assets/{rotate-ccw-hLlF_82X.js → rotate-ccw-BCkZViUZ.js} +0 -0
  367. /package/dist/assets/{save-8fSvKYJT.js → save-CUdcv5qm.js} +0 -0
  368. /package/dist/assets/{session-BrEm7qNv.js → session-CByuQ-M-.js} +0 -0
  369. /package/dist/assets/{settings-CzQUw9rV.js → settings-B7nhfCat.js} +0 -0
  370. /package/dist/assets/{spinner-C5JoisA7.js → spinner-pCogyRyo.js} +0 -0
  371. /package/dist/assets/{square-CxAsQQ77.js → square-KVNDGpgy.js} +0 -0
  372. /package/dist/assets/{square-function-B006EYFX.js → square-function-BMNCw7Qb.js} +0 -0
  373. /package/dist/assets/{stex-0ac7Aukl.js → stex-C6JeW1YI.js} +0 -0
  374. /package/dist/assets/{table-BCnp9gKC.js → table-Od8PbuV-.js} +0 -0
  375. /package/dist/assets/{toDate-BqKH-Jd9.js → toDate-Cfp9W_O9.js} +0 -0
  376. /package/dist/assets/{trash-2-CAoNMkjq.js → trash-2-Bc_J7TQO.js} +0 -0
  377. /package/dist/assets/{trash-BZMAQneW.js → trash-Cxd189Vw.js} +0 -0
  378. /package/dist/assets/{triangle-alert-qZo1ox6x.js → triangle-alert-CzLrbLGN.js} +0 -0
  379. /package/dist/assets/{types-C1RN112u.js → types-CLOMZuqU.js} +0 -0
  380. /package/dist/assets/{use-toast-Hc8CXlvz.js → use-toast-BtZldTi5.js} +0 -0
  381. /package/dist/assets/{useDebounce-B0dx2Gp0.js → useDebounce-DwTO_rGp.js} +0 -0
  382. /package/dist/assets/{useTheme-BYXBU1of.js → useTheme-KDW4sktg.js} +0 -0
  383. /package/dist/assets/{uuid-ClFZlR7U.js → uuid-BukULOeS.js} +0 -0
  384. /package/dist/assets/{workflow-BmeqNuSH.js → workflow-BqHyyStM.js} +0 -0
  385. /package/dist/assets/{x-BI1M8X_v.js → x-CdLP7-v3.js} +0 -0
  386. /package/dist/assets/{youtube-DE-Ej6FR.js → youtube-CfU-SnDw.js} +0 -0
@@ -1,15 +1,16 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
+
2
3
  import { beforeEach, describe, expect, it } from "vitest";
3
- import type { CellId } from "@/core/cells/ids";
4
+ import { cellId } from "@/__tests__/branded";
4
5
  import type { CellFocusState } from "../focus";
5
6
  import { exportedForTesting } from "../focus";
6
7
 
7
8
  const { initialState, reducer, createActions } = exportedForTesting;
8
9
 
9
10
  const CellIds = {
10
- a: "a" as CellId,
11
- b: "b" as CellId,
12
- c: "c" as CellId,
11
+ a: cellId("a"),
12
+ b: cellId("b"),
13
+ c: cellId("c"),
13
14
  };
14
15
 
15
16
  describe("cell focus reducer", () => {
@@ -1,6 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
4
+ import { cellId } from "@/__tests__/branded";
4
5
  import type { CellMessage } from "../../kernel/messages";
5
6
  import { formatLogTimestamp, getCellLogsForMessage } from "../logs";
6
7
 
@@ -18,7 +19,7 @@ describe("getCellLogsForMessage", () => {
18
19
 
19
20
  test("handles text/plain MIME type on stdout", () => {
20
21
  const cellMessage: CellMessage = {
21
- cell_id: "cell-1",
22
+ cell_id: cellId("cell-1"),
22
23
  console: [
23
24
  {
24
25
  mimetype: "text/plain",
@@ -46,7 +47,7 @@ describe("getCellLogsForMessage", () => {
46
47
 
47
48
  test("handles text/plain MIME type on stderr", () => {
48
49
  const cellMessage: CellMessage = {
49
- cell_id: "cell-2",
50
+ cell_id: cellId("cell-2"),
50
51
  console: [
51
52
  {
52
53
  mimetype: "text/plain",
@@ -74,7 +75,7 @@ describe("getCellLogsForMessage", () => {
74
75
 
75
76
  test("handles text/html MIME type and strips HTML tags", () => {
76
77
  const cellMessage: CellMessage = {
77
- cell_id: "cell-3",
78
+ cell_id: cellId("cell-3"),
78
79
  console: [
79
80
  {
80
81
  mimetype: "text/html",
@@ -102,7 +103,7 @@ describe("getCellLogsForMessage", () => {
102
103
 
103
104
  test("handles text/html MIME type on stderr", () => {
104
105
  const cellMessage: CellMessage = {
105
- cell_id: "cell-4",
106
+ cell_id: cellId("cell-4"),
106
107
  console: [
107
108
  {
108
109
  mimetype: "text/html",
@@ -130,7 +131,7 @@ describe("getCellLogsForMessage", () => {
130
131
 
131
132
  test("handles application/vnd.marimo+traceback MIME type and strips HTML", () => {
132
133
  const cellMessage: CellMessage = {
133
- cell_id: "cell-5",
134
+ cell_id: cellId("cell-5"),
134
135
  console: [
135
136
  {
136
137
  mimetype: "application/vnd.marimo+traceback",
@@ -156,7 +157,7 @@ describe("getCellLogsForMessage", () => {
156
157
 
157
158
  test("handles multiple console outputs with different MIME types", () => {
158
159
  const cellMessage: CellMessage = {
159
- cell_id: "cell-7",
160
+ cell_id: cellId("cell-7"),
160
161
  console: [
161
162
  {
162
163
  mimetype: "text/plain",
@@ -196,7 +197,7 @@ describe("getCellLogsForMessage", () => {
196
197
  vi.spyOn(Date, "now").mockReturnValue(now);
197
198
 
198
199
  const cellMessage: CellMessage = {
199
- cell_id: "cell-8",
200
+ cell_id: cellId("cell-8"),
200
201
  console: [
201
202
  {
202
203
  mimetype: "text/plain",
@@ -219,7 +220,7 @@ describe("getCellLogsForMessage", () => {
219
220
 
220
221
  test("ignores unsupported MIME types", () => {
221
222
  const cellMessage: CellMessage = {
222
- cell_id: "cell-9",
223
+ cell_id: cellId("cell-9"),
223
224
  console: [
224
225
  {
225
226
  mimetype: "application/json",
@@ -241,7 +242,7 @@ describe("getCellLogsForMessage", () => {
241
242
 
242
243
  test("ignores non-logging channels", () => {
243
244
  const cellMessage: CellMessage = {
244
- cell_id: "cell-10",
245
+ cell_id: cellId("cell-10"),
245
246
  console: [
246
247
  {
247
248
  mimetype: "text/plain",
@@ -263,7 +264,7 @@ describe("getCellLogsForMessage", () => {
263
264
 
264
265
  test("returns empty array when console is null", () => {
265
266
  const cellMessage: CellMessage = {
266
- cell_id: "cell-11",
267
+ cell_id: cellId("cell-11"),
267
268
  console: null as unknown as CellMessage["console"],
268
269
  output: null,
269
270
  status: "idle",
@@ -278,7 +279,7 @@ describe("getCellLogsForMessage", () => {
278
279
 
279
280
  test("handles complex HTML with nested elements in text/html", () => {
280
281
  const cellMessage: CellMessage = {
281
- cell_id: "cell-12",
282
+ cell_id: cellId("cell-12"),
282
283
  console: [
283
284
  {
284
285
  mimetype: "text/html",
@@ -301,7 +302,7 @@ describe("getCellLogsForMessage", () => {
301
302
 
302
303
  test("handles marimo-error channel as stderr level", () => {
303
304
  const cellMessage: CellMessage = {
304
- cell_id: "cell-13",
305
+ cell_id: cellId("cell-13"),
305
306
  console: [
306
307
  {
307
308
  mimetype: "text/plain",
@@ -4,11 +4,11 @@ import { act, renderHook, waitFor } from "@testing-library/react";
4
4
  import { createStore, Provider } from "jotai";
5
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import { MockNotebook } from "@/__mocks__/notebook";
7
+ import { variableName } from "@/__tests__/branded";
7
8
  import { notebookAtom } from "@/core/cells/cells";
8
9
  import { CellId } from "@/core/cells/ids";
9
10
  import { createCellRuntimeState } from "@/core/cells/types";
10
11
  import { variablesAtom } from "@/core/variables/state";
11
- import type { VariableName } from "@/core/variables/types";
12
12
  import type { Milliseconds } from "@/utils/time";
13
13
  import {
14
14
  usePendingDelete,
@@ -138,8 +138,8 @@ describe("pending-delete-service", () => {
138
138
 
139
139
  store.set(notebookAtom, notebook);
140
140
  store.set(variablesAtom, {
141
- ["x" as VariableName]: {
142
- name: "x" as VariableName,
141
+ [variableName("x")]: {
142
+ name: variableName("x"),
143
143
  declaredBy: [cell1Id],
144
144
  usedBy: [cell2Id],
145
145
  },
@@ -1,6 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { beforeEach, describe, expect, it } from "vitest";
4
+ import { cellId } from "@/__tests__/branded";
4
5
  import type { CellMessage } from "@/core/kernel/messages";
5
6
  import { invariant } from "@/utils/invariant";
6
7
  import {
@@ -22,13 +23,13 @@ describe("RunsState Reducer", () => {
22
23
  let state: RunsState;
23
24
 
24
25
  const runId = "run1" as RunId;
25
- const cellId = "cell1";
26
+ const testCellId = cellId("cell1");
26
27
  const timestamp = Date.now();
27
28
  const code = "print('Hello World')";
28
29
 
29
30
  const cellNotification: CellMessage = {
30
31
  run_id: runId,
31
- cell_id: cellId,
32
+ cell_id: testCellId,
32
33
  timestamp,
33
34
  status: "queued",
34
35
  };
@@ -61,9 +62,9 @@ describe("RunsState Reducer", () => {
61
62
  runStartTime: timestamp,
62
63
  cellRuns: new Map([
63
64
  [
64
- cellId,
65
+ testCellId,
65
66
  {
66
- cellId,
67
+ cellId: testCellId,
67
68
  code: code.slice(0, MAX_CODE_LENGTH),
68
69
  elapsedTime: 0,
69
70
  startTime: timestamp,
@@ -98,7 +99,7 @@ describe("RunsState Reducer", () => {
98
99
  payload: {
99
100
  cellNotification: {
100
101
  run_id: runId2,
101
- cell_id: "cell2",
102
+ cell_id: cellId("cell2"),
102
103
  timestamp,
103
104
  status: "queued",
104
105
  },
@@ -124,7 +125,7 @@ describe("RunsState Reducer", () => {
124
125
  payload: {
125
126
  cellNotification: {
126
127
  run_id: runId,
127
- cell_id: cellId,
128
+ cell_id: testCellId,
128
129
  timestamp: timestamp + 1000,
129
130
  status: "running",
130
131
  },
@@ -145,7 +146,7 @@ describe("RunsState Reducer", () => {
145
146
  payload: {
146
147
  cellNotification: {
147
148
  run_id: runId,
148
- cell_id: cellId,
149
+ cell_id: testCellId,
149
150
  timestamp: runStartTimestamp + 5000,
150
151
  status: "success",
151
152
  },
@@ -171,8 +172,8 @@ describe("RunsState Reducer", () => {
171
172
  type: "addCellNotification",
172
173
  payload: {
173
174
  cellNotification: {
174
- run_id: `run${i}`,
175
- cell_id: `cell${i}`,
175
+ run_id: `run${i}` as RunId,
176
+ cell_id: cellId(`cell${i}`),
176
177
  timestamp: timestamp,
177
178
  status: "queued",
178
179
  },
@@ -198,7 +199,7 @@ describe("RunsState Reducer", () => {
198
199
  payload: {
199
200
  cellNotification: {
200
201
  run_id: runId,
201
- cell_id: cellId,
202
+ cell_id: testCellId,
202
203
  timestamp,
203
204
  status: "queued",
204
205
  },
@@ -220,7 +221,7 @@ describe("RunsState Reducer", () => {
220
221
  payload: {
221
222
  cellNotification: {
222
223
  run_id: runId,
223
- cell_id: cellId,
224
+ cell_id: testCellId,
224
225
  timestamp: errorTimestamp,
225
226
  status: "running",
226
227
  output: {
@@ -248,7 +249,7 @@ describe("RunsState Reducer", () => {
248
249
  payload: {
249
250
  cellNotification: {
250
251
  run_id: runId,
251
- cell_id: cellId,
252
+ cell_id: testCellId,
252
253
  timestamp: errorTimestamp,
253
254
  status: "running",
254
255
  output: {
@@ -273,7 +274,7 @@ describe("RunsState Reducer", () => {
273
274
  payload: {
274
275
  cellNotification: {
275
276
  run_id: runId,
276
- cell_id: cellId,
277
+ cell_id: testCellId,
277
278
  timestamp,
278
279
  output: {
279
280
  channel: "marimo-error",
@@ -288,7 +289,7 @@ describe("RunsState Reducer", () => {
288
289
  payload: {
289
290
  cellNotification: {
290
291
  run_id: runId,
291
- cell_id: cellId,
292
+ cell_id: testCellId,
292
293
  timestamp: timestamp + 2000,
293
294
  status: "running", // shouldn't happen
294
295
  },
@@ -312,7 +313,7 @@ describe("RunsState Reducer", () => {
312
313
  payload: {
313
314
  cellNotification: {
314
315
  run_id: runId2,
315
- cell_id: "cell2",
316
+ cell_id: cellId("cell2"),
316
317
  timestamp: timestamp + 1000,
317
318
  status: "queued",
318
319
  },
@@ -325,7 +326,7 @@ describe("RunsState Reducer", () => {
325
326
  payload: {
326
327
  cellNotification: {
327
328
  run_id: runId3,
328
- cell_id: "cell3",
329
+ cell_id: cellId("cell3"),
329
330
  timestamp: timestamp + 2000,
330
331
  status: "queued",
331
332
  },
@@ -345,7 +346,7 @@ describe("RunsState Reducer", () => {
345
346
  payload: {
346
347
  cellNotification: {
347
348
  run_id: runId,
348
- cell_id: "cell2",
349
+ cell_id: cellId("cell2"),
349
350
  timestamp: timestamp + 1000,
350
351
  status: "queued",
351
352
  },
@@ -367,7 +368,7 @@ describe("RunsState Reducer", () => {
367
368
  payload: {
368
369
  cellNotification: {
369
370
  run_id: runId,
370
- cell_id: cellId,
371
+ cell_id: testCellId,
371
372
  timestamp: timestamp + 1000,
372
373
  status: "running",
373
374
  },
@@ -386,7 +387,7 @@ describe("RunsState Reducer", () => {
386
387
  payload: {
387
388
  cellNotification: {
388
389
  run_id: runId,
389
- cell_id: cellId,
390
+ cell_id: testCellId,
390
391
  timestamp,
391
392
  status: "queued",
392
393
  },
@@ -405,7 +406,7 @@ describe("RunsState Reducer", () => {
405
406
  payload: {
406
407
  cellNotification: {
407
408
  run_id: runId,
408
- cell_id: cellId,
409
+ cell_id: testCellId,
409
410
  timestamp,
410
411
  status: "queued",
411
412
  },
@@ -419,7 +420,7 @@ describe("RunsState Reducer", () => {
419
420
  payload: {
420
421
  cellNotification: {
421
422
  run_id: runId,
422
- cell_id: "cell2",
423
+ cell_id: cellId("cell2"),
423
424
  timestamp: timestamp + 1000,
424
425
  status: "queued",
425
426
  },
@@ -1,7 +1,8 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
- import { type CellId, HTMLCellId } from "@/core/cells/ids";
4
+ import { cellId } from "@/__tests__/branded";
5
+ import { HTMLCellId } from "@/core/cells/ids";
5
6
  import { Logger } from "@/utils/Logger";
6
7
 
7
8
  // Mock the getCellEditorView function
@@ -20,12 +21,12 @@ vi.mock("@/core/codemirror/extensions", () => ({
20
21
  const { scrollCellIntoView } = await import("@/core/cells/scrollCellIntoView");
21
22
 
22
23
  describe("scrollCellIntoView", () => {
23
- const cellId = "test-cell-id" as CellId;
24
+ const cid = cellId("test-cell-id");
24
25
  let cellElement: HTMLElement;
25
26
 
26
27
  beforeEach(() => {
27
28
  cellElement = document.createElement("div");
28
- cellElement.id = HTMLCellId.create(cellId);
29
+ cellElement.id = HTMLCellId.create(cid);
29
30
  cellElement.scrollIntoView = vi.fn();
30
31
  document.body.append(cellElement);
31
32
 
@@ -42,7 +43,7 @@ describe("scrollCellIntoView", () => {
42
43
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
44
  mockGetCellEditorView.mockReturnValue(mockEditor as any);
44
45
 
45
- scrollCellIntoView(cellId);
46
+ scrollCellIntoView(cid);
46
47
 
47
48
  expect(mockScrollActiveLineIntoView).toHaveBeenCalledWith(mockEditor, {
48
49
  behavior: "instant",
@@ -51,7 +52,7 @@ describe("scrollCellIntoView", () => {
51
52
  });
52
53
 
53
54
  it("should scroll cell element when editor is not focused", () => {
54
- scrollCellIntoView(cellId);
55
+ scrollCellIntoView(cid);
55
56
 
56
57
  expect(mockScrollActiveLineIntoView).not.toHaveBeenCalled();
57
58
  expect(cellElement.scrollIntoView).toHaveBeenCalledWith({
@@ -64,10 +65,10 @@ describe("scrollCellIntoView", () => {
64
65
  const warnSpy = vi.spyOn(Logger, "warn").mockImplementation(vi.fn());
65
66
  cellElement.remove();
66
67
 
67
- scrollCellIntoView(cellId);
68
+ scrollCellIntoView(cid);
68
69
 
69
70
  expect(warnSpy).toHaveBeenCalledWith(
70
- `[CellFocusManager] scrollCellIntoView: element not found: ${cellId}`,
71
+ `[CellFocusManager] scrollCellIntoView: element not found: ${cid}`,
71
72
  );
72
73
  warnSpy.mockRestore();
73
74
  });
@@ -4,11 +4,12 @@ import type * as api from "@marimo-team/marimo-api";
4
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import { Mocks } from "@/__mocks__/common";
7
+ import { cellId } from "@/__tests__/branded";
7
8
  import { parseOutline } from "@/core/dom/outline";
8
9
  import { MultiColumn, visibleForTesting } from "@/utils/id-tree";
9
10
  import { invariant } from "@/utils/invariant";
10
11
  import { Logger } from "@/utils/Logger";
11
- import { type CellId, SETUP_CELL_ID } from "../ids";
12
+ import { SETUP_CELL_ID } from "../ids";
12
13
  import { notebookStateFromSession } from "../session";
13
14
 
14
15
  // Mock dependencies
@@ -22,7 +23,7 @@ type SessionCell = api.Session["NotebookSessionV1"]["cells"][0];
22
23
  type NotebookCell = api.Notebook["NotebookV1"]["cells"][0];
23
24
 
24
25
  // Test constants
25
- const CELL_1 = "cell-1" as CellId;
26
+ const CELL_1 = cellId("cell-1");
26
27
 
27
28
  describe("notebookStateFromSession", () => {
28
29
  beforeEach(() => {
@@ -671,9 +672,9 @@ describe("notebookStateFromSession", () => {
671
672
  );
672
673
  // Should have correct code and output for each cell
673
674
  for (const code of ["a", "b", "c", "d", "e", "f"]) {
674
- const cellId = `cell-${code}` as CellId;
675
- expect(result.cellData[cellId].code).toBe(code);
676
- expect(result.cellRuntime[cellId].output).toEqual({
675
+ const cid = cellId(`cell-${code}`);
676
+ expect(result.cellData[cid].code).toBe(code);
677
+ expect(result.cellRuntime[cid].output).toEqual({
677
678
  channel: "output",
678
679
  data: `${code.toUpperCase()}!`,
679
680
  mimetype: "text/plain",
@@ -751,26 +752,26 @@ describe("notebookStateFromSession", () => {
751
752
  );
752
753
 
753
754
  // Should have correct code for each cell
754
- expect(result.cellData["cell-a" as CellId].code).toBe("a");
755
- expect(result.cellData["cell-c" as CellId].code).toBe("c");
756
- expect(result.cellData["cell-z" as CellId].code).toBe("z");
757
- expect(result.cellData["cell-e" as CellId].code).toBe("e");
758
- expect(result.cellData["cell-g" as CellId].code).toBe("g");
755
+ expect(result.cellData[cellId("cell-a")].code).toBe("a");
756
+ expect(result.cellData[cellId("cell-c")].code).toBe("c");
757
+ expect(result.cellData[cellId("cell-z")].code).toBe("z");
758
+ expect(result.cellData[cellId("cell-e")].code).toBe("e");
759
+ expect(result.cellData[cellId("cell-g")].code).toBe("g");
759
760
 
760
761
  // Should have session outputs for matching cells (a, c, e)
761
- expect(result.cellRuntime["cell-a" as CellId].output).toEqual({
762
+ expect(result.cellRuntime[cellId("cell-a")].output).toEqual({
762
763
  channel: "output",
763
764
  data: "A!",
764
765
  mimetype: "text/plain",
765
766
  timestamp: 0,
766
767
  });
767
- expect(result.cellRuntime["cell-c" as CellId].output).toEqual({
768
+ expect(result.cellRuntime[cellId("cell-c")].output).toEqual({
768
769
  channel: "output",
769
770
  data: "C!",
770
771
  mimetype: "text/plain",
771
772
  timestamp: 0,
772
773
  });
773
- expect(result.cellRuntime["cell-e" as CellId].output).toEqual({
774
+ expect(result.cellRuntime[cellId("cell-e")].output).toEqual({
774
775
  channel: "output",
775
776
  data: "E!",
776
777
  mimetype: "text/plain",
@@ -778,8 +779,8 @@ describe("notebookStateFromSession", () => {
778
779
  });
779
780
 
780
781
  // Should have no output for new cells (z, g) - they get stub session cells
781
- expect(result.cellRuntime["cell-z" as CellId].output).toBeNull();
782
- expect(result.cellRuntime["cell-g" as CellId].output).toBeNull();
782
+ expect(result.cellRuntime[cellId("cell-z")].output).toBeNull();
783
+ expect(result.cellRuntime[cellId("cell-g")].output).toBeNull();
783
784
 
784
785
  // Should log warning about different cells
785
786
  expect(Logger.warn).toHaveBeenCalledWith(
@@ -875,18 +876,18 @@ describe("notebookStateFromSession", () => {
875
876
  );
876
877
 
877
878
  // Should have correct code from notebook
878
- expect(result.cellData["cell-1" as CellId].code).toBe("1 / 0");
879
- expect(result.cellData["cell-2" as CellId].code).toBe('mo.md("Hello")');
880
- expect(result.cellData["cell-3" as CellId].code).toBe(
879
+ expect(result.cellData[cellId("cell-1")].code).toBe("1 / 0");
880
+ expect(result.cellData[cellId("cell-2")].code).toBe('mo.md("Hello")');
881
+ expect(result.cellData[cellId("cell-3")].code).toBe(
881
882
  "x = mo.ui.slider(0, 10)",
882
883
  );
883
884
 
884
885
  // cell-1: No matching session cell (hash is null), gets stub session cell
885
- expect(result.cellRuntime["cell-1" as CellId].output).toBeNull();
886
- expect(result.cellRuntime["cell-1" as CellId].consoleOutputs).toEqual([]);
886
+ expect(result.cellRuntime[cellId("cell-1")].output).toBeNull();
887
+ expect(result.cellRuntime[cellId("cell-1")].consoleOutputs).toEqual([]);
887
888
 
888
889
  // cell-2: Matches session cell-1 by hash (moMd), gets its output
889
- expect(result.cellRuntime["cell-2" as CellId].output).toEqual({
890
+ expect(result.cellRuntime[cellId("cell-2")].output).toEqual({
890
891
  channel: "output",
891
892
  data: "Welcome to marimo!",
892
893
  mimetype: "text/markdown",
@@ -894,7 +895,7 @@ describe("notebookStateFromSession", () => {
894
895
  });
895
896
 
896
897
  // cell-3: Matches session cell-2 by hash (slider), gets its output
897
- expect(result.cellRuntime["cell-3" as CellId].output).toEqual({
898
+ expect(result.cellRuntime[cellId("cell-3")].output).toEqual({
898
899
  channel: "output",
899
900
  data: "",
900
901
  mimetype: "text/plain",
@@ -755,7 +755,7 @@ const {
755
755
  });
756
756
  },
757
757
  handleCellMessage: (state, message: CellMessage) => {
758
- const cellId = message.cell_id as CellId;
758
+ const cellId = message.cell_id;
759
759
  const nextState = updateCellRuntimeState({
760
760
  state,
761
761
  cellId,
@@ -1,9 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  /* eslint-disable @typescript-eslint/no-redeclare */
3
3
 
4
+ import type { components } from "@marimo-team/marimo-api";
4
5
  import { OBJECT_ID_ATTR } from "@/core/dom/ui-element-constants";
5
6
  import { invariant } from "@/utils/invariant";
6
- import type { TypedString } from "../../utils/typed";
7
7
 
8
8
  const lowercase = "abcdefghijklmnopqrstuvwxyz";
9
9
  const uppercase = lowercase.toUpperCase();
@@ -14,9 +14,9 @@ export const SCRATCH_CELL_ID = "__scratch__" as CellId;
14
14
  export const SETUP_CELL_ID = "setup" as CellId;
15
15
 
16
16
  /**
17
- * A typed CellId
17
+ * A typed CellId — derived from the generated OpenAPI schema.
18
18
  */
19
- export type CellId = TypedString<"CellId">;
19
+ export type CellId = components["schemas"]["CellId"];
20
20
  export const CellId = {
21
21
  /**
22
22
  * Create a new CellId, a random 4 letter string.
@@ -106,9 +106,9 @@ export function findCellId(element: HTMLElement): CellId | null {
106
106
  }
107
107
 
108
108
  /**
109
- * A typed UIElementId
109
+ * A typed UIElementId — derived from the generated OpenAPI schema.
110
110
  */
111
- export type UIElementId = `${CellId}-${string}`;
111
+ export type UIElementId = components["schemas"]["UIElementId"];
112
112
  export const UIElementId = {
113
113
  parse(element: Element): UIElementId | null {
114
114
  return element.getAttribute(OBJECT_ID_ATTR) as UIElementId | null;
@@ -43,7 +43,7 @@ export function getCellLogsForMessage(cell: CellMessage): CellLog[] {
43
43
  timestamp: output.timestamp || Date.now(),
44
44
  level: isError ? "stderr" : "stdout",
45
45
  message: message,
46
- cellId: cell.cell_id as CellId,
46
+ cellId: cell.cell_id,
47
47
  });
48
48
  break;
49
49
  }
@@ -66,7 +66,7 @@ export function getCellLogsForMessage(cell: CellMessage): CellLog[] {
66
66
  cell.output.data.forEach((error) => {
67
67
  CellLogLogger.log({
68
68
  level: "stderr",
69
- cellId: cell.cell_id as CellId,
69
+ cellId: cell.cell_id,
70
70
  timestamp: cell.timestamp ?? 0,
71
71
  message: JSON.stringify(error),
72
72
  });
@@ -79,9 +79,9 @@ const {
79
79
  runId,
80
80
  cellRuns: new Map([
81
81
  [
82
- cellNotification.cell_id as CellId,
82
+ cellNotification.cell_id,
83
83
  {
84
- cellId: cellNotification.cell_id as CellId,
84
+ cellId: cellNotification.cell_id,
85
85
  code: code.slice(0, MAX_CODE_LENGTH),
86
86
  elapsedTime: 0,
87
87
  status: status,
@@ -111,9 +111,7 @@ const {
111
111
 
112
112
  // Update existing run
113
113
  const nextCellRuns = new Map(existingRun.cellRuns);
114
- const existingCellRun = nextCellRuns.get(
115
- cellNotification.cell_id as CellId,
116
- );
114
+ const existingCellRun = nextCellRuns.get(cellNotification.cell_id);
117
115
 
118
116
  // Early return if nothing changed
119
117
  if (
@@ -140,15 +138,15 @@ const {
140
138
  ? timestamp - existingCellRun.startTime
141
139
  : undefined;
142
140
 
143
- nextCellRuns.set(cellNotification.cell_id as CellId, {
141
+ nextCellRuns.set(cellNotification.cell_id, {
144
142
  ...existingCellRun,
145
143
  startTime,
146
144
  elapsedTime,
147
145
  status,
148
146
  });
149
147
  } else {
150
- nextCellRuns.set(cellNotification.cell_id as CellId, {
151
- cellId: cellNotification.cell_id as CellId,
148
+ nextCellRuns.set(cellNotification.cell_id, {
149
+ cellId: cellNotification.cell_id,
152
150
  code: code.slice(0, MAX_CODE_LENGTH),
153
151
  elapsedTime: 0,
154
152
  status: status,