@marimo-team/islands 0.22.1-dev37 → 0.22.1-dev39
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/{ConnectedDataExplorerComponent-DTOsfq2x.js → ConnectedDataExplorerComponent-DuD8BVl6.js} +2 -2
- package/dist/{Plot-WhbJAbBh.js → Plot-BxlSHo0G.js} +47 -38
- package/dist/{chat-ui-CJCTr1kq.js → chat-ui-Cel1kBfc.js} +1 -1
- package/dist/{glide-data-editor-BQPLhydy.js → glide-data-editor-BqnvTmDo.js} +1712 -1681
- package/dist/main.js +360 -354
- package/dist/{process-output-D0SEeV3t.js → process-output-DC1TOnIl.js} +1 -1
- package/dist/{spec-CiHus5Bb.js → spec-CD7QaCV-.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/useLifecycle-4fA1pHoh.js +177 -0
- package/package.json +1 -1
- package/src/__mocks__/common.ts +4 -4
- package/src/components/chat/acp/agent-panel.tsx +2 -2
- package/src/components/data-table/__tests__/columns.test.tsx +7 -7
- package/src/components/data-table/cell-hover-template/types.ts +1 -1
- package/src/components/data-table/cell-hover-text/types.ts +1 -1
- package/src/components/data-table/cell-selection/__tests__/feature.test.ts +1 -1
- package/src/components/data-table/cell-selection/types.ts +1 -1
- package/src/components/data-table/cell-styling/types.ts +1 -1
- package/src/components/data-table/charts/chart-spec/altair-generator.ts +2 -2
- package/src/components/data-table/column-formatting/types.ts +2 -2
- package/src/components/data-table/column-summary/legacy-chart-spec.ts +1 -1
- package/src/components/data-table/column-wrapping/types.ts +1 -1
- package/src/components/data-table/copy-column/types.ts +1 -1
- package/src/components/data-table/focus-row/types.ts +1 -1
- package/src/components/data-table/loading-table.tsx +1 -1
- package/src/components/data-table/range-focus/__tests__/atoms.test.ts +2 -2
- package/src/components/data-table/range-focus/atoms.ts +2 -2
- package/src/components/dependency-graph/dependency-graph-tree.tsx +1 -1
- package/src/components/editor/__tests__/dynamic-favicon.test.tsx +1 -1
- package/src/components/editor/actions/pair-with-agent-modal.tsx +142 -0
- package/src/components/editor/actions/useNotebookActions.tsx +10 -0
- package/src/components/editor/ai/ai-completion-editor.tsx +1 -1
- package/src/components/editor/app-container.tsx +1 -1
- package/src/components/editor/chrome/panels/empty-state.tsx +1 -0
- package/src/components/editor/controls/keyboard-shortcuts.tsx +1 -1
- package/src/components/editor/navigation/__tests__/navigation.test.ts +1 -1
- package/src/components/editor/navigation/navigation.ts +1 -1
- package/src/components/editor/notebook-cell.tsx +1 -1
- package/src/components/editor/output/JsonOutput.tsx +4 -4
- package/src/components/editor/output/ansi-reduce.ts +2 -2
- package/src/components/editor/output/console/ConsoleOutput.tsx +1 -1
- package/src/components/editor/renderers/cells-renderer.tsx +1 -1
- package/src/components/editor/renderers/grid-layout/grid-layout.tsx +1 -1
- package/src/components/editor/renderers/plugins.ts +1 -1
- package/src/components/editor/renderers/slides-layout/types.ts +2 -2
- package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +2 -2
- package/src/components/editor/renderers/vertical-layout/__tests__/vertical-layout.test.ts +1 -1
- package/src/components/find-replace/find-replace.tsx +3 -1
- package/src/components/forms/form.tsx +1 -1
- package/src/components/forms/options.ts +1 -1
- package/src/components/static-html/static-banner.tsx +2 -2
- package/src/components/terminal/terminal.tsx +4 -4
- package/src/components/ui/button.tsx +1 -1
- package/src/components/ui/command.tsx +1 -1
- package/src/core/ai/context/providers/__tests__/datasource.test.ts +1 -1
- package/src/core/ai/context/providers/__tests__/error.test.ts +1 -1
- package/src/core/ai/context/providers/__tests__/variable.test.ts +1 -1
- package/src/core/ai/context/registry.ts +2 -2
- package/src/core/ai/tools/registry.ts +1 -1
- package/src/core/cells/__tests__/cells.test.ts +2 -2
- package/src/core/cells/__tests__/scrollCellIntoView.test.ts +1 -1
- package/src/core/cells/__tests__/session.test.ts +1 -1
- package/src/core/cells/__tests__/utils.test.ts +1 -1
- package/src/core/cells/cells.ts +1 -1
- package/src/core/cells/ids.ts +1 -1
- package/src/core/codemirror/ai/request.ts +1 -1
- package/src/core/codemirror/copilot/__tests__/language-server.test.ts +1 -1
- package/src/core/codemirror/copilot/__tests__/transport.test.ts +1 -1
- package/src/core/codemirror/copilot/language-server.ts +1 -1
- package/src/core/codemirror/copilot/types.ts +1 -1
- package/src/core/codemirror/facet.ts +1 -1
- package/src/core/codemirror/language/__tests__/sql.test.ts +4 -4
- package/src/core/codemirror/language/languages/sql/completion-builder.ts +1 -1
- package/src/core/codemirror/language/metadata.ts +1 -1
- package/src/core/codemirror/language/types.ts +1 -1
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -1
- package/src/core/codemirror/lsp/notebook-lsp.ts +1 -1
- package/src/core/codemirror/misc/__tests__/dnd.test.ts +1 -1
- package/src/core/codemirror/rtc/loro/awareness.ts +1 -1
- package/src/core/config/feature-flag.tsx +1 -1
- package/src/core/dom/outline.ts +1 -1
- package/src/core/export/__tests__/hooks.test.ts +1 -1
- package/src/core/hotkeys/__tests__/hotkeys.test.ts +1 -1
- package/src/core/hotkeys/shortcuts.ts +1 -1
- package/src/core/islands/__tests__/bridge.test.ts +2 -2
- package/src/core/islands/bridge.ts +2 -2
- package/src/core/islands/components/output-wrapper.tsx +1 -1
- package/src/core/islands/parse.ts +1 -1
- package/src/core/lsp/__tests__/transport.test.ts +1 -1
- package/src/core/network/DeferredRequestRegistry.ts +1 -1
- package/src/core/network/__tests__/requests-network.test.ts +1 -1
- package/src/core/network/api.ts +2 -2
- package/src/core/network/requests-lazy.ts +1 -1
- package/src/core/network/requests-toasting.tsx +1 -1
- package/src/core/static/files.ts +1 -1
- package/src/core/vscode/vscode-bindings.ts +1 -1
- package/src/core/wasm/bridge.ts +3 -3
- package/src/core/wasm/worker/tracer.ts +1 -1
- package/src/core/websocket/useWebSocket.tsx +2 -2
- package/src/css/globals.css +37 -61
- package/src/custom.d.ts +1 -1
- package/src/hooks/__tests__/useDuplicateShortcuts.test.ts +2 -2
- package/src/hooks/debug.ts +3 -3
- package/src/hooks/useDebounce.ts +1 -1
- package/src/hooks/useEventListener.ts +1 -1
- package/src/hooks/useHotkey.ts +1 -1
- package/src/hooks/useLifecycle.ts +2 -2
- package/src/hooks/useNonce.ts +1 -1
- package/src/hooks/useResizeObserver.ts +2 -2
- package/src/main.tsx +1 -1
- package/src/plugins/core/RenderHTML.tsx +3 -3
- package/src/plugins/core/__test__/registerReactComponent.test.ts +1 -1
- package/src/plugins/core/registerReactComponent.tsx +4 -4
- package/src/plugins/core/rpc.ts +1 -1
- package/src/plugins/impl/DataTablePlugin.tsx +1 -1
- package/src/plugins/impl/FileBrowserPlugin.tsx +1 -1
- package/src/plugins/impl/FormPlugin.tsx +1 -1
- package/src/plugins/impl/__tests__/MatrixPlugin.test.tsx +1 -1
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +1 -1
- package/src/plugins/impl/anywidget/model.ts +1 -1
- package/src/plugins/impl/anywidget/types.ts +2 -2
- package/src/plugins/impl/anywidget/widget-binding.ts +1 -1
- package/src/plugins/impl/chat/ChatPlugin.tsx +1 -1
- package/src/plugins/impl/chat/chat-ui.tsx +1 -1
- package/src/plugins/impl/data-editor/glide-data-editor.tsx +1 -1
- package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +2 -2
- package/src/plugins/impl/data-explorer/components/query-form.tsx +1 -1
- package/src/plugins/impl/data-explorer/functions/function.ts +1 -1
- package/src/plugins/impl/data-explorer/queries/types.ts +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -1
- package/src/plugins/impl/data-frames/forms/renderers.tsx +1 -1
- package/src/plugins/impl/data-frames/utils/operators.ts +1 -1
- package/src/plugins/impl/matplotlib/MatplotlibPlugin.tsx +1 -1
- package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +1 -1
- package/src/plugins/impl/panel/PanelPlugin.tsx +2 -2
- package/src/plugins/impl/plotly/Plot.tsx +3 -3
- package/src/plugins/impl/vega/batched.ts +1 -1
- package/src/plugins/impl/vega/make-selectable.ts +1 -1
- package/src/plugins/impl/vega/types.ts +1 -1
- package/src/plugins/layout/DownloadPlugin.tsx +1 -1
- package/src/plugins/layout/LazyPlugin.tsx +1 -1
- package/src/plugins/layout/RoutesPlugin.tsx +1 -1
- package/src/plugins/layout/mermaid/mermaid.tsx +1 -1
- package/src/plugins/plugins.ts +1 -1
- package/src/stories/data-explorer.stories.tsx +1 -1
- package/src/stories/dataframe.stories.tsx +1 -1
- package/src/stories/editor.stories.tsx +1 -1
- package/src/stories/select.stories.tsx +1 -1
- package/src/stories/switchable-multi-select.stories.tsx +1 -1
- package/src/utils/Logger.ts +1 -1
- package/src/utils/__tests__/arrays.test.ts +1 -1
- package/src/utils/__tests__/blob.test.ts +1 -1
- package/src/utils/__tests__/dates.test.ts +1 -1
- package/src/utils/__tests__/errors.test.ts +1 -1
- package/src/utils/__tests__/objects.test.ts +3 -3
- package/src/utils/__tests__/waitForWs.test.ts +1 -1
- package/src/utils/arrays.ts +1 -1
- package/src/utils/assertNever.ts +1 -1
- package/src/utils/batch-requests.ts +2 -2
- package/src/utils/createReducer.ts +2 -2
- package/src/utils/id-tree.tsx +2 -2
- package/src/utils/idle.ts +1 -1
- package/src/utils/invariant.ts +1 -2
- package/src/utils/maps.ts +1 -1
- package/src/utils/math.ts +0 -1
- package/src/utils/multi-map.ts +1 -1
- package/src/utils/objects.ts +1 -1
- package/src/utils/once.ts +2 -2
- package/src/utils/staticImplements.ts +1 -1
- package/src/utils/storage/jotai.ts +1 -1
- package/src/utils/tracer.ts +2 -2
- package/dist/useLifecycle-DgDTfOLZ.js +0 -173
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
+
import { t as require_react } from "./react-Bs6Z0kvn.js";
|
|
3
|
+
import { t as require_compiler_runtime } from "./compiler-runtime-B_OLMU9S.js";
|
|
4
|
+
import { l as createLucideIcon } from "./dist-D_UjpfOY.js";
|
|
5
|
+
import { g as Logger, r as cva, y as cn } from "./button-DNlNlZY_.js";
|
|
6
|
+
import { t as require_jsx_runtime } from "./jsx-runtime-9hcJiI23.js";
|
|
7
|
+
import { _ as useSetAtom, y as atom } from "./useTheme-MWfxn4oz.js";
|
|
8
|
+
var Calendar = createLucideIcon("calendar", [
|
|
9
|
+
["path", {
|
|
10
|
+
d: "M8 2v4",
|
|
11
|
+
key: "1cmpym"
|
|
12
|
+
}],
|
|
13
|
+
["path", {
|
|
14
|
+
d: "M16 2v4",
|
|
15
|
+
key: "4m81vk"
|
|
16
|
+
}],
|
|
17
|
+
["rect", {
|
|
18
|
+
width: "18",
|
|
19
|
+
height: "18",
|
|
20
|
+
x: "3",
|
|
21
|
+
y: "4",
|
|
22
|
+
rx: "2",
|
|
23
|
+
key: "1hopcy"
|
|
24
|
+
}],
|
|
25
|
+
["path", {
|
|
26
|
+
d: "M3 10h18",
|
|
27
|
+
key: "8toen8"
|
|
28
|
+
}]
|
|
29
|
+
]), Hash = createLucideIcon("hash", [
|
|
30
|
+
["line", {
|
|
31
|
+
x1: "4",
|
|
32
|
+
x2: "20",
|
|
33
|
+
y1: "9",
|
|
34
|
+
y2: "9",
|
|
35
|
+
key: "4lhtct"
|
|
36
|
+
}],
|
|
37
|
+
["line", {
|
|
38
|
+
x1: "4",
|
|
39
|
+
x2: "20",
|
|
40
|
+
y1: "15",
|
|
41
|
+
y2: "15",
|
|
42
|
+
key: "vyu0kd"
|
|
43
|
+
}],
|
|
44
|
+
["line", {
|
|
45
|
+
x1: "10",
|
|
46
|
+
x2: "8",
|
|
47
|
+
y1: "3",
|
|
48
|
+
y2: "21",
|
|
49
|
+
key: "1ggp8o"
|
|
50
|
+
}],
|
|
51
|
+
["line", {
|
|
52
|
+
x1: "16",
|
|
53
|
+
x2: "14",
|
|
54
|
+
y1: "3",
|
|
55
|
+
y2: "21",
|
|
56
|
+
key: "weycgp"
|
|
57
|
+
}]
|
|
58
|
+
]), ToggleLeft = createLucideIcon("toggle-left", [["circle", {
|
|
59
|
+
cx: "9",
|
|
60
|
+
cy: "12",
|
|
61
|
+
r: "3",
|
|
62
|
+
key: "u3jwor"
|
|
63
|
+
}], ["rect", {
|
|
64
|
+
width: "20",
|
|
65
|
+
height: "14",
|
|
66
|
+
x: "2",
|
|
67
|
+
y: "5",
|
|
68
|
+
rx: "7",
|
|
69
|
+
key: "g7kal2"
|
|
70
|
+
}]]), Type = createLucideIcon("type", [
|
|
71
|
+
["path", {
|
|
72
|
+
d: "M12 4v16",
|
|
73
|
+
key: "1654pz"
|
|
74
|
+
}],
|
|
75
|
+
["path", {
|
|
76
|
+
d: "M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2",
|
|
77
|
+
key: "e0r10z"
|
|
78
|
+
}],
|
|
79
|
+
["path", {
|
|
80
|
+
d: "M9 20h6",
|
|
81
|
+
key: "s66wpe"
|
|
82
|
+
}]
|
|
83
|
+
]), import_compiler_runtime$2 = require_compiler_runtime();
|
|
84
|
+
function createReducer(e, m) {
|
|
85
|
+
return {
|
|
86
|
+
reducer: (h, g) => (h || (h = e()), g.type in m ? m[g.type](h, g.payload) : (Logger.error(`Action type ${g.type} is not defined in reducers.`), h)),
|
|
87
|
+
createActions: (e2) => {
|
|
88
|
+
let h = {};
|
|
89
|
+
for (let g in m) h[g] = (m2) => {
|
|
90
|
+
e2({
|
|
91
|
+
type: g,
|
|
92
|
+
payload: m2
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
return h;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function createReducerAndAtoms(e, m, h) {
|
|
100
|
+
let g = [...h ?? []], v = (e2) => {
|
|
101
|
+
g.push(e2);
|
|
102
|
+
}, { reducer: y, createActions: b } = createReducer(e, m), x = (e2, m2) => {
|
|
103
|
+
try {
|
|
104
|
+
let h2 = y(e2, m2);
|
|
105
|
+
for (let v2 of g) try {
|
|
106
|
+
v2(e2, h2, m2);
|
|
107
|
+
} catch (e3) {
|
|
108
|
+
Logger.error(`Error in middleware for action ${m2.type}:`, e3);
|
|
109
|
+
}
|
|
110
|
+
return h2;
|
|
111
|
+
} catch (h2) {
|
|
112
|
+
return Logger.error(`Error in reducer for action ${m2.type}:`, h2), e2;
|
|
113
|
+
}
|
|
114
|
+
}, S = atom(e()), C = /* @__PURE__ */ new WeakMap();
|
|
115
|
+
function w(e2) {
|
|
116
|
+
let m2 = (0, import_compiler_runtime$2.c)(4), h2 = e2 === void 0 ? {} : e2, g2 = useSetAtom(S);
|
|
117
|
+
if (h2.skipMiddleware === true) {
|
|
118
|
+
let e3;
|
|
119
|
+
return m2[0] === g2 ? e3 = m2[1] : (e3 = b((e4) => {
|
|
120
|
+
g2((m3) => y(m3, e4));
|
|
121
|
+
}), m2[0] = g2, m2[1] = e3), e3;
|
|
122
|
+
}
|
|
123
|
+
C.has(g2) || C.set(g2, b((e3) => {
|
|
124
|
+
g2((m3) => x(m3, e3));
|
|
125
|
+
}));
|
|
126
|
+
let _;
|
|
127
|
+
return m2[2] === g2 ? _ = m2[3] : (_ = C.get(g2), m2[2] = g2, m2[3] = _), _;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
reducer: x,
|
|
131
|
+
addMiddleware: v,
|
|
132
|
+
createActions: b,
|
|
133
|
+
valueAtom: S,
|
|
134
|
+
useActions: w
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
var import_compiler_runtime$1 = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1), import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime(), 1), badgeVariants = cva("inline-flex items-center border rounded-full px-2 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
138
|
+
variants: { variant: {
|
|
139
|
+
default: "bg-primary hover:bg-primary/60 border-transparent text-primary-foreground",
|
|
140
|
+
defaultOutline: "bg-(--blue-2) border-(--blue-8) text-(--blue-11)",
|
|
141
|
+
secondary: "bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground",
|
|
142
|
+
destructive: "bg-(--red-2) border-(--red-6) text-(--red-9) hover:bg-(--red-3)",
|
|
143
|
+
success: "bg-(--grass-2) border-(--grass-5) text-(--grass-9) hover:bg-(--grass-3)",
|
|
144
|
+
outline: "text-foreground"
|
|
145
|
+
} },
|
|
146
|
+
defaultVariants: { variant: "default" }
|
|
147
|
+
}), Badge = (e) => {
|
|
148
|
+
let m = (0, import_compiler_runtime$1.c)(10), h, g, _;
|
|
149
|
+
m[0] === e ? (h = m[1], g = m[2], _ = m[3]) : ({ className: h, variant: _, ...g } = e, m[0] = e, m[1] = h, m[2] = g, m[3] = _);
|
|
150
|
+
let v;
|
|
151
|
+
m[4] !== h || m[5] !== _ ? (v = cn(badgeVariants({ variant: _ }), h), m[4] = h, m[5] = _, m[6] = v) : v = m[6];
|
|
152
|
+
let b;
|
|
153
|
+
return m[7] !== g || m[8] !== v ? (b = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
154
|
+
className: v,
|
|
155
|
+
...g
|
|
156
|
+
}), m[7] = g, m[8] = v, m[9] = b) : b = m[9], b;
|
|
157
|
+
}, import_compiler_runtime = require_compiler_runtime();
|
|
158
|
+
function useOnMount(e) {
|
|
159
|
+
let m = (0, import_compiler_runtime.c)(1), h;
|
|
160
|
+
m[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (h = [], m[0] = h) : h = m[0], (0, import_react.useEffect)(e, h);
|
|
161
|
+
}
|
|
162
|
+
function useOnUnmount(e) {
|
|
163
|
+
let m = (0, import_compiler_runtime.c)(3), h;
|
|
164
|
+
m[0] === e ? h = m[1] : (h = () => e(), m[0] = e, m[1] = h);
|
|
165
|
+
let g;
|
|
166
|
+
m[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (g = [], m[2] = g) : g = m[2], (0, import_react.useEffect)(h, g);
|
|
167
|
+
}
|
|
168
|
+
export {
|
|
169
|
+
Type as a,
|
|
170
|
+
Calendar as c,
|
|
171
|
+
createReducerAndAtoms as i,
|
|
172
|
+
useOnUnmount as n,
|
|
173
|
+
ToggleLeft as o,
|
|
174
|
+
Badge as r,
|
|
175
|
+
Hash as s,
|
|
176
|
+
useOnMount as t
|
|
177
|
+
};
|
package/package.json
CHANGED
package/src/__mocks__/common.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
|
|
2
|
+
/* oxlint-disable no-console -- for debugging */
|
|
3
3
|
import { type Mock, vi } from "vitest";
|
|
4
4
|
import { invariant } from "@/utils/invariant";
|
|
5
5
|
|
|
@@ -137,12 +137,12 @@ export const SetupMocks = {
|
|
|
137
137
|
store[key] = value;
|
|
138
138
|
}),
|
|
139
139
|
removeItem: vi.fn((key: string) => {
|
|
140
|
-
//
|
|
140
|
+
// oxlint-disable-next-line typescript/no-dynamic-delete
|
|
141
141
|
delete store[key];
|
|
142
142
|
}),
|
|
143
143
|
clear: vi.fn(() => {
|
|
144
144
|
for (const key of Object.keys(store)) {
|
|
145
|
-
//
|
|
145
|
+
// oxlint-disable-next-line typescript/no-dynamic-delete
|
|
146
146
|
delete store[key];
|
|
147
147
|
}
|
|
148
148
|
}),
|
|
@@ -179,7 +179,7 @@ export const SetupMocks = {
|
|
|
179
179
|
},
|
|
180
180
|
};
|
|
181
181
|
|
|
182
|
-
//
|
|
182
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
183
183
|
export function asMock<T extends (...args: any[]) => unknown>(fn: T): Mock<T> {
|
|
184
184
|
invariant(
|
|
185
185
|
"mock" in fn,
|
|
@@ -763,7 +763,7 @@ const AgentPanel: React.FC = () => {
|
|
|
763
763
|
// We don't want to disconnect so users can switch between different
|
|
764
764
|
// panels without losing their session
|
|
765
765
|
};
|
|
766
|
-
//
|
|
766
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
767
767
|
}, [wsUrl]);
|
|
768
768
|
|
|
769
769
|
const handleNewSession = useEvent(async () => {
|
|
@@ -889,7 +889,7 @@ const AgentPanel: React.FC = () => {
|
|
|
889
889
|
};
|
|
890
890
|
|
|
891
891
|
createOrResumeSession();
|
|
892
|
-
//
|
|
892
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
893
893
|
}, [isConnected, agent, tabLastActiveSessionId, activeSessionId]);
|
|
894
894
|
|
|
895
895
|
// Handler for prompt submission
|
|
@@ -230,7 +230,7 @@ describe("generateColumns", () => {
|
|
|
230
230
|
});
|
|
231
231
|
|
|
232
232
|
// "age" is a number column — should auto right-align
|
|
233
|
-
//
|
|
233
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
234
234
|
const cell = (columns[1].cell as any)({
|
|
235
235
|
column: {
|
|
236
236
|
columnDef: columns[1],
|
|
@@ -241,7 +241,7 @@ describe("generateColumns", () => {
|
|
|
241
241
|
expect(cell?.props.className).toContain("text-right");
|
|
242
242
|
|
|
243
243
|
// "name" is a string column — should remain left-aligned
|
|
244
|
-
//
|
|
244
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
245
245
|
const nameCell = (columns[0].cell as any)({
|
|
246
246
|
column: {
|
|
247
247
|
columnDef: columns[0],
|
|
@@ -261,7 +261,7 @@ describe("generateColumns", () => {
|
|
|
261
261
|
});
|
|
262
262
|
|
|
263
263
|
// "age" is numeric but explicitly set to left
|
|
264
|
-
//
|
|
264
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
265
265
|
const cell = (columns[1].cell as any)({
|
|
266
266
|
column: {
|
|
267
267
|
columnDef: columns[1],
|
|
@@ -301,7 +301,7 @@ describe("generateColumns", () => {
|
|
|
301
301
|
});
|
|
302
302
|
|
|
303
303
|
// Assuming getCellStyleClass is a function that returns a class name
|
|
304
|
-
//
|
|
304
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
305
305
|
const cell = (columns[0].cell as any)({
|
|
306
306
|
column: {
|
|
307
307
|
columnDef: columns[0],
|
|
@@ -333,7 +333,7 @@ describe("generateColumns", () => {
|
|
|
333
333
|
// Right-justified: parent wrapper should have items-end, sort/filter icons should flip to the left
|
|
334
334
|
const { container: rightContainer } = render(
|
|
335
335
|
<TooltipProvider>
|
|
336
|
-
{/*
|
|
336
|
+
{/* oxlint-disable-next-line typescript/no-explicit-any */}
|
|
337
337
|
{(columns[0].header as any)({ column: mockColumn(columns[0]) })}
|
|
338
338
|
</TooltipProvider>,
|
|
339
339
|
);
|
|
@@ -347,7 +347,7 @@ describe("generateColumns", () => {
|
|
|
347
347
|
// Center-justified: parent wrapper should have items-center, no flex-row-reverse
|
|
348
348
|
const { container: centerContainer } = render(
|
|
349
349
|
<TooltipProvider>
|
|
350
|
-
{/*
|
|
350
|
+
{/* oxlint-disable-next-line typescript/no-explicit-any */}
|
|
351
351
|
{(columns[1].header as any)({ column: mockColumn(columns[1]) })}
|
|
352
352
|
</TooltipProvider>,
|
|
353
353
|
);
|
|
@@ -572,7 +572,7 @@ describe("LocaleNumber", () => {
|
|
|
572
572
|
<LocaleNumber value={1_234_567.89} />
|
|
573
573
|
</I18nProvider>,
|
|
574
574
|
);
|
|
575
|
-
//
|
|
575
|
+
// oxlint-disable-next-line no-irregular-whitespace
|
|
576
576
|
expect(container.textContent).toMatchInlineSnapshot(`"1 234 567,89"`);
|
|
577
577
|
});
|
|
578
578
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
/*
|
|
2
|
+
/* oxlint-disable typescript/no-explicit-any */
|
|
3
3
|
|
|
4
4
|
import type { Cell, Column, Row, Table } from "@tanstack/react-table";
|
|
5
5
|
import { describe, expect, it, vi } from "vitest";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
/*
|
|
2
|
+
/* oxlint-disable typescript/no-empty-object-type */
|
|
3
3
|
import type { OnChangeFn, RowData, Updater } from "@tanstack/react-table";
|
|
4
4
|
|
|
5
5
|
export interface CellSelectionItem {
|
|
@@ -78,7 +78,7 @@ export function generateAltairChart(
|
|
|
78
78
|
|
|
79
79
|
if (encodings?.tooltip) {
|
|
80
80
|
const tooltip = encodings.tooltip;
|
|
81
|
-
//
|
|
81
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
82
82
|
const makeTooltip = (t: Record<string, any>) => {
|
|
83
83
|
const kwargs = makeKwargs(t);
|
|
84
84
|
return new FunctionCall("alt.Tooltip", kwargs);
|
|
@@ -149,7 +149,7 @@ ${variableName}
|
|
|
149
149
|
`.trim();
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
//
|
|
152
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
153
153
|
function makeKwargs<T extends Record<string, any>>(obj: T) {
|
|
154
154
|
const result: Record<string, PythonCode> = {};
|
|
155
155
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
/*
|
|
2
|
+
/* oxlint-disable typescript/no-empty-object-type */
|
|
3
3
|
|
|
4
4
|
import type { OnChangeFn, RowData } from "@tanstack/react-table";
|
|
5
5
|
import type { DataType } from "@/core/kernel/messages";
|
|
@@ -38,7 +38,7 @@ export interface ColumnFormattingInstance {
|
|
|
38
38
|
setColumnFormatting: (value?: FormatOption) => void;
|
|
39
39
|
getColumnFormatting?: () => FormatOption | undefined;
|
|
40
40
|
getCanFormat?: () => boolean;
|
|
41
|
-
//
|
|
41
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
42
42
|
applyColumnFormatting: (value: any) => any;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -282,7 +282,7 @@ export function getDataSpecAndSourceName<T>(data: string | T[]): {
|
|
|
282
282
|
const base64 = extractBase64FromDataURL(data);
|
|
283
283
|
const decoded = window.atob(base64);
|
|
284
284
|
|
|
285
|
-
//
|
|
285
|
+
// oxlint-disable-next-line unicorn/prefer-ternary
|
|
286
286
|
if (decoded.startsWith(ARROW_MAGIC_NUMBER)) {
|
|
287
287
|
dataSpec = {
|
|
288
288
|
values: base64ToUint8Array(base64),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
/*
|
|
2
|
+
/* oxlint-disable typescript/no-empty-object-type */
|
|
3
3
|
import type { OnChangeFn, RowData } from "@tanstack/react-table";
|
|
4
4
|
|
|
5
5
|
export type ColumnWrappingState = Record<string, "nowrap" | "wrap" | undefined>;
|
|
@@ -43,7 +43,7 @@ export const LoadingTable = ({
|
|
|
43
43
|
<TableBody>
|
|
44
44
|
{Array.from({ length: pageSize }).map((_, i) => (
|
|
45
45
|
<TableRow key={i}>
|
|
46
|
-
{Array.from({ length: NUM_COLUMNS }).map((
|
|
46
|
+
{Array.from({ length: NUM_COLUMNS }).map((__, j) => (
|
|
47
47
|
<TableCell key={j}>
|
|
48
48
|
<div className="h-4 bg-(--slate-5) animate-pulse rounded-md w-[90%]" />
|
|
49
49
|
</TableCell>
|
|
@@ -10,7 +10,7 @@ vi.mock("@/utils/copy", () => ({
|
|
|
10
10
|
}));
|
|
11
11
|
|
|
12
12
|
vi.mock("../utils", async (importOriginal) => {
|
|
13
|
-
//
|
|
13
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
14
14
|
const original = (await importOriginal()) as any;
|
|
15
15
|
return {
|
|
16
16
|
...original,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from "../atoms";
|
|
29
29
|
import { getCellsBetween, getCellValues } from "../utils";
|
|
30
30
|
|
|
31
|
-
//
|
|
31
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
32
32
|
type T = any;
|
|
33
33
|
|
|
34
34
|
// Create mock table and cells
|
|
@@ -32,9 +32,9 @@ function initialState(): CellSelectionState {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
36
36
|
type AnyTable = Table<any>;
|
|
37
|
-
//
|
|
37
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
38
38
|
type AnyCell = Cell<any, unknown>;
|
|
39
39
|
|
|
40
40
|
const {
|
|
@@ -51,7 +51,7 @@ export const DependencyGraphTree: React.FC<PropsWithChildren<Props>> = ({
|
|
|
51
51
|
layoutDirection,
|
|
52
52
|
settings,
|
|
53
53
|
}) => {
|
|
54
|
-
//
|
|
54
|
+
// oxlint-disable-next-line react/hook-use-state
|
|
55
55
|
const [initial] = useState(() => {
|
|
56
56
|
let elements = elementsBuilder.createElements(
|
|
57
57
|
cellIds,
|
|
@@ -176,7 +176,7 @@ describe("DynamicFavicon", () => {
|
|
|
176
176
|
const { rerender } = render(<DynamicFavicon isRunning={true} />);
|
|
177
177
|
rerender(<DynamicFavicon isRunning={false} />);
|
|
178
178
|
|
|
179
|
-
//
|
|
179
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
180
180
|
expect(Notification.requestPermission).toHaveBeenCalled();
|
|
181
181
|
});
|
|
182
182
|
});
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { useAtomValue } from "jotai";
|
|
4
|
+
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
5
|
+
import React, { useState } from "react";
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import {
|
|
8
|
+
DialogContent,
|
|
9
|
+
DialogDescription,
|
|
10
|
+
DialogFooter,
|
|
11
|
+
DialogHeader,
|
|
12
|
+
DialogTitle,
|
|
13
|
+
} from "@/components/ui/dialog";
|
|
14
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
15
|
+
import { runtimeConfigAtom } from "@/core/runtime/config";
|
|
16
|
+
import { copyToClipboard } from "@/utils/copy";
|
|
17
|
+
import { Events } from "@/utils/events";
|
|
18
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
19
|
+
import type { RuntimeConfig } from "@/core/runtime/types";
|
|
20
|
+
|
|
21
|
+
type AgentTab = "claude" | "codex" | "opencode";
|
|
22
|
+
|
|
23
|
+
function buildRemoteUrl(config: RuntimeConfig) {
|
|
24
|
+
const url = new URL(config.url);
|
|
25
|
+
if (config.authToken) {
|
|
26
|
+
url.searchParams.set("auth", config.authToken);
|
|
27
|
+
}
|
|
28
|
+
return url.toString();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getPromptCommand(agent: AgentTab, remoteUrl: string): string {
|
|
32
|
+
const command = import.meta.env.DEV ? "uv run marimo" : "uvx marimo@latest";
|
|
33
|
+
const base = `${command} pair prompt --url '${remoteUrl}'`;
|
|
34
|
+
switch (agent) {
|
|
35
|
+
case "claude":
|
|
36
|
+
return `claude "$(${base} --claude)"`;
|
|
37
|
+
case "codex":
|
|
38
|
+
return `codex "$(${base} --codex)"`;
|
|
39
|
+
case "opencode":
|
|
40
|
+
return `opencode "$(${base} --opencode)"`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SKILL_INSTALL = "npx skills add marimo-team/marimo-pair";
|
|
45
|
+
|
|
46
|
+
export const PairWithAgentModal: React.FC<{
|
|
47
|
+
onClose: () => void;
|
|
48
|
+
}> = ({ onClose }) => {
|
|
49
|
+
const [activeTab, setActiveTab] = useState<AgentTab>("claude");
|
|
50
|
+
const runtimeConfig = useAtomValue(runtimeConfigAtom);
|
|
51
|
+
const remoteUrl = buildRemoteUrl(runtimeConfig);
|
|
52
|
+
const promptCommand = getPromptCommand(activeTab, remoteUrl);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<DialogContent className="sm:max-w-lg">
|
|
56
|
+
<DialogHeader>
|
|
57
|
+
<DialogTitle>Pair with an agent</DialogTitle>
|
|
58
|
+
<DialogDescription>
|
|
59
|
+
Use an AI coding agent to pair-program on this notebook.{" "}
|
|
60
|
+
<a
|
|
61
|
+
href="https://links.marimo.app/marimo-pair"
|
|
62
|
+
target="_blank"
|
|
63
|
+
rel="noopener noreferrer"
|
|
64
|
+
className="underline"
|
|
65
|
+
>
|
|
66
|
+
Learn more
|
|
67
|
+
</a>
|
|
68
|
+
.
|
|
69
|
+
</DialogDescription>
|
|
70
|
+
</DialogHeader>
|
|
71
|
+
|
|
72
|
+
<div className="flex flex-col gap-4 py-2">
|
|
73
|
+
<div className="flex flex-col gap-2">
|
|
74
|
+
<span className="text-sm font-medium">1. Install the skill</span>
|
|
75
|
+
<CommandBlock command={SKILL_INSTALL} />
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div className="flex flex-col gap-2">
|
|
79
|
+
<span className="text-sm font-medium">2. Run in your terminal</span>
|
|
80
|
+
<Tabs
|
|
81
|
+
value={activeTab}
|
|
82
|
+
onValueChange={(v) => setActiveTab(v as AgentTab)}
|
|
83
|
+
>
|
|
84
|
+
<TabsList className="w-full">
|
|
85
|
+
<TabsTrigger value="claude" className="flex-1">
|
|
86
|
+
Claude
|
|
87
|
+
</TabsTrigger>
|
|
88
|
+
<TabsTrigger value="codex" className="flex-1">
|
|
89
|
+
Codex
|
|
90
|
+
</TabsTrigger>
|
|
91
|
+
<TabsTrigger value="opencode" className="flex-1">
|
|
92
|
+
OpenCode
|
|
93
|
+
</TabsTrigger>
|
|
94
|
+
</TabsList>
|
|
95
|
+
|
|
96
|
+
<TabsContent value="claude" className="mt-3">
|
|
97
|
+
<CommandBlock command={promptCommand} />
|
|
98
|
+
</TabsContent>
|
|
99
|
+
<TabsContent value="codex" className="mt-3">
|
|
100
|
+
<CommandBlock command={promptCommand} />
|
|
101
|
+
</TabsContent>
|
|
102
|
+
<TabsContent value="opencode" className="mt-3">
|
|
103
|
+
<CommandBlock command={promptCommand} />
|
|
104
|
+
</TabsContent>
|
|
105
|
+
</Tabs>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<DialogFooter>
|
|
110
|
+
<Button variant="secondary" onClick={onClose}>
|
|
111
|
+
Close
|
|
112
|
+
</Button>
|
|
113
|
+
</DialogFooter>
|
|
114
|
+
</DialogContent>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const CommandBlock: React.FC<{ command: string }> = ({ command }) => {
|
|
119
|
+
const [copied, setCopied] = useState(false);
|
|
120
|
+
|
|
121
|
+
const copy = Events.stopPropagation(async (e) => {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
await copyToClipboard(command);
|
|
124
|
+
setCopied(true);
|
|
125
|
+
setTimeout(() => setCopied(false), 2000);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<div className="flex items-center gap-2 rounded-md bg-muted px-3 py-2 font-mono text-xs">
|
|
130
|
+
<code className="flex-1 select-all break-words">{command}</code>
|
|
131
|
+
<Tooltip content="Copied!" open={copied}>
|
|
132
|
+
<Button onClick={copy} size="xs" variant="ghost">
|
|
133
|
+
{copied ? (
|
|
134
|
+
<CheckIcon size={14} strokeWidth={1.5} />
|
|
135
|
+
) : (
|
|
136
|
+
<CopyIcon size={14} strokeWidth={1.5} />
|
|
137
|
+
)}
|
|
138
|
+
</Button>
|
|
139
|
+
</Tooltip>
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
};
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
PresentationIcon,
|
|
37
37
|
SettingsIcon,
|
|
38
38
|
Share2Icon,
|
|
39
|
+
SparklesIcon,
|
|
39
40
|
Undo2Icon,
|
|
40
41
|
XCircleIcon,
|
|
41
42
|
YoutubeIcon,
|
|
@@ -45,6 +46,7 @@ import { settingDialogAtom } from "@/components/app-config/state";
|
|
|
45
46
|
import { MarkdownIcon } from "@/components/editor/cell/code/icons";
|
|
46
47
|
import { useImperativeModal } from "@/components/modal/ImperativeModal";
|
|
47
48
|
import { renderShortcut } from "@/components/shortcuts/renderShortcut";
|
|
49
|
+
import { PairWithAgentModal } from "@/components/editor/actions/pair-with-agent-modal";
|
|
48
50
|
import { ShareStaticNotebookModal } from "@/components/static-html/share-modal";
|
|
49
51
|
import { toast } from "@/components/ui/use-toast";
|
|
50
52
|
import {
|
|
@@ -343,6 +345,14 @@ export function useNotebookActions() {
|
|
|
343
345
|
],
|
|
344
346
|
},
|
|
345
347
|
|
|
348
|
+
{
|
|
349
|
+
icon: <SparklesIcon size={14} strokeWidth={1.5} />,
|
|
350
|
+
label: "Pair with an agent",
|
|
351
|
+
handle: async () => {
|
|
352
|
+
openModal(<PairWithAgentModal onClose={closeModal} />);
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
|
|
346
356
|
{
|
|
347
357
|
icon: <Share2Icon size={14} strokeWidth={1.5} />,
|
|
348
358
|
label: "Share",
|
|
@@ -156,7 +156,7 @@ export const AiCompletionEditor: React.FC<Props> = ({
|
|
|
156
156
|
// Use complete to pass the prompt directly, else input might be empty
|
|
157
157
|
complete(initialPrompt);
|
|
158
158
|
}
|
|
159
|
-
//
|
|
159
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
160
160
|
}, [triggerImmediately]);
|
|
161
161
|
|
|
162
162
|
// Focus the input
|
|
@@ -31,7 +31,7 @@ export const AppContainer: React.FC<PropsWithChildren<Props>> = ({
|
|
|
31
31
|
<StatusOverlay connection={connection} isRunning={isRunning} />
|
|
32
32
|
<PyodideLoader>
|
|
33
33
|
<WrappedWithSidebar>
|
|
34
|
-
{/**
|
|
34
|
+
{/** oxlint-ignore-next-line -- ID is used by other components to grab the DOM element */}
|
|
35
35
|
<div
|
|
36
36
|
id="App"
|
|
37
37
|
data-config-width={width}
|