@marimo-team/islands 0.25.3-dev222 → 0.25.3-dev224

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/{ErrorBoundary-Cg9q4kUW.js → ErrorBoundary-Ba6GHuhB.js} +1 -1
  2. package/dist/{code-visibility-Dp-DkL1e.js → code-visibility-BXNYYFb5.js} +1 -1
  3. package/dist/{common-DHr2MXY3.js → common-BHSOMSDG.js} +1 -1
  4. package/dist/{data-grid-overlay-editor-B-OJHxuO.js → data-grid-overlay-editor-CGLPw73V.js} +1 -1
  5. package/dist/{feedback-button-DGAcA9xH.js → feedback-button-BUf6rqKQ.js} +2 -2
  6. package/dist/{glide-data-editor-09FJOvJw.js → glide-data-editor-Dm3DXKHl.js} +3 -3
  7. package/dist/{globals-2eTRp9qC.js → globals-DjSaXJeh.js} +1 -1
  8. package/dist/main.js +4179 -4062
  9. package/dist/{number-overlay-editor-XJ1jA8Jv.js → number-overlay-editor-BVAnAmYf.js} +1 -1
  10. package/dist/{reveal-component-DxdLWQiq.js → reveal-component-Cfoa8xAb.js} +2 -2
  11. package/dist/style.css +1 -1
  12. package/package.json +1 -1
  13. package/src/components/app-config/ai-config.tsx +148 -147
  14. package/src/components/app-config/app-config-button.tsx +6 -5
  15. package/src/components/app-config/common.tsx +7 -9
  16. package/src/components/app-config/data-form.tsx +112 -113
  17. package/src/components/app-config/mcp-config.tsx +30 -53
  18. package/src/components/app-config/user-config-form.css +91 -0
  19. package/src/components/app-config/user-config-form.tsx +236 -298
  20. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +9 -5
  21. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +3 -3
  22. package/src/components/editor/actions/pair-with-agent-modal.tsx +5 -5
  23. package/src/components/editor/actions/pair-with-agent.tsx +10 -7
  24. package/src/core/notebook/replica/__tests__/executions.test.ts +201 -0
  25. package/src/core/notebook/replica/__tests__/replica.test.ts +6 -0
  26. package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
  27. package/src/core/notebook/replica/index.ts +7 -0
  28. package/src/core/notebook/replica/replica.ts +34 -2
  29. package/src/core/notebook/replica/resources/executions.ts +157 -0
  30. package/src/core/notebook/replica/resources/results.ts +48 -0
@@ -0,0 +1,157 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type * as Protocol from "@marimo-team/client/protocol";
4
+ import type { NotebookResource } from "@marimo-team/client";
5
+
6
+ /** A console line, display, or input an execution produced, tagged by kind. */
7
+ export type Item =
8
+ | (Protocol.Console & { readonly kind: "console" })
9
+ | (Protocol.Display & { readonly kind: "display" })
10
+ | (Protocol.Input & { readonly kind: "input" });
11
+
12
+ /** An execution on the stream, with the items and variables it has produced. */
13
+ export interface Execution {
14
+ readonly record: Protocol.Execution;
15
+ /** Items by id. `itemsInOrder` sorts them by `seq`. */
16
+ readonly items: ReadonlyMap<Protocol.ItemId, Item>;
17
+ /** The variables the execution bound, by item id. */
18
+ readonly variables: ReadonlyMap<Protocol.ItemId, Protocol.Variable>;
19
+ }
20
+
21
+ /**
22
+ * Runs and executions as the stream reports them.
23
+ *
24
+ * Nothing outlives its removal. The host removes a cell's previous
25
+ * execution before it publishes the next one, so `results` keeps each
26
+ * cell's last completed record for display.
27
+ */
28
+ export interface Executions {
29
+ readonly runs: ReadonlyMap<Protocol.RunId, Protocol.Run>;
30
+ /** Every execution on the stream, scratch included. */
31
+ readonly executions: ReadonlyMap<Protocol.ExecutionId, Execution>;
32
+ /** The execution on the stream for each cell that has one. */
33
+ readonly latest: ReadonlyMap<Protocol.CellId, Protocol.ExecutionId>;
34
+ }
35
+
36
+ type Kind = "run" | "execution" | "console" | "display" | "input" | "variable";
37
+
38
+ /** An execution's items in the order they were produced. */
39
+ export function itemsInOrder(execution: Pick<Execution, "items">): Item[] {
40
+ return [...execution.items.values()].toSorted((a, b) => a.seq - b.seq);
41
+ }
42
+
43
+ function without<K, V>(map: ReadonlyMap<K, V>, key: K): ReadonlyMap<K, V> {
44
+ if (!map.has(key)) {
45
+ return map;
46
+ }
47
+ const next = new Map(map);
48
+ next.delete(key);
49
+ return next;
50
+ }
51
+
52
+ /** Replace an execution on the stream, indexed under its cell. */
53
+ function set(state: Executions, execution: Execution): Executions {
54
+ const { id, cell_id: cellId } = execution.record;
55
+ return {
56
+ ...state,
57
+ executions: new Map(state.executions).set(id, execution),
58
+ latest:
59
+ cellId === null || state.latest.get(cellId) === id
60
+ ? state.latest
61
+ : new Map(state.latest).set(cellId, id),
62
+ };
63
+ }
64
+
65
+ function remove(state: Executions, id: Protocol.ExecutionId): Executions {
66
+ const execution = state.executions.get(id);
67
+ if (execution === undefined) {
68
+ return state;
69
+ }
70
+ const cellId = execution.record.cell_id;
71
+ return {
72
+ ...state,
73
+ executions: without(state.executions, id),
74
+ latest:
75
+ cellId !== null && state.latest.get(cellId) === id
76
+ ? without(state.latest, cellId)
77
+ : state.latest,
78
+ };
79
+ }
80
+
81
+ function attach(state: Executions, item: Item): Executions {
82
+ const execution = state.executions.get(item.execution_id);
83
+ if (execution === undefined) {
84
+ return state;
85
+ }
86
+ return set(state, {
87
+ ...execution,
88
+ items: new Map(execution.items).set(item.id, item),
89
+ });
90
+ }
91
+
92
+ function detach(state: Executions, itemId: Protocol.ItemId): Executions {
93
+ for (const execution of state.executions.values()) {
94
+ if (execution.items.has(itemId)) {
95
+ return set(state, {
96
+ ...execution,
97
+ items: without(execution.items, itemId),
98
+ });
99
+ }
100
+ }
101
+ return state;
102
+ }
103
+
104
+ function bind(state: Executions, variable: Protocol.Variable): Executions {
105
+ const execution = state.executions.get(variable.execution_id);
106
+ if (execution === undefined) {
107
+ return state;
108
+ }
109
+ return set(state, {
110
+ ...execution,
111
+ variables: new Map(execution.variables).set(variable.id, variable),
112
+ });
113
+ }
114
+
115
+ function unbind(state: Executions, itemId: Protocol.ItemId): Executions {
116
+ for (const execution of state.executions.values()) {
117
+ if (execution.variables.has(itemId)) {
118
+ return set(state, {
119
+ ...execution,
120
+ variables: without(execution.variables, itemId),
121
+ });
122
+ }
123
+ }
124
+ return state;
125
+ }
126
+
127
+ export const executions: NotebookResource<Executions, Kind> = {
128
+ initial: { runs: new Map(), executions: new Map(), latest: new Map() },
129
+ on: {
130
+ run: (state, { data }) => ({
131
+ ...state,
132
+ runs: new Map(state.runs).set(data.run.id, data.run),
133
+ }),
134
+ "run.removed": (state, { data }) =>
135
+ state.runs.has(data.id)
136
+ ? { ...state, runs: without(state.runs, data.id) }
137
+ : state,
138
+ execution: (state, { data: { execution: record } }) => {
139
+ const previous = state.executions.get(record.id);
140
+ return set(state, {
141
+ record,
142
+ items: previous?.items ?? new Map(),
143
+ variables: previous?.variables ?? new Map(),
144
+ });
145
+ },
146
+ "execution.removed": (state, { data }) => remove(state, data.id),
147
+ console: (state, { data }) =>
148
+ attach(state, { ...data.console, kind: "console" }),
149
+ "console.removed": (state, { data }) => detach(state, data.id),
150
+ display: (state, { data }) =>
151
+ attach(state, { ...data.display, kind: "display" }),
152
+ "display.removed": (state, { data }) => detach(state, data.id),
153
+ input: (state, { data }) => attach(state, { ...data.input, kind: "input" }),
154
+ variable: (state, { data }) => bind(state, data.variable),
155
+ "variable.removed": (state, { data }) => unbind(state, data.id),
156
+ },
157
+ };
@@ -0,0 +1,48 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type * as Protocol from "@marimo-team/client/protocol";
4
+ import type { NotebookResource } from "@marimo-team/client";
5
+
6
+ /**
7
+ * Each document cell's last completed execution record.
8
+ *
9
+ * The host removes a cell's previous execution before it publishes the
10
+ * next one. A result stays until a newer execution for the cell completes
11
+ * or the cell leaves the document, so a cell can show its last outcome
12
+ * while it runs again. Only the record is kept. Its outcome carries the
13
+ * cell's output, while items and variables stay with the stream's copy of
14
+ * the execution.
15
+ *
16
+ * A cell has an entry from its `cell` event until its removal, null until
17
+ * it completes once. Cells precede their executions on the stream, so a
18
+ * completion for a cell without an entry belongs to a cell the document
19
+ * no longer has.
20
+ */
21
+ export type Results = ReadonlyMap<Protocol.CellId, Protocol.Execution | null>;
22
+
23
+ export const results: NotebookResource<Results, "cell" | "execution"> = {
24
+ initial: new Map(),
25
+ on: {
26
+ cell: (state, { data }) =>
27
+ state.has(data.cell.id) ? state : new Map(state).set(data.cell.id, null),
28
+ "cell.removed": (state, { data }) => {
29
+ if (!state.has(data.id)) {
30
+ return state;
31
+ }
32
+ const next = new Map(state);
33
+ next.delete(data.id);
34
+ return next;
35
+ },
36
+ execution: (state, { data: { execution } }) => {
37
+ const cellId = execution.cell_id;
38
+ if (
39
+ cellId === null ||
40
+ execution.status !== "completed" ||
41
+ !state.has(cellId)
42
+ ) {
43
+ return state;
44
+ }
45
+ return new Map(state).set(cellId, execution);
46
+ },
47
+ },
48
+ };