@marimo-team/frontend 0.24.1-dev50 → 0.24.1-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 (30) hide show
  1. package/dist/assets/{JsonOutput-BI2qFHVr.js → JsonOutput--lW6GQQ9.js} +10 -10
  2. package/dist/assets/{agent-panel-PB0I1dIC.js → agent-panel-i6F-fC5e.js} +1 -1
  3. package/dist/assets/{cell-editor-5wcJHF0s.js → cell-editor-X3xHqmCs.js} +1 -1
  4. package/dist/assets/{column-preview-D6cIOnWQ.js → column-preview-DKbMmEB5.js} +1 -1
  5. package/dist/assets/{command-palette-DkGgAhyM.js → command-palette-L1LZCmet.js} +1 -1
  6. package/dist/assets/{edit-page-Bpqbjwkb.js → edit-page-DOpi9pL6.js} +4 -4
  7. package/dist/assets/file-explorer-panel-z-rke195.js +1 -0
  8. package/dist/assets/{index-CRLe8Sox.js → index-CNnOirLv.js} +2 -2
  9. package/dist/assets/{layout-Ddsz1eHh.js → layout-DmbNDyY3.js} +3 -3
  10. package/dist/assets/{panels-D53vWR00.js → panels-BMikLSqU.js} +1 -1
  11. package/dist/assets/{reveal-component-C0L5MU2W.js → reveal-component-6t8SeOsr.js} +1 -1
  12. package/dist/assets/{run-page-DXZapRtY.js → run-page-BIyr61hZ.js} +1 -1
  13. package/dist/assets/{scratchpad-panel-ja6doGoa.js → scratchpad-panel-B2KUccqM.js} +1 -1
  14. package/dist/assets/{session-panel-ftyqfsYy.js → session-panel-1RH7Zh0c.js} +1 -1
  15. package/dist/assets/{skeleton-CxFczTPo.js → skeleton-DZV2_Wnl.js} +1 -1
  16. package/dist/assets/{useNotebookActions-DpphIKt5.js → useNotebookActions-BcAzvJBD.js} +1 -1
  17. package/dist/index.html +3 -3
  18. package/package.json +4 -2
  19. package/src/components/editor/file-tree/__tests__/file-render-mode.test.ts +3 -0
  20. package/src/components/editor/file-tree/__tests__/file-viewer.test.tsx +21 -0
  21. package/src/components/editor/file-tree/__tests__/renderers.test.tsx +129 -0
  22. package/src/components/editor/file-tree/file-viewer.tsx +1 -0
  23. package/src/components/editor/file-tree/renderers.tsx +27 -1
  24. package/src/components/storage/__tests__/storage-file-viewer.test.tsx +84 -0
  25. package/src/components/storage/storage-file-viewer.tsx +1 -0
  26. package/src/plugins/__tests__/plugin-schema.test.ts +343 -0
  27. package/src/plugins/__tests__/plugin-schema.ts +398 -0
  28. package/src/plugins/plugins.ts +1 -1
  29. package/dist/assets/file-explorer-panel-DaDDgJV2.js +0 -1
  30. package/src/components/editor/file-tree/__tests__/renderers.test.ts +0 -31
@@ -1,4 +1,4 @@
1
- import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{c as t,f as n,l as r,r as i,u as a}from"./useEvent-xfs0Sn4r.js";import{t as o}from"./react-CBDbhulC.js";import{Ao as s,Bi as c,Ct as l,E as u,Fa as d,It as f,Kr as p,Qi as m,Qr as h,T as g,Wn as _,Xi as v,Xr as y,Zi as b,Zr as x,bo as S,cn as C,do as w,ei as T,g as E,go as ee,ir as D,li as O,ln as te,m as k,ra as A,sa as j,t as M,ta as N,ti as P,y as ne,zi as F}from"./cells-B1S_6FG3.js";import{Cn as I,kt as L,vt as R}from"./schemas-aTUejmFi.js";import{t as z}from"./compiler-runtime-CYIjoINj.js";import{C as re,n as B,r as V}from"./ai-model-dropdown-DjQy2bo-.js";import{g as H,n as U}from"./useEventListener-D27Dii_l.js";import{t as ie}from"./objects-snlMn4yk.js";import{C as ae,r as oe}from"./utils-R_pHe-RB.js";import{n as W,t as G}from"./constants-BDbGiS7O.js";import{A as se,M as ce,N as K,O as le,T as ue,j as de,k as fe,v as pe}from"./config-CUBl5qBg.js";import{t as me}from"./switch-CBR-ykv3.js";import{c as he}from"./readonly-python-code-De0vvuWh.js";import{t as q}from"./cn-ldLVeaqm.js";import{t as ge}from"./jsx-runtime-B74pBk57.js";import{o as _e}from"./alert-dialog-DBoy-FMx.js";import{i as ve,n as ye,r as be,t as xe}from"./tabs-c6mpccpH.js";import{a as Se,c as Ce,i as we,n as Te,r as Ee,s as De,t as Oe}from"./select-BUEX2Vfl.js";import{Pt as ke,X as Ae}from"./JsonOutput-BI2qFHVr.js";import{a as je,c as J,o as Me,p as Ne,t as Pe}from"./download-CIdXYNHv.js";import{t as Fe}from"./tooltip-D7dq6bnc.js";import{n as Ie,r as Le,t as Re}from"./button-BMBznEru.js";import{i as ze,r as Be,t as Ve}from"./strings-CpYReX2Q.js";import{r as He}from"./requests-C6_IaFh7.js";import{t as Y}from"./createLucideIcon-B7HeEoG2.js";import{F as Ue,I as We,L as Ge,P as Ke,a as qe,i as Je,u as Ye}from"./layout-Ddsz1eHh.js";import{t as Xe}from"./check-BoA6XBpj.js";import{r as Ze}from"./useCellActionButton-DXyUqFdJ.js";import{t as Qe}from"./code-CF0HKE9K.js";import{t as $e}from"./copy-BMXKNElG.js";import{t as et}from"./eye-off-CFuPxa9F.js";import{t as tt}from"./external-link-Bp3BxyRA.js";import{t as nt}from"./file-DF8n85RA.js";import{t as rt}from"./globe-BQf75qV_.js";import{n as it,r as at,t as ot}from"./youtube-DCJ-ihUU.js";import{n as st}from"./components-DwH_Yb1N.js";import{i as ct,n as lt,r as ut}from"./markdown-export-0rLbaq8b.js";import{t as dt}from"./image-ab13yGv4.js";import{D as ft,E as pt,O as mt,T as ht,b as gt,j as _t}from"./write-secret-modal-BG_B6y1P.js";import{t as vt}from"./link-Cap-MZiw.js";import{t as yt}from"./spinner-Ck-Hgfvj.js";import{r as bt}from"./input-DeyycFtq.js";import{t as xt}from"./settings-C-cYas75.js";import{t as St}from"./square-B58Ib8Ir.js";import{t as Ct}from"./triangle-alert-MihykDYG.js";import{t as wt}from"./use-toast-DpWHUGuF.js";import{n as Tt,t as Et}from"./paths-zcL04qUW.js";import{o as Dt}from"./session-CEdta5_Q.js";import{n as Ot}from"./useAsyncData-Buhk-UgR.js";import{n as kt}from"./copy-Cg05mM3C.js";import{t as At}from"./copy-icon-LPQzn7_f.js";import{r as jt}from"./useRunCells-DHnbXALT.js";import{r as Mt,t as Nt}from"./share-C2MPy_VX.js";import{n as Pt,t as Ft}from"./alert-dmKwNsrp.js";import{a as It}from"./cell-link-BbAJokoX.js";import{t as Lt}from"./icons-CjLa9BiH.js";import{i as Rt,n as zt}from"./error-entries-DEjvzkum.js";import{n as Bt,t as Vt}from"./pair-with-agent-modal-CBIL9_6g.js";import{n as Ht}from"./add-connection-dialog-CcnJ2LkX.js";import{t as Ut}from"./github-YRgb6LMu.js";import{n as Wt}from"./marimo-icons-C3KxMV9A.js";import{t as Gt}from"./links-DPh7yoP-.js";import{i as Kt,n as qt,t as Jt}from"./skeleton-CxFczTPo.js";import{t as Yt}from"./types-CoHi_MQq.js";var Xt=Y(`circle-chevron-down`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m16 10-4 4-4-4`,key:`894hmk`}]]),Zt=Y(`circle-chevron-right`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m10 8 4 4-4 4`,key:`1wy4r4`}]]),Qt=Y(`clipboard-copy`,[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2`,key:`4jdomd`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v4`,key:`3hqy98`}],[`path`,{d:`M21 14H11`,key:`1bme5i`}],[`path`,{d:`m15 10-4 4 4 4`,key:`5dvupr`}]]),$t=Y(`cloud-download`,[[`path`,{d:`M12 13v8l-4-4`,key:`1f5nwf`}],[`path`,{d:`m12 21 4-4`,key:`1lfcce`}],[`path`,{d:`M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284`,key:`ui1hmy`}]]),en=Y(`command`,[[`path`,{d:`M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3`,key:`11bfej`}]]),tn=Y(`diamond-plus`,[[`path`,{d:`M12 8v8`,key:`napkw2`}],[`path`,{d:`M2.7 10.3a2.41 2.41 0 0 0 0 3.41l7.59 7.59a2.41 2.41 0 0 0 3.41 0l7.59-7.59a2.41 2.41 0 0 0 0-3.41L13.7 2.71a2.41 2.41 0 0 0-3.41 0z`,key:`1ey20j`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}]]),nn=Y(`fast-forward`,[[`path`,{d:`M12 6a2 2 0 0 1 3.414-1.414l6 6a2 2 0 0 1 0 2.828l-6 6A2 2 0 0 1 12 18z`,key:`b19h5q`}],[`path`,{d:`M2 6a2 2 0 0 1 3.414-1.414l6 6a2 2 0 0 1 0 2.828l-6 6A2 2 0 0 1 2 18z`,key:`h7h5ge`}]]),rn=Y(`files`,[[`path`,{d:`M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8`,key:`14sh0y`}],[`path`,{d:`M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z`,key:`1970lx`}],[`path`,{d:`M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1`,key:`l4dndm`}]]),an=Y(`list`,[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]),on=Y(`message-circle-question-mark`,[[`path`,{d:`M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719`,key:`1sd12s`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`,key:`1u773s`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),sn=Y(`notebook`,[[`path`,{d:`M2 6h4`,key:`aawbzj`}],[`path`,{d:`M2 10h4`,key:`l0bgd4`}],[`path`,{d:`M2 14h4`,key:`1gsvsf`}],[`path`,{d:`M2 18h4`,key:`1bu2t1`}],[`rect`,{width:`16`,height:`20`,x:`4`,y:`2`,rx:`2`,key:`1nb95v`}],[`path`,{d:`M16 2v20`,key:`rotuqe`}]]),cn=Y(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),ln=Y(`presentation`,[[`path`,{d:`M2 3h20`,key:`91anmk`}],[`path`,{d:`M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3`,key:`2k9sn8`}],[`path`,{d:`m7 21 5-5 5 5`,key:`bip4we`}]]),un=Y(`share-2`,[[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}],[`circle`,{cx:`6`,cy:`12`,r:`3`,key:`w7nqdw`}],[`circle`,{cx:`18`,cy:`19`,r:`3`,key:`1xt0gg`}],[`line`,{x1:`8.59`,x2:`15.42`,y1:`13.51`,y2:`17.49`,key:`47mynk`}],[`line`,{x1:`15.41`,x2:`8.59`,y1:`6.51`,y2:`10.49`,key:`1n3mei`}]]),dn=Y(`square-power`,[[`path`,{d:`M12 7v4`,key:`xawao1`}],[`path`,{d:`M7.998 9.003a5 5 0 1 0 8-.005`,key:`1pek45`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),fn=Y(`undo-2`,[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]),X=ge(),Z=z(),Q=e(o(),1);function pn(e,t){let n=(0,Z.c)(11),r;n[0]===t?r=n[1]:(r=new w(t),n[0]=t,n[1]=r);let i=r,a;n[2]!==e||n[3]!==i?(a=()=>i.get(e),n[2]=e,n[3]=i,n[4]=a):a=n[4];let[o,s]=(0,Q.useState)(a),c;n[5]!==e||n[6]!==i?(c=t=>{s(t),i.set(e,t)},n[5]=e,n[6]=i,n[7]=c):c=n[7];let l=c,u;return n[8]!==l||n[9]!==o?(u=[o,l],n[8]=l,n[9]=o,n[10]=u):u=n[10],u}function mn(e,t){return{...e,Binaries:{...e.Binaries,Browser:t}}}function hn(e,t,n,r){return{marimo:e,Locale:n||void 0,Binaries:{Browser:t},"Environment Collection Error":r}}function gn(e,t){let n=Math.max(2,...Array.from(t.matchAll(/`+/g),e=>e[0].length)),r="`".repeat(n+1);return`${r}${e}\n${t}\n${r}`}function _n(e,t){let n=e.includes(`?`)?`&`:`?`,r=[],i=e,a=0;for(let[e,o]of Object.entries(t)){if(o.length===0)continue;let t=`${e}=${encodeURIComponent(o)}`,s=`${i}${a===0?n:`&`}${t}`;if(s.length>6e3){r.push(e);continue}i=s,a+=1}return{url:i,omitted:r}}function vn(e,t){return[`<details>`,`<summary>${Ve.htmlEscape(e)??``}</summary>`,``,t,``,`</details>`].join(`
1
+ import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{c as t,f as n,l as r,r as i,u as a}from"./useEvent-xfs0Sn4r.js";import{t as o}from"./react-CBDbhulC.js";import{Ao as s,Bi as c,Ct as l,E as u,Fa as d,It as f,Kr as p,Qi as m,Qr as h,T as g,Wn as _,Xi as v,Xr as y,Zi as b,Zr as x,bo as S,cn as C,do as w,ei as T,g as E,go as ee,ir as D,li as O,ln as te,m as k,ra as A,sa as j,t as M,ta as N,ti as P,y as ne,zi as F}from"./cells-B1S_6FG3.js";import{Cn as I,kt as L,vt as R}from"./schemas-aTUejmFi.js";import{t as z}from"./compiler-runtime-CYIjoINj.js";import{C as re,n as B,r as V}from"./ai-model-dropdown-DjQy2bo-.js";import{g as H,n as U}from"./useEventListener-D27Dii_l.js";import{t as ie}from"./objects-snlMn4yk.js";import{C as ae,r as oe}from"./utils-R_pHe-RB.js";import{n as W,t as G}from"./constants-BDbGiS7O.js";import{A as se,M as ce,N as K,O as le,T as ue,j as de,k as fe,v as pe}from"./config-CUBl5qBg.js";import{t as me}from"./switch-CBR-ykv3.js";import{c as he}from"./readonly-python-code-De0vvuWh.js";import{t as q}from"./cn-ldLVeaqm.js";import{t as ge}from"./jsx-runtime-B74pBk57.js";import{o as _e}from"./alert-dialog-DBoy-FMx.js";import{i as ve,n as ye,r as be,t as xe}from"./tabs-c6mpccpH.js";import{a as Se,c as Ce,i as we,n as Te,r as Ee,s as De,t as Oe}from"./select-BUEX2Vfl.js";import{Pt as ke,X as Ae}from"./JsonOutput--lW6GQQ9.js";import{a as je,c as J,o as Me,p as Ne,t as Pe}from"./download-CIdXYNHv.js";import{t as Fe}from"./tooltip-D7dq6bnc.js";import{n as Ie,r as Le,t as Re}from"./button-BMBznEru.js";import{i as ze,r as Be,t as Ve}from"./strings-CpYReX2Q.js";import{r as He}from"./requests-C6_IaFh7.js";import{t as Y}from"./createLucideIcon-B7HeEoG2.js";import{F as Ue,I as We,L as Ge,P as Ke,a as qe,i as Je,u as Ye}from"./layout-DmbNDyY3.js";import{t as Xe}from"./check-BoA6XBpj.js";import{r as Ze}from"./useCellActionButton-DXyUqFdJ.js";import{t as Qe}from"./code-CF0HKE9K.js";import{t as $e}from"./copy-BMXKNElG.js";import{t as et}from"./eye-off-CFuPxa9F.js";import{t as tt}from"./external-link-Bp3BxyRA.js";import{t as nt}from"./file-DF8n85RA.js";import{t as rt}from"./globe-BQf75qV_.js";import{n as it,r as at,t as ot}from"./youtube-DCJ-ihUU.js";import{n as st}from"./components-DwH_Yb1N.js";import{i as ct,n as lt,r as ut}from"./markdown-export-0rLbaq8b.js";import{t as dt}from"./image-ab13yGv4.js";import{D as ft,E as pt,O as mt,T as ht,b as gt,j as _t}from"./write-secret-modal-BG_B6y1P.js";import{t as vt}from"./link-Cap-MZiw.js";import{t as yt}from"./spinner-Ck-Hgfvj.js";import{r as bt}from"./input-DeyycFtq.js";import{t as xt}from"./settings-C-cYas75.js";import{t as St}from"./square-B58Ib8Ir.js";import{t as Ct}from"./triangle-alert-MihykDYG.js";import{t as wt}from"./use-toast-DpWHUGuF.js";import{n as Tt,t as Et}from"./paths-zcL04qUW.js";import{o as Dt}from"./session-CEdta5_Q.js";import{n as Ot}from"./useAsyncData-Buhk-UgR.js";import{n as kt}from"./copy-Cg05mM3C.js";import{t as At}from"./copy-icon-LPQzn7_f.js";import{r as jt}from"./useRunCells-DHnbXALT.js";import{r as Mt,t as Nt}from"./share-C2MPy_VX.js";import{n as Pt,t as Ft}from"./alert-dmKwNsrp.js";import{a as It}from"./cell-link-BbAJokoX.js";import{t as Lt}from"./icons-CjLa9BiH.js";import{i as Rt,n as zt}from"./error-entries-DEjvzkum.js";import{n as Bt,t as Vt}from"./pair-with-agent-modal-CBIL9_6g.js";import{n as Ht}from"./add-connection-dialog-CcnJ2LkX.js";import{t as Ut}from"./github-YRgb6LMu.js";import{n as Wt}from"./marimo-icons-C3KxMV9A.js";import{t as Gt}from"./links-DPh7yoP-.js";import{i as Kt,n as qt,t as Jt}from"./skeleton-DZV2_Wnl.js";import{t as Yt}from"./types-CoHi_MQq.js";var Xt=Y(`circle-chevron-down`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m16 10-4 4-4-4`,key:`894hmk`}]]),Zt=Y(`circle-chevron-right`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m10 8 4 4-4 4`,key:`1wy4r4`}]]),Qt=Y(`clipboard-copy`,[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2`,key:`4jdomd`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v4`,key:`3hqy98`}],[`path`,{d:`M21 14H11`,key:`1bme5i`}],[`path`,{d:`m15 10-4 4 4 4`,key:`5dvupr`}]]),$t=Y(`cloud-download`,[[`path`,{d:`M12 13v8l-4-4`,key:`1f5nwf`}],[`path`,{d:`m12 21 4-4`,key:`1lfcce`}],[`path`,{d:`M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284`,key:`ui1hmy`}]]),en=Y(`command`,[[`path`,{d:`M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3`,key:`11bfej`}]]),tn=Y(`diamond-plus`,[[`path`,{d:`M12 8v8`,key:`napkw2`}],[`path`,{d:`M2.7 10.3a2.41 2.41 0 0 0 0 3.41l7.59 7.59a2.41 2.41 0 0 0 3.41 0l7.59-7.59a2.41 2.41 0 0 0 0-3.41L13.7 2.71a2.41 2.41 0 0 0-3.41 0z`,key:`1ey20j`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}]]),nn=Y(`fast-forward`,[[`path`,{d:`M12 6a2 2 0 0 1 3.414-1.414l6 6a2 2 0 0 1 0 2.828l-6 6A2 2 0 0 1 12 18z`,key:`b19h5q`}],[`path`,{d:`M2 6a2 2 0 0 1 3.414-1.414l6 6a2 2 0 0 1 0 2.828l-6 6A2 2 0 0 1 2 18z`,key:`h7h5ge`}]]),rn=Y(`files`,[[`path`,{d:`M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8`,key:`14sh0y`}],[`path`,{d:`M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z`,key:`1970lx`}],[`path`,{d:`M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1`,key:`l4dndm`}]]),an=Y(`list`,[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]),on=Y(`message-circle-question-mark`,[[`path`,{d:`M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719`,key:`1sd12s`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`,key:`1u773s`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),sn=Y(`notebook`,[[`path`,{d:`M2 6h4`,key:`aawbzj`}],[`path`,{d:`M2 10h4`,key:`l0bgd4`}],[`path`,{d:`M2 14h4`,key:`1gsvsf`}],[`path`,{d:`M2 18h4`,key:`1bu2t1`}],[`rect`,{width:`16`,height:`20`,x:`4`,y:`2`,rx:`2`,key:`1nb95v`}],[`path`,{d:`M16 2v20`,key:`rotuqe`}]]),cn=Y(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),ln=Y(`presentation`,[[`path`,{d:`M2 3h20`,key:`91anmk`}],[`path`,{d:`M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3`,key:`2k9sn8`}],[`path`,{d:`m7 21 5-5 5 5`,key:`bip4we`}]]),un=Y(`share-2`,[[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}],[`circle`,{cx:`6`,cy:`12`,r:`3`,key:`w7nqdw`}],[`circle`,{cx:`18`,cy:`19`,r:`3`,key:`1xt0gg`}],[`line`,{x1:`8.59`,x2:`15.42`,y1:`13.51`,y2:`17.49`,key:`47mynk`}],[`line`,{x1:`15.41`,x2:`8.59`,y1:`6.51`,y2:`10.49`,key:`1n3mei`}]]),dn=Y(`square-power`,[[`path`,{d:`M12 7v4`,key:`xawao1`}],[`path`,{d:`M7.998 9.003a5 5 0 1 0 8-.005`,key:`1pek45`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),fn=Y(`undo-2`,[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]),X=ge(),Z=z(),Q=e(o(),1);function pn(e,t){let n=(0,Z.c)(11),r;n[0]===t?r=n[1]:(r=new w(t),n[0]=t,n[1]=r);let i=r,a;n[2]!==e||n[3]!==i?(a=()=>i.get(e),n[2]=e,n[3]=i,n[4]=a):a=n[4];let[o,s]=(0,Q.useState)(a),c;n[5]!==e||n[6]!==i?(c=t=>{s(t),i.set(e,t)},n[5]=e,n[6]=i,n[7]=c):c=n[7];let l=c,u;return n[8]!==l||n[9]!==o?(u=[o,l],n[8]=l,n[9]=o,n[10]=u):u=n[10],u}function mn(e,t){return{...e,Binaries:{...e.Binaries,Browser:t}}}function hn(e,t,n,r){return{marimo:e,Locale:n||void 0,Binaries:{Browser:t},"Environment Collection Error":r}}function gn(e,t){let n=Math.max(2,...Array.from(t.matchAll(/`+/g),e=>e[0].length)),r="`".repeat(n+1);return`${r}${e}\n${t}\n${r}`}function _n(e,t){let n=e.includes(`?`)?`&`:`?`,r=[],i=e,a=0;for(let[e,o]of Object.entries(t)){if(o.length===0)continue;let t=`${e}=${encodeURIComponent(o)}`,s=`${i}${a===0?n:`&`}${t}`;if(s.length>6e3){r.push(e);continue}i=s,a+=1}return{url:i,omitted:r}}function vn(e,t){return[`<details>`,`<summary>${Ve.htmlEscape(e)??``}</summary>`,``,t,``,`</details>`].join(`
2
2
  `)}function yn(e){return vn(`Environment`,gn(`json`,JSON.stringify(e,null,2)))}function bn(e){return vn(`Errors`,gn(`text`,e.map(zt).join(`
3
3
 
4
4
  ---
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-CRLe8Sox.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-CNnOirLv.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-CBDbhulC.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-CYIjoINj.js">
@@ -205,7 +205,7 @@
205
205
  <link rel="modulepreload" crossorigin href="./assets/formats-DSzGCKeO.js">
206
206
  <link rel="modulepreload" crossorigin href="./assets/table-DmqOOjfe.js">
207
207
  <link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-BSRAHC4P.js">
208
- <link rel="modulepreload" crossorigin href="./assets/JsonOutput-BI2qFHVr.js">
208
+ <link rel="modulepreload" crossorigin href="./assets/JsonOutput--lW6GQQ9.js">
209
209
  <link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-ChZdjJhj.js">
210
210
  <link rel="modulepreload" crossorigin href="./assets/square-function-DkZweMAs.js">
211
211
  <link rel="modulepreload" crossorigin href="./assets/spec-CUFquO6R.js">
@@ -220,7 +220,7 @@
220
220
  <link rel="modulepreload" crossorigin href="./assets/globe-BQf75qV_.js">
221
221
  <link rel="modulepreload" crossorigin href="./assets/markdown-export-0rLbaq8b.js">
222
222
  <link rel="modulepreload" crossorigin href="./assets/types-BflGgckY.js">
223
- <link rel="modulepreload" crossorigin href="./assets/column-preview-D6cIOnWQ.js">
223
+ <link rel="modulepreload" crossorigin href="./assets/column-preview-DKbMmEB5.js">
224
224
  <link rel="modulepreload" crossorigin href="./assets/square-B58Ib8Ir.js">
225
225
  <link rel="modulepreload" crossorigin href="./assets/triangle-alert-MihykDYG.js">
226
226
  <link rel="modulepreload" crossorigin href="./assets/prop-types-Djf4O40e.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.24.1-dev50",
3
+ "version": "0.24.1-dev52",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -179,6 +179,7 @@
179
179
  "lint:oxlint": "oxlint --fix",
180
180
  "lint:stylelint": "stylelint src/**/*.css --fix",
181
181
  "preview": "vite preview",
182
+ "plugins:generate-schema": "cross-env UPDATE_PLUGIN_SCHEMA=1 vitest run src/plugins/__tests__/plugin-schema.test.ts",
182
183
  "dev:quarto": "VITE_MARIMO_ISLANDS=true vite",
183
184
  "dev:islands": "cross-env VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts",
184
185
  "build:islands": "cross-env VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts build",
@@ -228,6 +229,7 @@
228
229
  "vega-typings": "^2.1.0",
229
230
  "vite": "^8.2.1",
230
231
  "vite-plugin-wasm": "^3.6.0",
231
- "vitest": "^4.1.10"
232
+ "vitest": "^4.1.10",
233
+ "yaml": "^2.8.3"
232
234
  }
233
235
  }
@@ -8,7 +8,10 @@ describe("getFileRenderMode", () => {
8
8
  ["text/plain", false, "text"],
9
9
  ["text/x-rust", false, "text"],
10
10
  ["application/json", false, "text"],
11
+ ["application/toml", false, "text"],
12
+ ["application/x-toml", false, "text"],
11
13
  ["application/xml", false, "text"],
14
+ ["text/x-toml", false, "text"],
12
15
  ["text/csv", false, "csv"],
13
16
  ["image/png", true, "media"],
14
17
  ["video/mp4", true, "media"],
@@ -15,13 +15,19 @@ vi.mock("@/plugins/impl/code/LazyAnyLanguageCodeMirror", () => ({
15
15
  LazyAnyLanguageCodeMirror: ({
16
16
  value,
17
17
  onChange,
18
+ language,
19
+ readOnly,
18
20
  }: {
19
21
  value?: string;
20
22
  onChange?: (value: string) => void;
23
+ language?: string;
24
+ readOnly?: boolean;
21
25
  }) => (
22
26
  <textarea
23
27
  data-testid="code-editor"
28
+ data-language={language}
24
29
  value={value ?? ""}
30
+ readOnly={readOnly}
25
31
  onChange={(evt) => onChange?.(evt.target.value)}
26
32
  />
27
33
  ),
@@ -106,6 +112,21 @@ describe("FileViewer bounded previews", () => {
106
112
  expect(screen.queryByText(/too large to preview/i)).not.toBeInTheDocument();
107
113
  });
108
114
 
115
+ it("renders TOML files as editable TOML", async () => {
116
+ renderViewer({
117
+ file: { ...file, name: "pyproject.toml", size: 20 },
118
+ contents: '[project]\nname = "demo"',
119
+ mimeType: "application/toml",
120
+ isBase64: false,
121
+ isTooLarge: false,
122
+ });
123
+
124
+ const editor =
125
+ await screen.findByTestId<HTMLTextAreaElement>("code-editor");
126
+ expect(editor).toHaveAttribute("data-language", "toml");
127
+ expect(editor).not.toHaveAttribute("readonly");
128
+ });
129
+
109
130
  it("preserves edits to an initially empty text file across remount", async () => {
110
131
  const emptyFile: FileInfo = {
111
132
  id: "/workspace/empty.txt",
@@ -0,0 +1,129 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { buildMediaSource, FileContentRenderer } from "../renderers";
5
+
6
+ vi.mock("@/plugins/impl/code/LazyAnyLanguageCodeMirror", () => ({
7
+ LazyAnyLanguageCodeMirror: ({
8
+ value,
9
+ language,
10
+ readOnly,
11
+ onChange,
12
+ }: {
13
+ value?: string;
14
+ language?: string;
15
+ readOnly?: boolean;
16
+ onChange?: (value: string) => void;
17
+ }) => (
18
+ <textarea
19
+ data-testid="code-editor"
20
+ data-language={language}
21
+ value={value}
22
+ readOnly={readOnly}
23
+ onChange={(event) => onChange?.(event.target.value)}
24
+ />
25
+ ),
26
+ }));
27
+
28
+ vi.mock("@/theme/useTheme", () => ({
29
+ useTheme: () => ({ theme: "light" }),
30
+ }));
31
+
32
+ describe("buildMediaSource", () => {
33
+ it("returns base64 source for binary media", () => {
34
+ expect(
35
+ buildMediaSource({
36
+ contents: "aGVsbG8=",
37
+ mimeType: "image/png",
38
+ isBase64: true,
39
+ }),
40
+ ).toEqual({
41
+ base64: "aGVsbG8=",
42
+ mime: "image/png",
43
+ });
44
+ });
45
+
46
+ it("returns UTF-8 data URL for text-based media", () => {
47
+ const svg = '<svg xmlns="http://www.w3.org/2000/svg"></svg>';
48
+ expect(
49
+ buildMediaSource({
50
+ contents: svg,
51
+ mimeType: "image/svg+xml",
52
+ isBase64: false,
53
+ }),
54
+ ).toEqual({
55
+ url: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`,
56
+ });
57
+ });
58
+ });
59
+
60
+ describe("FileContentRenderer", () => {
61
+ it("renders editable TOML with syntax highlighting", () => {
62
+ const onChange = vi.fn();
63
+ render(
64
+ <FileContentRenderer
65
+ mimeType="application/toml"
66
+ contents={'name = "demo"'}
67
+ readOnly={false}
68
+ onChange={onChange}
69
+ />,
70
+ );
71
+
72
+ const editor = screen.getByTestId<HTMLTextAreaElement>("code-editor");
73
+ expect(editor).toHaveAttribute("data-language", "toml");
74
+ expect(editor).not.toHaveAttribute("readonly");
75
+
76
+ fireEvent.change(editor, { target: { value: 'name = "updated"' } });
77
+ expect(onChange).toHaveBeenCalledWith('name = "updated"');
78
+ });
79
+
80
+ it.each(["application/toml", "application/x-toml", "text/x-toml"])(
81
+ "renders %s as read-only TOML by default",
82
+ (mimeType) => {
83
+ render(
84
+ <FileContentRenderer mimeType={mimeType} contents={'name = "demo"'} />,
85
+ );
86
+
87
+ const editor = screen.getByTestId<HTMLTextAreaElement>("code-editor");
88
+ expect(editor).toHaveAttribute("data-language", "toml");
89
+ expect(editor).toHaveAttribute("readonly");
90
+ },
91
+ );
92
+
93
+ it.each([
94
+ "application/octet-stream",
95
+ "text/plain",
96
+ "text/plain; charset=utf-8",
97
+ ])("uses the filename when a provider returns %s", (mimeType) => {
98
+ render(
99
+ <FileContentRenderer
100
+ mimeType={mimeType}
101
+ filename="pyproject.TOML"
102
+ contents={'name = "demo"'}
103
+ />,
104
+ );
105
+
106
+ expect(screen.getByTestId("code-editor")).toHaveAttribute(
107
+ "data-language",
108
+ "toml",
109
+ );
110
+ });
111
+
112
+ it.each(["file.constructor", "file.__proto__"])(
113
+ "ignores inherited extension-map property in %s",
114
+ (filename) => {
115
+ render(
116
+ <FileContentRenderer
117
+ mimeType="text/plain"
118
+ filename={filename}
119
+ contents="text"
120
+ />,
121
+ );
122
+
123
+ expect(screen.getByTestId("code-editor")).toHaveAttribute(
124
+ "data-language",
125
+ "markdown",
126
+ );
127
+ },
128
+ );
129
+ });
@@ -240,6 +240,7 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
240
240
  {warningBanner}
241
241
  <FileContentRenderer
242
242
  mimeType={mimeType}
243
+ filename={data.file.name}
243
244
  contents={
244
245
  isText
245
246
  ? internalValue
@@ -16,6 +16,7 @@ import { useTheme } from "@/theme/useTheme";
16
16
  import { Arrays } from "@/utils/arrays";
17
17
  import { type Base64String, base64ToDataURL } from "@/utils/json/base64";
18
18
  import { Objects } from "@/utils/objects";
19
+ import { Paths } from "@/utils/paths";
19
20
 
20
21
  const PAGE_SIZE = 25;
21
22
 
@@ -38,13 +39,36 @@ export const MIME_TO_LANGUAGE: Record<string, string> = {
38
39
  "text/css": "css",
39
40
  "text/x-python": "python",
40
41
  "application/json": "json",
42
+ "application/toml": "toml",
43
+ "application/x-toml": "toml",
41
44
  "application/xml": "xml",
45
+ "text/x-toml": "toml",
42
46
  "text/x-yaml": "yaml",
43
47
  "text/csv": "markdown",
44
48
  "text/plain": "markdown",
45
49
  default: "markdown",
46
50
  };
47
51
 
52
+ const EXTENSION_TO_LANGUAGE: Record<string, string> = {
53
+ toml: "toml",
54
+ };
55
+
56
+ const GENERIC_MIME_TYPES = new Set(["application/octet-stream", "text/plain"]);
57
+
58
+ function resolveLanguage(mimeType: string, filename?: string): string {
59
+ const normalizedMimeType = mimeType.split(";", 1)[0].trim().toLowerCase();
60
+ if (GENERIC_MIME_TYPES.has(normalizedMimeType) && filename) {
61
+ const extension = Paths.extension(filename).toLowerCase();
62
+ const language = Object.hasOwn(EXTENSION_TO_LANGUAGE, extension)
63
+ ? EXTENSION_TO_LANGUAGE[extension]
64
+ : undefined;
65
+ if (language) {
66
+ return language;
67
+ }
68
+ }
69
+ return MIME_TO_LANGUAGE[normalizedMimeType] || MIME_TO_LANGUAGE.default;
70
+ }
71
+
48
72
  /**
49
73
  * Media viewer props: provide either a direct `url` or `base64` + `mime`.
50
74
  * When `url` is set it takes precedence.
@@ -167,6 +191,7 @@ export const MediaRenderer: React.FC<MediaSource & { mimeType: string }> = ({
167
191
  */
168
192
  export const FileContentRenderer: React.FC<{
169
193
  mimeType: string;
194
+ filename?: string;
170
195
  /** Text content for text/CSV files. */
171
196
  contents?: string;
172
197
  /** Media source for image/audio/video/PDF files. */
@@ -177,6 +202,7 @@ export const FileContentRenderer: React.FC<{
177
202
  extensions?: Extension[];
178
203
  }> = ({
179
204
  mimeType,
205
+ filename,
180
206
  contents,
181
207
  mediaSource,
182
208
  readOnly = true,
@@ -202,7 +228,7 @@ export const FileContentRenderer: React.FC<{
202
228
  }
203
229
 
204
230
  if (contents != null) {
205
- const language = MIME_TO_LANGUAGE[mimeType] || MIME_TO_LANGUAGE.default;
231
+ const language = resolveLanguage(mimeType, filename);
206
232
  return (
207
233
  <div className="flex-1 overflow-auto">
208
234
  <Suspense>
@@ -0,0 +1,84 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { render, screen } from "@testing-library/react";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
+ import { TooltipProvider } from "@/components/ui/tooltip";
6
+ import { DownloadStorage } from "@/core/storage/request-registry";
7
+ import { StorageFileViewer } from "../storage-file-viewer";
8
+
9
+ vi.mock("@/components/editor/cell/useAddCell", () => ({
10
+ useAddCodeToNewCell: () => vi.fn(),
11
+ }));
12
+
13
+ vi.mock("@/plugins/impl/code/LazyAnyLanguageCodeMirror", () => ({
14
+ LazyAnyLanguageCodeMirror: ({
15
+ value,
16
+ language,
17
+ readOnly,
18
+ }: {
19
+ value?: string;
20
+ language?: string;
21
+ readOnly?: boolean;
22
+ }) => (
23
+ <textarea
24
+ data-testid="code-editor"
25
+ data-language={language}
26
+ value={value}
27
+ readOnly={readOnly}
28
+ />
29
+ ),
30
+ }));
31
+
32
+ vi.mock("@/theme/useTheme", () => ({
33
+ useTheme: () => ({ theme: "light" }),
34
+ }));
35
+
36
+ describe("StorageFileViewer", () => {
37
+ afterEach(() => {
38
+ vi.restoreAllMocks();
39
+ vi.unstubAllGlobals();
40
+ });
41
+
42
+ it("renders TOML from generic storage metadata as read-only TOML", async () => {
43
+ const request = vi.spyOn(DownloadStorage, "request").mockResolvedValue({
44
+ request_id: "request-id",
45
+ url: "https://example.com/pyproject.toml?signature=secret",
46
+ });
47
+ vi.stubGlobal(
48
+ "fetch",
49
+ vi.fn().mockResolvedValue({
50
+ ok: true,
51
+ text: async () => '[project]\nname = "demo"',
52
+ }),
53
+ );
54
+
55
+ render(
56
+ <TooltipProvider>
57
+ <StorageFileViewer
58
+ entry={{
59
+ path: "config/pyproject.toml",
60
+ kind: "file",
61
+ size: 24,
62
+ lastModified: null,
63
+ mimeType: null,
64
+ }}
65
+ namespace="files"
66
+ protocol="s3"
67
+ backendType="fsspec"
68
+ onBack={vi.fn()}
69
+ />
70
+ </TooltipProvider>,
71
+ );
72
+
73
+ const editor =
74
+ await screen.findByTestId<HTMLTextAreaElement>("code-editor");
75
+ expect(editor).toHaveAttribute("data-language", "toml");
76
+ expect(editor).toHaveAttribute("readonly");
77
+ expect(editor).toHaveValue('[project]\nname = "demo"');
78
+ expect(request).toHaveBeenCalledWith({
79
+ namespace: "files",
80
+ path: "config/pyproject.toml",
81
+ preview: true,
82
+ });
83
+ });
84
+ });
@@ -237,6 +237,7 @@ export const StorageFileViewer: React.FC<Props> = ({
237
237
  {renderMetadata({})}
238
238
  <FileContentRenderer
239
239
  mimeType={mime}
240
+ filename={name}
240
241
  contents={preview.type === "text" ? preview.content : undefined}
241
242
  mediaSource={
242
243
  preview.type === "media" ? { url: preview.url } : undefined