@marimo-team/frontend 0.24.3-dev82 → 0.24.3-dev83
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.
- package/dist/assets/{ConnectedDataExplorerComponent-DkTZ7AvX.js → ConnectedDataExplorerComponent-BpquZl-D.js} +1 -1
- package/dist/assets/{ErrorBoundary-DTpbqvzY.js → ErrorBoundary-BQqmHnXk.js} +2 -2
- package/dist/assets/{LazyAnyLanguageCodeMirror-DYsZfkSk.js → LazyAnyLanguageCodeMirror-CvxfNkWH.js} +2 -2
- package/dist/assets/{RunButton-IMtEkRXV.js → RunButton-DNkIh9-L.js} +8 -8
- package/dist/assets/{abnfDiagram-VCTEODGH-pTFf_XLR.js → abnfDiagram-VCTEODGH-CnUMzJx3.js} +1 -1
- package/dist/assets/add-cell-with-ai-BMP2uVIa.js +76 -0
- package/dist/assets/{agent-panel-DxU4qgxk.js → agent-panel-45n6y1yx.js} +5 -5
- package/dist/assets/ai-model-dropdown-DHCy-cih.js +3 -0
- package/dist/assets/{any-language-editor-DBp5CC3w.js → any-language-editor-C4RQC2Cx.js} +1 -1
- package/dist/assets/{app-config-button-BjxXAmKd.js → app-config-button-_8eL7EEp.js} +1 -1
- package/dist/assets/{architectureDiagram-5GKGNRK7-C7t0AR-N.js → architectureDiagram-5GKGNRK7-bfcUxn_j.js} +1 -1
- package/dist/assets/arrow-down-BFFrjzad.js +1 -0
- package/dist/assets/{blockDiagram-I7D4REHJ-DZgXohrV.js → blockDiagram-I7D4REHJ-BpF8yI-R.js} +1 -1
- package/dist/assets/{cache-panel-DDlfv8BP.js → cache-panel-BR4yhYeu.js} +1 -1
- package/dist/assets/cells-BcQ8Tm3j.js +220 -0
- package/dist/assets/{chat-display-CHxh_MGC.js → chat-display-C_qIajXO.js} +1 -1
- package/dist/assets/{chat-panel-Ca6yjxkg.js → chat-panel-DZ_Wgf9u.js} +3 -3
- package/dist/assets/{chat-ui-D5zW1hYM.js → chat-ui-BrP572Cm.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-CAmhQu-F.js → chunk-IMKFNOWR-C-rPN2GF.js} +1 -1
- package/dist/assets/{chunk-SHT3W25Y-BqEFXoRq.js → chunk-SHT3W25Y-P5kn0hWZ.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-Dxu0eRzD.js → chunk-SVP7TREG-BDSmMBZT.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-gHNMAWa9.js → chunk-TICWLB2K-D3dtJ1vz.js} +1 -1
- package/dist/assets/{classDiagram-ZZMXUADV-DE3i3SzX.js → classDiagram-ZZMXUADV-DHIDyAFc.js} +1 -1
- package/dist/assets/{classDiagram-v2-VYDZK3BY-DE3i3SzX.js → classDiagram-v2-VYDZK3BY-DHIDyAFc.js} +1 -1
- package/dist/assets/{code-visibility-kUtIY_sH.js → code-visibility-DB0T__on.js} +1 -1
- package/dist/assets/{command-palette-BZJRR34P.js → command-palette-DvYu24TH.js} +1 -1
- package/dist/assets/{common-DtiDLSXB.js → common-C53kupuv.js} +1 -1
- package/dist/assets/{components-DScgyZ8j.js → components-BrsyCK82.js} +1 -1
- package/dist/assets/{components-CHh1MGbL.js → components-BuvKvfSS.js} +1 -1
- package/dist/assets/config-CmBpjGXk.js +1 -0
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-C8RK-PLH.js → cynefinDiagram-5FMLGOSQ-CYdbFzEV.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-DZ6JGcBM.js → dagre-GXQ25YYZ-CSEPMX9I.js} +1 -1
- package/dist/assets/dagre-SOh4Qguh.js +1 -0
- package/dist/assets/{data-grid-overlay-editor-BkZfO-uG.js → data-grid-overlay-editor-ierQMJA6.js} +1 -1
- package/dist/assets/dependency-graph-panel-DBaLCinF.js +5 -0
- package/dist/assets/{diagram-S7CK7UJ4-BN77DDKM.js → diagram-S7CK7UJ4-D5YIr9T4.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-BZthP0T4.js → diagram-UQ7AKVKN-uqarxJJM.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-D3GF3lRq.js → diagram-VX7I27RA-HcvMY8pK.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-DnsKITpy.js → diagram-Z3DM3KII-fJYqqcs8.js} +1 -1
- package/dist/assets/{documentation-panel-D8fz9UDV.js → documentation-panel-LhtR1Gdz.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-CHqqdhbQ.js → ebnfDiagram-PWID7BFC-z1dFbGgp.js} +1 -1
- package/dist/assets/edit-page-B28h9Fb6.js +176 -0
- package/dist/assets/{erDiagram-RLTQ6QDP-ChDyfc3w.js → erDiagram-RLTQ6QDP-D0QTGZaN.js} +1 -1
- package/dist/assets/{error-entries-Dy7E9tUS.js → error-entries-C-LFkdXb.js} +1 -1
- package/dist/assets/{error-panel-FYd4Tvsc.js → error-panel-JrTKWez-.js} +1 -1
- package/dist/assets/{feedback-button-Zjt-Mi38.js → feedback-button-CXZUuGO0.js} +2 -2
- package/dist/assets/file-explorer-panel-0uckfsy9.js +1 -0
- package/dist/assets/{file-name-input-DifonhZ7.js → file-name-input-B1oP4qI1.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-CelwDl0Y.js → flowDiagram-HODETNUW-CvnIcAyp.js} +1 -1
- package/dist/assets/{gallery-page-C0T1oyzr.js → gallery-page-Dr6gmPct.js} +1 -1
- package/dist/assets/{glide-data-editor-Dqd-if6R.js → glide-data-editor-BdNlPATo.js} +4 -4
- package/dist/assets/{graphlib-6_f7N0YM.js → graphlib-coUtpRhg.js} +1 -1
- package/dist/assets/has-HvSiby4C.js +1 -0
- package/dist/assets/home-page-DU_vk7YP.js +4 -0
- package/dist/assets/index-C0mx13kv.css +2 -0
- package/dist/assets/index-anJECncb.js +62 -0
- package/dist/assets/{infoDiagram-27XIBGKW-Dh0ztpYZ.js → infoDiagram-27XIBGKW-B-ESiKKL.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-Yy11Lj-8.js → ishikawaDiagram-5VMMS53U-958453Qs.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-_hCm9ITM.js → kanban-definition-UXKFOSKX-Cl3MvgdV.js} +1 -1
- package/dist/assets/{logs-panel-D_Ki0PRi.js → logs-panel-B6dW8QcS.js} +1 -1
- package/dist/assets/{mermaid-DUZOkwYg.js → mermaid-Dk7Zo_kD.js} +4 -4
- package/dist/assets/{mindmap-definition-YA3MSWOX-CqKVab9Z.js → mindmap-definition-YA3MSWOX-ObRzpp8l.js} +1 -1
- package/dist/assets/{number-overlay-editor-BFwgibS5.js → number-overlay-editor-BaA6YHpZ.js} +1 -1
- package/dist/assets/{outline-panel-BVLrHsJa.js → outline-panel-AF6eqkBP.js} +1 -1
- package/dist/assets/packages-panel-DnQBjrbw.js +1 -0
- package/dist/assets/panel-context-BPaQeOuV.js +1 -0
- package/dist/assets/panels-Gl9xHiUG.js +33 -0
- package/dist/assets/{pegDiagram-XKGWAZYB-Cq-QrQFc.js → pegDiagram-XKGWAZYB-Dr1N-uz9.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-DXU0ndOt.js → pieDiagram-E7YTZNPT-CuOB3ooB.js} +1 -1
- package/dist/assets/{process-output-B76bPsnA.js → process-output-dY19eMY7.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-CFI_pgSK.js → railroadDiagram-O6MQD6OU-B-2q9lGc.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-DgdygEWz.js → requirementDiagram-BXWQKSXE-DDO3d-q-.js} +1 -1
- package/dist/assets/{reveal-component-BqiZOsW3.js → reveal-component-CVZuomdL.js} +3 -3
- package/dist/assets/run-page-q9RV38Se.js +1 -0
- package/dist/assets/scratchpad-panel-CB7Fy9xQ.js +1 -0
- package/dist/assets/scroll-to-bottom-button-BSCkDXet.js +1 -0
- package/dist/assets/{secrets-panel-CeovmJAu.js → secrets-panel-fyK3DrMo.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-Cq7P3SPg.js → sequenceDiagram-WJ2MYXX4-09ej9W_c.js} +1 -1
- package/dist/assets/session-panel-CQR7EQYe.js +1 -0
- package/dist/assets/snippets-panel-C8pCQY6-.js +1 -0
- package/dist/assets/{stateDiagram-D77RDMKH-CO8GuJdh.js → stateDiagram-D77RDMKH-Dwreh_3X.js} +1 -1
- package/dist/assets/{stateDiagram-v2-MP3YSRHH-DA7CflqT.js → stateDiagram-v2-MP3YSRHH-CYctHUHC.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-Bkf4BWja.js → swimlanes-42K2YHIH-CqtUaFZN.js} +1 -1
- package/dist/assets/{swimlanesDiagram-VR7AAH4N-Bf0FHwi-.js → swimlanesDiagram-VR7AAH4N-BTvyGqcs.js} +1 -1
- package/dist/assets/{swiper-component-Dcb47cI1.js → swiper-component-BPjhKuFC.js} +1 -1
- package/dist/assets/{terminal-bvd8BLSi.js → terminal-CWmhjUVd.js} +2 -2
- package/dist/assets/{timeline-definition-24CTP7MA-CWdT681e.js → timeline-definition-24CTP7MA-DESfjZe6.js} +1 -1
- package/dist/assets/tracing-DHQdLJrw.js +1 -0
- package/dist/assets/{tracing-panel-AQUl8b58.js → tracing-panel-DkDpfzxp.js} +2 -2
- package/dist/assets/{useCellActionButton-DIiKKxoN.js → useCellActionButton-JBMxiVrN.js} +1 -1
- package/dist/assets/{vega-component-C5LY21OO.js → vega-component-C3dIfNSQ.js} +1 -1
- package/dist/assets/{vega-embed-container-C6Hr9CZj.js → vega-embed-container-DRnOQFW3.js} +1 -1
- package/dist/assets/{vennDiagram-4TSXK5OY-B3uJF3gV.js → vennDiagram-4TSXK5OY-DVP0MtbH.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-DGmcLh5J.js → wardleyDiagram-VM6X3IG4-Boyg2AlL.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-kFxqIAk2.js → xychartDiagram-S5SC5T6Z-6MNoagFi.js} +1 -1
- package/dist/index.html +6 -6
- package/package.json +1 -1
- package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +186 -0
- package/src/components/editor/alerts/__tests__/startup-progress.test.tsx +185 -0
- package/src/components/editor/alerts/connection-notice.tsx +100 -54
- package/src/components/editor/alerts/startup-output.tsx +173 -0
- package/src/components/editor/alerts/startup-progress.tsx +204 -0
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +53 -4
- package/src/components/editor/chrome/panels/__tests__/sandbox-details.test.tsx +358 -0
- package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +5 -2
- package/src/components/editor/chrome/panels/packages-panel.tsx +32 -21
- package/src/components/editor/chrome/panels/sandbox-details-state.ts +38 -0
- package/src/components/editor/chrome/panels/sandbox-panel.tsx +188 -131
- package/src/components/editor/chrome/panels/sandbox-toggle.tsx +52 -0
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +7 -0
- package/src/components/editor/package-alert.tsx +112 -66
- package/src/core/alerts/__tests__/environment.test.ts +183 -0
- package/src/core/alerts/__tests__/state.test.tsx +240 -0
- package/src/core/alerts/environment.ts +57 -0
- package/src/core/alerts/state.ts +155 -99
- package/src/core/islands/bootstrap.ts +2 -1
- package/src/core/kernel/messages.ts +2 -2
- package/src/core/network/connection-notice.ts +45 -12
- package/src/core/network/connection.ts +19 -0
- package/src/core/network/useConnectionNotice.ts +53 -0
- package/src/core/packages/__tests__/useSandboxController.test.tsx +86 -5
- package/src/core/packages/sandbox-state.ts +56 -4
- package/src/core/packages/useSandboxController.ts +27 -7
- package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +199 -8
- package/src/core/websocket/types.ts +1 -1
- package/src/core/websocket/useMarimoKernelConnection.tsx +31 -19
- package/src/stories/sandbox.stories.tsx +230 -50
- package/dist/assets/add-cell-with-ai-CSNC0MIy.js +0 -76
- package/dist/assets/ai-model-dropdown-Ct4CTWKe.js +0 -3
- package/dist/assets/cells-C0itXtA7.js +0 -220
- package/dist/assets/config-CBLBAU5c.js +0 -1
- package/dist/assets/dagre-Be6hV3Qt.js +0 -1
- package/dist/assets/dependency-graph-panel-DhGTFsO9.js +0 -5
- package/dist/assets/edit-page-Cw1A5Rhq.js +0 -176
- package/dist/assets/file-explorer-panel-BpklXFSu.js +0 -1
- package/dist/assets/has-D5vyh6J_.js +0 -1
- package/dist/assets/home-page-CN05bwXu.js +0 -4
- package/dist/assets/index-B8OSEJVD.css +0 -2
- package/dist/assets/index-CcaMC2ZX.js +0 -62
- package/dist/assets/packages-panel-cq-qnvM5.js +0 -1
- package/dist/assets/panels-DwxpnIFf.js +0 -33
- package/dist/assets/run-page-DVqnr-8x.js +0 -1
- package/dist/assets/scratchpad-panel-BT2lF-Gs.js +0 -1
- package/dist/assets/scroll-to-bottom-button-D4qWtyN8.js +0 -1
- package/dist/assets/session-panel-CGddxX8c.js +0 -1
- package/dist/assets/snippets-panel-UawnfExC.js +0 -1
- package/dist/assets/tracing-BbV840Cl.js +0 -1
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
import { useAtomValue } from "jotai";
|
|
3
|
-
import {
|
|
4
|
-
AlertCircleIcon,
|
|
5
|
-
ChevronUpIcon,
|
|
6
|
-
FileCodeIcon,
|
|
7
|
-
RefreshCwIcon,
|
|
8
|
-
} from "lucide-react";
|
|
2
|
+
import { useAtom, useAtomValue } from "jotai";
|
|
3
|
+
import { RefreshCwIcon } from "lucide-react";
|
|
9
4
|
import { connectionNoticeAtom } from "@/core/network/connection-notice";
|
|
10
|
-
import { Spinner } from "@/components/icons/spinner";
|
|
11
5
|
import { Button } from "@/components/ui/button";
|
|
6
|
+
import { useRestartKernel } from "@/components/editor/actions/useRestartKernel";
|
|
12
7
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from "@/components/ui/dropdown-menu";
|
|
18
|
-
import { Tooltip } from "@/components/ui/tooltip";
|
|
19
|
-
import { isConnectedAtom } from "@/core/network/connection";
|
|
8
|
+
isConnectedAtom,
|
|
9
|
+
startupProgressAtom,
|
|
10
|
+
} from "@/core/network/connection";
|
|
11
|
+
import type { DisplayConnectionNotice } from "@/core/network/useConnectionNotice";
|
|
20
12
|
import {
|
|
13
|
+
preparationAtom,
|
|
21
14
|
sandboxActionsAtom,
|
|
22
15
|
sandboxAtom,
|
|
23
16
|
sandboxSyncAtom,
|
|
17
|
+
sandboxSyncOperationAtom,
|
|
24
18
|
} from "@/core/packages/sandbox-state";
|
|
25
19
|
import { cn } from "@/utils/cn";
|
|
20
|
+
import { usePanelSection } from "./panel-context";
|
|
21
|
+
import { sandboxDetailsExpandedAtom } from "./sandbox-details-state";
|
|
22
|
+
import { StartupOutput } from "../../alerts/startup-output";
|
|
23
|
+
import {
|
|
24
|
+
ConnectionStatusIcon,
|
|
25
|
+
StartupProgress,
|
|
26
|
+
} from "../../alerts/startup-progress";
|
|
26
27
|
|
|
27
28
|
export function SandboxErrorOutput({ error }: { error: string }) {
|
|
28
29
|
return (
|
|
@@ -36,138 +37,194 @@ export function SandboxErrorOutput({ error }: { error: string }) {
|
|
|
36
37
|
);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
const notice = useAtomValue(connectionNoticeAtom);
|
|
40
|
+
function SandboxRecovery({ notice }: { notice: DisplayConnectionNotice }) {
|
|
41
41
|
const sandbox = useAtomValue(sandboxAtom);
|
|
42
42
|
const actions = useAtomValue(sandboxActionsAtom);
|
|
43
|
-
|
|
43
|
+
const sync = useAtomValue(sandboxSyncAtom);
|
|
44
|
+
if (notice.pending || notice.ready) {
|
|
44
45
|
return null;
|
|
45
46
|
}
|
|
46
47
|
return (
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
<>
|
|
49
|
+
<p className="mt-2 text-foreground">{notice.description}</p>
|
|
50
|
+
{notice.error && <SandboxErrorOutput error={notice.error} />}
|
|
51
|
+
<div className="flex items-center gap-2 mt-3">
|
|
52
|
+
<Button
|
|
53
|
+
variant="outline"
|
|
54
|
+
size="xs"
|
|
55
|
+
disabled={!actions || sandbox?.manifest == null}
|
|
56
|
+
onClick={() => actions?.editManifest()}
|
|
57
|
+
>
|
|
58
|
+
Edit manifest…
|
|
59
|
+
</Button>
|
|
60
|
+
{notice.kind === "sync" && sync.kind === "restart-required" ? (
|
|
61
|
+
<SandboxRestart />
|
|
58
62
|
) : (
|
|
59
|
-
<
|
|
63
|
+
<Button
|
|
64
|
+
variant="text"
|
|
65
|
+
size="xs"
|
|
66
|
+
disabled={!actions}
|
|
67
|
+
onClick={() => actions?.sync()}
|
|
68
|
+
>
|
|
69
|
+
Retry sync
|
|
70
|
+
</Button>
|
|
60
71
|
)}
|
|
61
|
-
<h2>{notice.title}</h2>
|
|
62
72
|
</div>
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
{sandbox?.manifest == null && (
|
|
74
|
+
<p className="mt-3 text-xs text-muted-foreground">
|
|
75
|
+
A manifest will be available once this new notebook starts.
|
|
76
|
+
</p>
|
|
77
|
+
)}
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function SandboxRestart() {
|
|
83
|
+
const restartKernel = useRestartKernel();
|
|
84
|
+
return (
|
|
85
|
+
<Button variant="text" size="xs" onClick={restartKernel}>
|
|
86
|
+
Restart Kernel
|
|
87
|
+
</Button>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function SandboxStartupPanel({ notice }: { notice: DisplayConnectionNotice }) {
|
|
92
|
+
const showSteps =
|
|
93
|
+
notice.kind === "startup" &&
|
|
94
|
+
(notice.ready ||
|
|
95
|
+
notice.phase === "preparing-environment" ||
|
|
96
|
+
notice.phase === "starting-kernel");
|
|
97
|
+
return (
|
|
98
|
+
<div className="min-w-0 text-sm">
|
|
99
|
+
{showSteps ? (
|
|
100
|
+
<StartupProgress notice={notice} surface="sidebar" />
|
|
101
|
+
) : (
|
|
102
|
+
<div className="flex items-center gap-2" role="status">
|
|
103
|
+
<ConnectionStatusIcon notice={notice} />
|
|
104
|
+
<h2>{notice.title}</h2>
|
|
105
|
+
</div>
|
|
91
106
|
)}
|
|
107
|
+
<SandboxRecovery notice={notice} />
|
|
92
108
|
</div>
|
|
93
109
|
);
|
|
94
110
|
}
|
|
95
111
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
function SandboxSyncStatus({ notice }: { notice: DisplayConnectionNotice }) {
|
|
113
|
+
return (
|
|
114
|
+
<div className="mb-5 text-sm">
|
|
115
|
+
<output className="flex items-center gap-2 text-xs">
|
|
116
|
+
<ConnectionStatusIcon notice={notice} />
|
|
117
|
+
<span>{notice.title}</span>
|
|
118
|
+
</output>
|
|
119
|
+
<SandboxRecovery notice={notice} />
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function SandboxSyncDetails({
|
|
125
|
+
notice,
|
|
126
|
+
}: {
|
|
127
|
+
notice: DisplayConnectionNotice | null;
|
|
128
|
+
}) {
|
|
129
|
+
const operation = useAtomValue(sandboxSyncOperationAtom);
|
|
130
|
+
if (!operation && !notice) {
|
|
103
131
|
return null;
|
|
104
132
|
}
|
|
105
|
-
const pending = operation.pending || notice?.pending;
|
|
106
|
-
const status = operation.pending
|
|
107
|
-
? "Syncing sandbox…"
|
|
108
|
-
: (notice?.title ?? (connected ? "Sandbox ready" : "Sandbox not started"));
|
|
109
133
|
return (
|
|
110
|
-
<div className="
|
|
111
|
-
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
134
|
+
<div className="mt-5 min-w-0">
|
|
135
|
+
{notice ? (
|
|
136
|
+
<SandboxSyncStatus notice={notice} />
|
|
137
|
+
) : (
|
|
138
|
+
<p className="text-sm">Environment synced</p>
|
|
139
|
+
)}
|
|
140
|
+
<StartupOutput
|
|
141
|
+
key={operation?.operation_id}
|
|
142
|
+
logs={operation?.logs.environment ?? ""}
|
|
143
|
+
state={
|
|
144
|
+
operation?.status.kind === "running"
|
|
145
|
+
? "running"
|
|
146
|
+
: operation?.status.kind === "succeeded"
|
|
147
|
+
? "succeeded"
|
|
148
|
+
: "failed"
|
|
149
|
+
}
|
|
150
|
+
label="sandbox sync output"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function SandboxDetails() {
|
|
157
|
+
const section = usePanelSection();
|
|
158
|
+
const connected = useAtomValue(isConnectedAtom);
|
|
159
|
+
const notice = useAtomValue(connectionNoticeAtom);
|
|
160
|
+
const preparation = useAtomValue(preparationAtom);
|
|
161
|
+
const progress = useAtomValue(startupProgressAtom);
|
|
162
|
+
const [expanded, setExpanded] = useAtom(sandboxDetailsExpandedAtom);
|
|
163
|
+
const startup: DisplayConnectionNotice | null =
|
|
164
|
+
notice?.kind === "startup"
|
|
165
|
+
? { ...notice, ready: false }
|
|
166
|
+
: preparation || progress
|
|
167
|
+
? {
|
|
168
|
+
kind: "startup",
|
|
169
|
+
sandbox: true,
|
|
170
|
+
title: "Notebook started",
|
|
171
|
+
description: "The notebook is ready to run.",
|
|
172
|
+
pending: false,
|
|
173
|
+
ready: true,
|
|
174
|
+
error: null,
|
|
175
|
+
}
|
|
176
|
+
: null;
|
|
177
|
+
return (
|
|
178
|
+
<section
|
|
179
|
+
id={`sandbox-details-${section}`}
|
|
180
|
+
aria-label="Sandbox details"
|
|
181
|
+
hidden={!expanded}
|
|
182
|
+
className={cn(
|
|
183
|
+
"min-w-0 overflow-auto p-4",
|
|
184
|
+
connected ? "shrink-0 max-h-[65%] border-b" : "flex-1",
|
|
185
|
+
)}
|
|
186
|
+
onPointerDownCapture={() => setExpanded(true)}
|
|
187
|
+
onFocusCapture={() => setExpanded(true)}
|
|
188
|
+
>
|
|
189
|
+
{notice?.kind === "connection" && (
|
|
190
|
+
<SandboxSyncStatus notice={{ ...notice, ready: false }} />
|
|
191
|
+
)}
|
|
192
|
+
{startup && <SandboxStartupPanel notice={startup} />}
|
|
193
|
+
{connected && (
|
|
194
|
+
<SandboxSyncDetails
|
|
195
|
+
notice={notice?.kind === "sync" ? { ...notice, ready: false } : null}
|
|
196
|
+
/>
|
|
197
|
+
)}
|
|
198
|
+
{connected && (!notice || notice.pending) && <SandboxActions />}
|
|
199
|
+
</section>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function SandboxActions() {
|
|
204
|
+
const sandbox = useAtomValue(sandboxAtom);
|
|
205
|
+
const actions = useAtomValue(sandboxActionsAtom);
|
|
206
|
+
const pending = useAtomValue(sandboxSyncAtom).kind === "running";
|
|
207
|
+
return (
|
|
208
|
+
<div className="flex items-center gap-4 mt-5 border-t pt-3">
|
|
209
|
+
<Button
|
|
210
|
+
variant="text"
|
|
211
|
+
size="xs"
|
|
212
|
+
className="text-muted-foreground gap-1.5 p-0"
|
|
213
|
+
disabled={pending || !actions}
|
|
214
|
+
onClick={() => actions?.sync()}
|
|
215
|
+
>
|
|
216
|
+
<RefreshCwIcon className="size-3" aria-hidden={true} />
|
|
217
|
+
Sync
|
|
218
|
+
</Button>
|
|
219
|
+
<Button
|
|
220
|
+
variant="text"
|
|
221
|
+
size="xs"
|
|
222
|
+
className="text-muted-foreground p-0"
|
|
223
|
+
disabled={!actions || sandbox?.manifest == null}
|
|
224
|
+
onClick={() => actions?.editManifest()}
|
|
225
|
+
>
|
|
226
|
+
Edit manifest…
|
|
227
|
+
</Button>
|
|
171
228
|
</div>
|
|
172
229
|
);
|
|
173
230
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
import { useAtom, useAtomValue } from "jotai";
|
|
3
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
4
|
+
import { connectionNoticeAtom } from "@/core/network/connection-notice";
|
|
5
|
+
import { sandboxAtom } from "@/core/packages/sandbox-state";
|
|
6
|
+
import { cn } from "@/utils/cn";
|
|
7
|
+
import type { PanelSection } from "./panel-context";
|
|
8
|
+
import { sandboxDetailsExpandedAtom } from "./sandbox-details-state";
|
|
9
|
+
|
|
10
|
+
export function SandboxToggle({ section }: { section: PanelSection }) {
|
|
11
|
+
const sandbox = useAtomValue(sandboxAtom);
|
|
12
|
+
const notice = useAtomValue(connectionNoticeAtom);
|
|
13
|
+
const [expanded, setExpanded] = useAtom(sandboxDetailsExpandedAtom);
|
|
14
|
+
if (!sandbox?.backend) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const status = notice ? (notice.pending ? "pending" : "error") : "healthy";
|
|
18
|
+
return (
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
aria-label={`${sandbox.backend} sandbox`}
|
|
22
|
+
aria-expanded={expanded}
|
|
23
|
+
aria-controls={`sandbox-details-${section}`}
|
|
24
|
+
title={notice?.title ?? "Sandbox details"}
|
|
25
|
+
className={cn(
|
|
26
|
+
"flex items-center gap-1.5 rounded px-1.5 py-1 text-xs whitespace-nowrap hover:bg-accent focus-visible:outline-2 focus-visible:outline-ring",
|
|
27
|
+
status === "error" ? "text-(--red-11)" : "text-foreground",
|
|
28
|
+
)}
|
|
29
|
+
onClick={() => setExpanded(!expanded)}
|
|
30
|
+
>
|
|
31
|
+
<output
|
|
32
|
+
aria-label={notice?.title ?? "Sandbox healthy"}
|
|
33
|
+
className={cn(
|
|
34
|
+
"size-1.5 shrink-0 rounded-full",
|
|
35
|
+
status === "error"
|
|
36
|
+
? "bg-(--red-9)"
|
|
37
|
+
: status === "pending"
|
|
38
|
+
? "bg-muted-foreground motion-safe:animate-pulse"
|
|
39
|
+
: "bg-(--grass-9)",
|
|
40
|
+
)}
|
|
41
|
+
/>
|
|
42
|
+
{sandbox.backend} sandbox
|
|
43
|
+
<ChevronDownIcon
|
|
44
|
+
aria-hidden={true}
|
|
45
|
+
className={cn(
|
|
46
|
+
"size-3 shrink-0 text-muted-foreground",
|
|
47
|
+
expanded && "rotate-180",
|
|
48
|
+
)}
|
|
49
|
+
/>
|
|
50
|
+
</button>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -34,6 +34,7 @@ import { ErrorBoundary } from "../../boundary/ErrorBoundary";
|
|
|
34
34
|
import { raf2 } from "../../navigation/focus-utils";
|
|
35
35
|
import { ContextAwarePanel } from "../panels/context-aware-panel/context-aware-panel";
|
|
36
36
|
import { PanelSectionProvider } from "../panels/panel-context";
|
|
37
|
+
import { SandboxToggle } from "../panels/sandbox-toggle";
|
|
37
38
|
import { useTheme } from "@/theme/useTheme";
|
|
38
39
|
import {
|
|
39
40
|
LazyAgentPanel,
|
|
@@ -389,6 +390,9 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
389
390
|
{selectedPanel}
|
|
390
391
|
</span>
|
|
391
392
|
)}
|
|
393
|
+
{selectedPanel === "packages" && (
|
|
394
|
+
<SandboxToggle section="sidebar" />
|
|
395
|
+
)}
|
|
392
396
|
<Button
|
|
393
397
|
data-testid="close-helper-pane"
|
|
394
398
|
className="m-0"
|
|
@@ -544,6 +548,9 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
544
548
|
<BackendConnectionStatus />
|
|
545
549
|
<LspStatus />
|
|
546
550
|
<div className="flex-1" />
|
|
551
|
+
{selectedDeveloperPanelTab === "packages" && (
|
|
552
|
+
<SandboxToggle section="developer-panel" />
|
|
553
|
+
)}
|
|
547
554
|
<Button
|
|
548
555
|
size="xs"
|
|
549
556
|
variant="text"
|