@marimo-team/islands 0.25.1-dev24 → 0.25.1-dev26

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.
@@ -135,7 +135,7 @@ function F(e) {
135
135
  }
136
136
  //#endregion
137
137
  //#region src/components/editor/boundary/ErrorBoundary.tsx
138
- var I = (0, T.lazy)(() => import("./feedback-button-CPITlC3N.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
138
+ var I = (0, T.lazy)(() => import("./feedback-button-CJxD9fy8.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
139
139
  let t = (0, w.c)(2), n;
140
140
  return t[0] === e.children ? n = t[1] : (n = /* @__PURE__ */ (0, j.jsx)(O, {
141
141
  FallbackComponent: R,
@@ -18,7 +18,7 @@ function x() {
18
18
  return e.warn("Failed to get version from mount config"), null;
19
19
  }
20
20
  }
21
- var S = x() || "0.25.1-dev24", C = u(S), w = u(!0);
21
+ var S = x() || "0.25.1-dev26", C = u(S), w = u(!0);
22
22
  u(null);
23
23
  //#endregion
24
24
  //#region src/core/wasm/state.ts
@@ -12,7 +12,7 @@ import { t as lt } from "./check-B7cIK6gb.js";
12
12
  import { A as ut, C as dt, D as ft, M as pt, O as mt, S as ht, _ as gt, b as _t, c as vt, d as yt, g as bt, h as xt, i as St, m as Ct, n as wt, p as Tt, s as Et, t as Dt, u as Ot, v as kt, y as At } from "./select-C6plhmZr.js";
13
13
  import { $ as jt, $t as Mt, A as Nt, At as Pt, B as Ft, Bt as It, Ct as Lt, D as Rt, Dt as zt, E as Bt, Et as Vt, F as Ht, Ft as Ut, G as Wt, Gt, H as Kt, Ht as qt, I as Jt, It as Yt, Jt as Xt, K as Zt, Kt as Qt, L as $t, Lt as en, M as tn, Mt as nn, N as rn, Nt as an, O as on, Ot as sn, P as cn, Pt as ln, Q as un, Qt as dn, R as fn, Rt as pn, S as mn, St as hn, T as gn, Tt as _n, U as vn, Ut as yn, V as bn, Vt as xn, W as Sn, Wt as Cn, X as wn, Xt as Tn, Y as En, Yt as Dn, Z as On, Zt as kn, _ as An, _t as jn, a as Mn, an as Nn, b as Pn, bt as Fn, cn as In, ct as Ln, d as Rn, dn as zn, dt as Bn, en as Vn, et as Hn, f as Un, fn as Wn, ft as Gn, gt as Kn, h as qn, ht as Jn, i as Yn, it as Xn, j as Zn, jt as Qn, k as $n, kt as er, l as tr, ln as nr, lt as rr, mt as ir, n as ar, nn as or, nt as sr, o as cr, on as lr, ot as ur, pn as dr, pt as fr, qt as pr, rn as mr, rt as hr, s as gr, sn as _r, st as vr, t as yr, tn as br, tt as xr, u as Sr, un as Cr, ut as wr, vt as Tr, w as Er, wt as Dr, x as Or, xt as kr, y as Ar, yt as jr, z as Mr, zt as Nr } from "./dropdown-menu-CZgjYSAh.js";
14
14
  import { C as Pr, a as Fr, b as Ir, c as Lr, d as Rr, i as zr, n as Br, o as Vr, p as Hr, r as Ur, s as Wr, t as Gr, x as Kr } from "./toDate-C67bxMWn.js";
15
- import { n as qr, t as Jr } from "./ErrorBoundary-BsK2YhEK.js";
15
+ import { n as qr, t as Jr } from "./ErrorBoundary-pWWhtr0s.js";
16
16
  import { t as Yr } from "./clsx-CoeGtWvn.js";
17
17
  import { t as Xr } from "./react-dom-BUgJ-ab_.js";
18
18
  import { t as Zr } from "./jsx-runtime-DgDPJV9S.js";
@@ -2,7 +2,7 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-ofJbxM4x.js";
3
3
  import { t as n } from "./react-dom-BUgJ-ab_.js";
4
4
  import { c as r, l as i, u as a } from "./data-grid-types-BucVmDDp.js";
5
- import { a as o, i as s, n as c, r as l } from "./glide-data-editor-5utWq4-S.js";
5
+ import { a as o, i as s, n as c, r as l } from "./glide-data-editor-cm-NQofk.js";
6
6
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.js
7
7
  var u = /* @__PURE__ */ e(t(), 1), d = /* @__PURE__ */ e(n(), 1), f = /*#__PURE__*/ o("div")({
8
8
  name: "DataGridOverlayEditorStyle",
@@ -5,12 +5,12 @@ import { t as i } from "./compiler-runtime-Cj8ZWiNS.js";
5
5
  import { t as a } from "./copy-icon-CLdENY__.js";
6
6
  import { Ct as o, Ft as s, H as c, L as l, Lt as u, V as d, d as f, un as p } from "./cells-Cksce8br.js";
7
7
  import { b as m } from "./select-C6plhmZr.js";
8
- import { n as h, t as ee } from "./globals-RnznOHva.js";
8
+ import { n as h, t as ee } from "./globals-BquX8N9R.js";
9
9
  import { t as g } from "./jsx-runtime-DgDPJV9S.js";
10
10
  import { C as _, _ as te, i as v } from "./useTheme-DzXmYZ5V.js";
11
11
  import { a as ne, i as re, n as ie, r as ae } from "./dialog-CgNq6y9-.js";
12
12
  import { t as oe } from "./useAsyncData-BD6AStMt.js";
13
- import { t as se } from "./code-visibility-c34jEj9l.js";
13
+ import { t as se } from "./code-visibility-Ba_KMLhg.js";
14
14
  import { i as ce, n as le } from "./error-entries-CvCFdpY2.js";
15
15
  //#region src/components/ui/skeleton.tsx
16
16
  var y = /* @__PURE__ */ e(r(), 1), b = i(), x = g(), ue = (e) => {
@@ -6,7 +6,7 @@ import { i as s, n as c, r as l } from "./copy-icon-CLdENY__.js";
6
6
  import { C as u, c as d, i as f, n as p, s as m, t as h, x as g } from "./select-C6plhmZr.js";
7
7
  import { d as _, h as v, i as y, l as b, n as x, o as S, s as C, t as w, u as T } from "./dropdown-menu-CZgjYSAh.js";
8
8
  import { c as E, d as D, l as O, n as k, o as A, s as ee, t as j, u as te } from "./glide-utils-B3rUT5PI.js";
9
- import { n as ne, t as re } from "./ErrorBoundary-BsK2YhEK.js";
9
+ import { n as ne, t as re } from "./ErrorBoundary-pWWhtr0s.js";
10
10
  import { t as M } from "./react-dom-BUgJ-ab_.js";
11
11
  import { t as N } from "./jsx-runtime-DgDPJV9S.js";
12
12
  import { t as ie } from "./label-BJ49YTvk.js";
@@ -7062,7 +7062,7 @@ function rs(e, t, n, r, i) {
7062
7062
  }
7063
7063
  //#endregion
7064
7064
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/data-editor/data-editor.js
7065
- var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-QUWpjmXy.js")), ss = 0;
7065
+ var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-CpH8-A59.js")), ss = 0;
7066
7066
  function cs(e) {
7067
7067
  return (0, is.default)((0, as.default)((0, as.default)(e).filter((e) => e.span !== void 0).map((e) => (0, Za.default)((e.span?.[0] ?? 0) + 1, (e.span?.[1] ?? 0) + 1))));
7068
7068
  }
@@ -9293,7 +9293,7 @@ function Vs(e, t, n, r, i) {
9293
9293
  }
9294
9294
  //#endregion
9295
9295
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/cells/number-cell.js
9296
- var Hs = K.lazy(async () => await import("./number-overlay-editor-BDCVSh9n.js")), Us = {
9296
+ var Hs = K.lazy(async () => await import("./number-overlay-editor-3AkAzj7F.js")), Us = {
9297
9297
  getAccessibilityString: (e) => e.data?.toString() ?? "",
9298
9298
  kind: W.Number,
9299
9299
  needsHover: (e) => e.hoverEffect === !0,
@@ -1,6 +1,6 @@
1
1
  import { g as e } from "./tooltip-qB8NlSqV.js";
2
2
  import { _ as t } from "./useTheme-DzXmYZ5V.js";
3
- import { r as n } from "./code-visibility-c34jEj9l.js";
3
+ import { r as n } from "./code-visibility-Ba_KMLhg.js";
4
4
  var r = e("triangle-alert", [
5
5
  ["path", {
6
6
  d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
package/dist/main.js CHANGED
@@ -7,7 +7,7 @@ import { C as T, F as E, G as D, I as O, J as k, K as A, L as j, P as M, R as N,
7
7
  import { a as se, f as ce, g as V, i as le, n as ue, o as de, p as fe, r as pe, t as me } from "./tooltip-qB8NlSqV.js";
8
8
  import { $ as he, $t as ge, B as _e, Bt as ve, C as ye, Ct as be, D as xe, Dt as Se, Et as Ce, F as we, G as Te, Gt as Ee, Ht as De, I as Oe, J as ke, Jt as Ae, Kt as je, L as Me, O as Ne, Ot as Pe, P as Fe, Pt as Ie, Q as Le, Qt as Re, Rt as ze, S as Be, St as Ve, T as He, Tt as Ue, U as We, W as Ge, Wt as Ke, bt as qe, c as Je, cn as Ye, ct as Xe, d as Ze, dn as Qe, dt as $e, en as et, f as tt, fn as nt, ft as rt, g as it, gt as at, h as ot, hn as st, k as ct, l as lt, ln as ut, m as dt, mn as ft, n as pt, o as mt, on as ht, ot as gt, p as _t, q as vt, qt as yt, r as bt, rn as xt, rt as St, sn as Ct, st as wt, tn as Tt, u as Et, v as Dt, w as Ot, wt as kt, zt as At } from "./cells-Cksce8br.js";
9
9
  import { D as jt, E as Mt, O as Nt, S as Pt, T as Ft, _ as It, a as Lt, c as Rt, d as zt, f as Bt, g as Vt, h as Ht, i as Ut, l as Wt, m as Gt, n as Kt, o as qt, p as Jt, r as Yt, s as Xt, t as Zt, u as Qt, v as $t, w as en, x as tn, y as nn } from "./spec-CAYwFeV6.js";
10
- import { $t as rn, A as an, At as on, B as sn, Bt as cn, C as ln, Ct as un, D as dn, Dt as fn, E as pn, Et as mn, F as hn, Ft as gn, G as _n, Gt as vn, H as yn, Ht as bn, I as xn, It as Sn, J as Cn, Jt as wn, K as Tn, Kt as En, L as Dn, Lt as On, M as kn, Mt as An, N as jn, Nt as Mn, O as Nn, Ot as Pn, P as Fn, Pt as In, Qt as Ln, R as Rn, Rt as zn, S as Bn, St as Vn, T as Hn, Tt as Un, U as Wn, Ut as Gn, V as Kn, Vt as qn, W as Jn, Wt as Yn, X as Xn, Xt as Zn, Y as Qn, Yt as $n, Zt as er, _ as tr, _t as nr, an as rr, at as ir, b as ar, c as or, cn as sr, ct as cr, d as lr, dn as ur, dt as dr, en as fr, et as pr, f as mr, fn as hr, ft as gr, g as _r, gt as vr, h as yr, hn as br, ht as xr, in as Sr, it as Cr, j as wr, jt as Tr, k as Er, kt as Dr, ln as Or, lt as kr, m as Ar, mn as jr, mt as Mr, nn as Nr, nt as Pr, ot as Fr, p as Ir, pn as Lr, pt as Rr, q as zr, qt as Br, r as Vr, rn as Hr, rt as Ur, sn as Wr, st as Gr, t as Kr, tn as qr, tt as Jr, u as Yr, un as Xr, ut as Zr, v as Qr, vt as $r, w as ei, wt as ti, x as ni, y as ri, yt as ii, z as ai, zt as oi } from "./common-LfW4tQ6o.js";
10
+ import { $t as rn, A as an, At as on, B as sn, Bt as cn, C as ln, Ct as un, D as dn, Dt as fn, E as pn, Et as mn, F as hn, Ft as gn, G as _n, Gt as vn, H as yn, Ht as bn, I as xn, It as Sn, J as Cn, Jt as wn, K as Tn, Kt as En, L as Dn, Lt as On, M as kn, Mt as An, N as jn, Nt as Mn, O as Nn, Ot as Pn, P as Fn, Pt as In, Qt as Ln, R as Rn, Rt as zn, S as Bn, St as Vn, T as Hn, Tt as Un, U as Wn, Ut as Gn, V as Kn, Vt as qn, W as Jn, Wt as Yn, X as Xn, Xt as Zn, Y as Qn, Yt as $n, Zt as er, _ as tr, _t as nr, an as rr, at as ir, b as ar, c as or, cn as sr, ct as cr, d as lr, dn as ur, dt as dr, en as fr, et as pr, f as mr, fn as hr, ft as gr, g as _r, gt as vr, h as yr, hn as br, ht as xr, in as Sr, it as Cr, j as wr, jt as Tr, k as Er, kt as Dr, ln as Or, lt as kr, m as Ar, mn as jr, mt as Mr, nn as Nr, nt as Pr, ot as Fr, p as Ir, pn as Lr, pt as Rr, q as zr, qt as Br, r as Vr, rn as Hr, rt as Ur, sn as Wr, st as Gr, t as Kr, tn as qr, tt as Jr, u as Yr, un as Xr, ut as Zr, v as Qr, vt as $r, w as ei, wt as ti, x as ni, y as ri, yt as ii, z as ai, zt as oi } from "./common-Cqwp2VSj.js";
11
11
  import { c as si, i as ci, n as li, o as ui, t as di } from "./useLifecycle-DPgiiwwU.js";
12
12
  import { t as fi } from "./check-B7cIK6gb.js";
13
13
  import { A as pi, C as mi, D as hi, E as gi, M as _i, O as vi, S as yi, T as bi, a as xi, b as Si, c as Ci, i as wi, k as Ti, l as Ei, n as Di, o as Oi, r as ki, s as Ai, t as ji, w as Mi, x as Ni } from "./select-C6plhmZr.js";
@@ -15,8 +15,8 @@ import { B as Pi, C as Fi, J as Ii, Mt as Li, Nt as Ri, S as zi, Vt as Bi, W as
15
15
  import { C as da, S as fa, T as pa, _ as ma, c as ha, d as ga, f as _a, g as va, h as ya, m as ba, u as xa, x as Sa, y as Ca } from "./toDate-C67bxMWn.js";
16
16
  import { a as wa, c as Ta, d as Ea, f as Da, i as Oa, l as ka, n as Aa, o as ja, r as Ma, s as Na, t as Pa } from "./process-output-C6apL85F.js";
17
17
  import { a as Fa, c as Ia, d as La, i as Ra, l as za, r as Ba, u as Va } from "./glide-utils-B3rUT5PI.js";
18
- import { n as Ha, t as Ua } from "./ErrorBoundary-BsK2YhEK.js";
19
- import { n as Wa, t as Ga } from "./globals-RnznOHva.js";
18
+ import { n as Ha, t as Ua } from "./ErrorBoundary-pWWhtr0s.js";
19
+ import { n as Wa, t as Ga } from "./globals-BquX8N9R.js";
20
20
  import { t as Ka } from "./react-dom-BUgJ-ab_.js";
21
21
  import { t as qa } from "./jsx-runtime-DgDPJV9S.js";
22
22
  import { B as Ja, C as H, Ct as Ya, D as Xa, E as Za, Et as Qa, F as U, G as $a, H as eo, I as to, L as no, M as W, N as ro, O as io, P as ao, Q as oo, R as so, S as G, St as co, Tt as lo, U as uo, W as fo, Y as po, Z as mo, _ as ho, a as go, b as _o, bt as vo, c as yo, d as bo, dt as xo, f as So, g as Co, gt as wo, h as To, i as Eo, j as K, k as Do, l as Oo, m as ko, n as Ao, o as jo, p as Mo, r as No, s as Po, u as Fo, v as Io, vt as Lo, w as Ro, wt as zo, x as Bo, xt as Vo, y as Ho, yt as Uo } from "./use-restore-focus-D5D9xEjZ.js";
@@ -40,7 +40,7 @@ import { t as Ns } from "./useAsyncData-BD6AStMt.js";
40
40
  import { i as Ps, n as Fs, r as Is } from "./formats-Cl_67ghI.js";
41
41
  import { M as Ls, N as Rs } from "./vega-loader.browser-DNST6uVf.js";
42
42
  import { a as zs, n as Bs } from "./loader-DEZSzvma.js";
43
- import { c as Vs, d as Hs, i as Us, l as Ws, o as Gs, s as Ks, t as qs, u as Js } from "./code-visibility-c34jEj9l.js";
43
+ import { c as Vs, d as Hs, i as Us, l as Ws, o as Gs, s as Ks, t as qs, u as Js } from "./code-visibility-Ba_KMLhg.js";
44
44
  import { t as Ys } from "./useDeepCompareMemoize-D_HNdyvI.js";
45
45
  import { t as Xs } from "./esm-BElI3qKH.js";
46
46
  //#region ../node_modules/.pnpm/iconify-icon@2.3.0/node_modules/iconify-icon/dist/iconify-icon.mjs
@@ -10458,7 +10458,7 @@ function RC(e, t) {
10458
10458
  }
10459
10459
  //#endregion
10460
10460
  //#region src/plugins/impl/DataEditorPlugin.tsx
10461
- var zC = J.lazy(() => import("./glide-data-editor-5utWq4-S.js").then((e) => e.t)), BC = xS("marimo-data-editor", { cssStyles: [WS] }).withData(W({
10461
+ var zC = J.lazy(() => import("./glide-data-editor-cm-NQofk.js").then((e) => e.t)), BC = xS("marimo-data-editor", { cssStyles: [WS] }).withData(W({
10462
10462
  initialValue: W({ edits: G(W({
10463
10463
  rowIdx: K(),
10464
10464
  columnId: U(),
@@ -29934,7 +29934,7 @@ function bR(e) {
29934
29934
  }
29935
29935
  //#endregion
29936
29936
  //#region src/components/editor/renderers/slides-layout/slides-layout.tsx
29937
- var xR = J.lazy(() => import("./reveal-component-DegASFv3.js")), SR = (e) => {
29937
+ var xR = J.lazy(() => import("./reveal-component-rC5k5pu3.js")), SR = (e) => {
29938
29938
  let t = (0, X.c)(33), { layout: n, setLayout: r, cells: i, mode: a } = e, o = rs(Ca), s = a === "read" || o, c = rs(_t) > 1, [l, u] = (0, J.useState)(null), d;
29939
29939
  t[0] !== i || t[1] !== n ? (d = vP(i, n), t[0] = i, t[1] = n, t[2] = d) : d = t[2];
29940
29940
  let { slideCells: f, skippedIds: p, noOutputIds: m, slideTypes: h, startCellIndex: g } = d, _;
@@ -1,6 +1,6 @@
1
1
  import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-ofJbxM4x.js";
3
- import { a as n } from "./glide-data-editor-5utWq4-S.js";
3
+ import { a as n } from "./glide-data-editor-cm-NQofk.js";
4
4
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/internal/data-grid-overlay-editor/private/number-overlay-editor-style.js
5
5
  var r = /* @__PURE__ */ e(t()), i = /*#__PURE__*/ n("div")({
6
6
  name: "NumberOverlayEditorStyle",
@@ -4,14 +4,14 @@ import { t as o } from "./react-ofJbxM4x.js";
4
4
  import { t as s } from "./compiler-runtime-Cj8ZWiNS.js";
5
5
  import { g as c, t as l } from "./tooltip-qB8NlSqV.js";
6
6
  import { w as u } from "./cells-Cksce8br.js";
7
- import { $ as d, Q as f, Z as p, an as m, i as h, l as g, ln as _, n as v, on as y, r as b, t as x, u as S } from "./common-LfW4tQ6o.js";
7
+ import { $ as d, Q as f, Z as p, an as m, i as h, l as g, ln as _, n as v, on as y, r as b, t as x, u as S } from "./common-Cqwp2VSj.js";
8
8
  import { M as C } from "./select-C6plhmZr.js";
9
9
  import { J as ee } from "./dropdown-menu-CZgjYSAh.js";
10
10
  import { y as w } from "./toDate-C67bxMWn.js";
11
11
  import { t as T } from "./jsx-runtime-DgDPJV9S.js";
12
12
  import { q as te } from "./use-restore-focus-D5D9xEjZ.js";
13
13
  import { A as E, C as D, b as O } from "./useTheme-DzXmYZ5V.js";
14
- import { a as k, n as ne, t as re } from "./code-visibility-c34jEj9l.js";
14
+ import { a as k, n as ne, t as re } from "./code-visibility-Ba_KMLhg.js";
15
15
  /* empty css */
16
16
  var A = c("sticky-note", [["path", {
17
17
  d: "M21 9a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 15 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.1-dev24",
3
+ "version": "0.25.1-dev26",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -0,0 +1,140 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, screen } from "@testing-library/react";
4
+ import { createStore, Provider } from "jotai";
5
+ import { expect, it, vi } from "vitest";
6
+ import { MockRequestClient } from "@/__mocks__/requests";
7
+ import { TooltipProvider } from "@/components/ui/tooltip";
8
+ import { alertAtom } from "@/core/alerts/state";
9
+ import {
10
+ defaultUserConfig,
11
+ type PackageManagerName,
12
+ } from "@/core/config/config-schema";
13
+ import { userConfigAtom } from "@/core/config/config";
14
+ import { requestClientAtom } from "@/core/network/requests";
15
+ import { sandboxAtom } from "@/core/packages/sandbox-state";
16
+ import { PackageAlert } from "../package-alert";
17
+
18
+ vi.mock("@/hooks/usePackageMetadata", () => ({
19
+ usePackageMetadata: () => ({
20
+ data: { versions: ["1.2.3"], extras: [] },
21
+ error: null,
22
+ isPending: false,
23
+ }),
24
+ }));
25
+
26
+ function mountPackageAlert({
27
+ configuredManager,
28
+ sandboxBackend,
29
+ source = "kernel",
30
+ }: {
31
+ configuredManager: PackageManagerName;
32
+ sandboxBackend: "uv" | "pixi" | null;
33
+ source?: "kernel" | "server";
34
+ }) {
35
+ const store = createStore();
36
+ const client = MockRequestClient.create();
37
+ const config = defaultUserConfig();
38
+ store.set(userConfigAtom, {
39
+ ...config,
40
+ package_management: { manager: configuredManager },
41
+ });
42
+ store.set(requestClientAtom, client);
43
+ store.set(
44
+ sandboxAtom,
45
+ sandboxBackend
46
+ ? {
47
+ backend: sandboxBackend,
48
+ manifest: "",
49
+ filename: "notebook.py",
50
+ }
51
+ : null,
52
+ );
53
+ store.set(alertAtom, {
54
+ ...store.get(alertAtom),
55
+ packageAlert: {
56
+ id: "missing-package",
57
+ kind: "missing",
58
+ packages: ["polars"],
59
+ isolated: true,
60
+ source,
61
+ },
62
+ });
63
+ render(
64
+ <Provider store={store}>
65
+ <TooltipProvider>
66
+ <PackageAlert />
67
+ </TooltipProvider>
68
+ </Provider>,
69
+ );
70
+ return client;
71
+ }
72
+
73
+ it.each(["uv", "pixi"] as const)(
74
+ "shows the fixed %s manager for a sandbox",
75
+ (sandboxBackend) => {
76
+ const client = mountPackageAlert({
77
+ configuredManager: sandboxBackend === "uv" ? "pixi" : "uv",
78
+ sandboxBackend,
79
+ });
80
+
81
+ const managerSelect = screen.getByTestId("install-package-manager-select");
82
+ expect(managerSelect).toHaveValue(sandboxBackend);
83
+ expect(managerSelect).toBeDisabled();
84
+
85
+ fireEvent.click(screen.getByTestId("install-packages-button"));
86
+ expect(client.sendInstallMissingPackages).toHaveBeenCalledWith(
87
+ expect.objectContaining({ manager: sandboxBackend }),
88
+ );
89
+ },
90
+ );
91
+
92
+ it("keeps the configured package manager selectable outside a sandbox", () => {
93
+ mountPackageAlert({ configuredManager: "uv", sandboxBackend: null });
94
+
95
+ const managerSelect = screen.getByTestId("install-package-manager-select");
96
+ expect(managerSelect).toHaveValue("uv");
97
+ expect(managerSelect).not.toBeDisabled();
98
+ });
99
+
100
+ it("installs a selected version in a Pixi sandbox", () => {
101
+ const client = mountPackageAlert({
102
+ configuredManager: "uv",
103
+ sandboxBackend: "pixi",
104
+ });
105
+
106
+ fireEvent.change(screen.getByDisplayValue("latest"), {
107
+ target: { value: "1.2.3" },
108
+ });
109
+ fireEvent.click(screen.getByTestId("install-packages-button"));
110
+ expect(client.sendInstallMissingPackages).toHaveBeenCalledExactlyOnceWith({
111
+ manager: "pixi",
112
+ versions: { polars: "1.2.3" },
113
+ source: "kernel",
114
+ });
115
+ });
116
+
117
+ it("does not offer version selection for Pixi outside a sandbox", () => {
118
+ mountPackageAlert({ configuredManager: "pixi", sandboxBackend: null });
119
+
120
+ expect(screen.queryByDisplayValue("latest")).not.toBeInTheDocument();
121
+ });
122
+
123
+ it("uses the configured package manager for a server installation", () => {
124
+ const client = mountPackageAlert({
125
+ configuredManager: "uv",
126
+ sandboxBackend: "pixi",
127
+ source: "server",
128
+ });
129
+
130
+ expect(
131
+ screen.queryByTestId("install-package-manager-select"),
132
+ ).not.toBeInTheDocument();
133
+
134
+ fireEvent.click(screen.getByTestId("install-packages-button"));
135
+ expect(client.sendInstallMissingPackages).toHaveBeenCalledExactlyOnceWith({
136
+ manager: "uv",
137
+ versions: { polars: "" },
138
+ source: "server",
139
+ });
140
+ });
@@ -1,6 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { zodResolver } from "@hookform/resolvers/zod";
4
+ import { useAtomValue } from "jotai";
4
5
  import {
5
6
  BoxIcon,
6
7
  CheckIcon,
@@ -34,6 +35,7 @@ import {
34
35
  import { useResolvedMarimoConfig } from "@/core/config/config";
35
36
  import type { PackageOperationStatus } from "@/core/kernel/messages";
36
37
  import { useRequestClient } from "@/core/network/requests";
38
+ import { sandboxAtom } from "@/core/packages/sandbox-state";
37
39
  import { RESTART_REQUIRED_DESCRIPTION } from "@/core/packages/toast-components";
38
40
  import { isWasm } from "@/core/wasm/utils";
39
41
  import { usePackageMetadata } from "@/hooks/usePackageMetadata";
@@ -104,6 +106,7 @@ export const PackageAlert: React.FC = () => {
104
106
  const { packageAlert } = useAlerts();
105
107
  const { clearPackageAlert } = useAlertActions();
106
108
  const [userConfig] = useResolvedMarimoConfig();
109
+ const sandbox = useAtomValue(sandboxAtom);
107
110
  const [desiredPackageVersions, setDesiredPackageVersions] = useState<
108
111
  Record<string, string>
109
112
  >({});
@@ -132,8 +135,14 @@ export const PackageAlert: React.FC = () => {
132
135
  return null;
133
136
  }
134
137
 
138
+ const sandboxPackageManager =
139
+ packageAlert.source === "server" ? null : sandbox?.backend;
140
+ const packageManager =
141
+ sandboxPackageManager ?? userConfig.package_management.manager;
135
142
  const doesSupportVersioning =
136
- userConfig.package_management.manager !== "pixi";
143
+ packageAlert.source === "server" ||
144
+ sandbox !== null ||
145
+ packageManager !== "pixi";
137
146
 
138
147
  if (isMissingPackageAlert(packageAlert)) {
139
148
  return (
@@ -207,7 +216,7 @@ export const PackageAlert: React.FC = () => {
207
216
  {packageAlert.isolated ? (
208
217
  <>
209
218
  <InstallPackagesButton
210
- manager={userConfig.package_management.manager}
219
+ manager={packageManager}
211
220
  packages={packageAlert.packages.map((pkg) => {
212
221
  const parsed = parsePackageSpecifier(pkg);
213
222
  const currentExtras =
@@ -219,10 +228,12 @@ export const PackageAlert: React.FC = () => {
219
228
  source={packageAlert.source}
220
229
  />
221
230
 
222
- {!isWasm() && (
231
+ {!isWasm() && packageAlert.source !== "server" && (
223
232
  <>
224
233
  <span className="px-2 text-sm">with</span>{" "}
225
- <PackageManagerForm />
234
+ <PackageManagerForm
235
+ fixedManager={sandboxPackageManager ?? undefined}
236
+ />
226
237
  </>
227
238
  )}
228
239
  </>
@@ -449,7 +460,9 @@ const InstallPackagesButton = ({
449
460
  );
450
461
  };
451
462
 
452
- const PackageManagerForm: React.FC = () => {
463
+ const PackageManagerForm: React.FC<{
464
+ fixedManager?: PackageManagerName;
465
+ }> = ({ fixedManager }) => {
453
466
  const [config, setConfig] = useResolvedMarimoConfig();
454
467
  const { saveUserConfig } = useRequestClient();
455
468
 
@@ -490,8 +503,8 @@ const PackageManagerForm: React.FC = () => {
490
503
  <NativeSelect
491
504
  data-testid="install-package-manager-select"
492
505
  onChange={(e) => field.onChange(e.target.value)}
493
- value={field.value}
494
- disabled={field.disabled}
506
+ value={fixedManager ?? field.value}
507
+ disabled={fixedManager !== undefined || field.disabled}
495
508
  className="inline-flex mr-2"
496
509
  >
497
510
  {PackageManagerNames.map((option) => (