@marimo-team/islands 0.25.3-dev266 → 0.25.3-dev268

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 (184) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C_hj7Poi.js → ConnectedDataExplorerComponent-eLHPh6uu.js} +9 -9
  2. package/dist/{ErrorBoundary-CvxlC3F1.js → ErrorBoundary-CQYAoD7X.js} +64 -69
  3. package/dist/{abnfDiagram-VCTEODGH-DzrZZXRD.js → abnfDiagram-VCTEODGH-hqd0IBtX.js} +2 -2
  4. package/dist/{any-language-editor-CFeWfC3o.js → any-language-editor-DnG26QXh.js} +1 -1
  5. package/dist/{architectureDiagram-5GKGNRK7-iF_snyFL.js → architectureDiagram-5GKGNRK7-BzLAFcc0.js} +1 -1
  6. package/dist/{strings-BCKpLFNU.js → assertNever-DIU3JJbt.js} +14 -14
  7. package/dist/{chat-ui-DFxNgzXF.js → chat-ui-BAnLgpTe.js} +1964 -1740
  8. package/dist/{chunk-IMKFNOWR-B7xytD4B.js → chunk-IMKFNOWR-DOeVvuyE.js} +1 -1
  9. package/dist/{chunk-SHT3W25Y-I8ZFP5L1.js → chunk-SHT3W25Y-DZoFI8wR.js} +1 -1
  10. package/dist/{chunk-SVP7TREG-Di-uAPdT.js → chunk-SVP7TREG-CWu86PSW.js} +1 -1
  11. package/dist/{chunk-TICWLB2K-BFpUy0ud.js → chunk-TICWLB2K-BrM0GoP3.js} +1 -1
  12. package/dist/{classDiagram-ZZMXUADV-Cqm4JGpx.js → classDiagram-ZZMXUADV-DYi4V2bB.js} +2 -2
  13. package/dist/{classDiagram-v2-VYDZK3BY-DFHRJpN3.js → classDiagram-v2-VYDZK3BY-tN7FIk-m.js} +2 -2
  14. package/dist/{code-visibility-SRM1JiD_.js → code-visibility-DcZ_RwaH.js} +44 -47
  15. package/dist/{common-yiRhZ6ZZ.js → common-BGeQilvh.js} +5846 -5519
  16. package/dist/{config-CmeG_Pb6.js → config-BsPruWMR.js} +2 -2
  17. package/dist/{createReducer-C_syF8Td.js → createReducer-DdtT_7ji.js} +1 -1
  18. package/dist/{cynefinDiagram-5FMLGOSQ-cuGOeTBC.js → cynefinDiagram-5FMLGOSQ-D5nCnDc-.js} +1 -1
  19. package/dist/{dagre-GXQ25YYZ-DJ76aC4k.js → dagre-GXQ25YYZ-BHkd7f_i.js} +1 -1
  20. package/dist/{data-grid-overlay-editor-DLTzcQ4O.js → data-grid-overlay-editor-Dc4lW4A3.js} +1 -1
  21. package/dist/{diagram-S7CK7UJ4-DLLc0sw7.js → diagram-S7CK7UJ4-D1ALppT2.js} +1 -1
  22. package/dist/{diagram-UQ7AKVKN-Tz_d6qmk.js → diagram-UQ7AKVKN-DLv0b83L.js} +1 -1
  23. package/dist/{diagram-VX7I27RA-D7SzPrDN.js → diagram-VX7I27RA-7XJ7J6qg.js} +1 -1
  24. package/dist/{diagram-Z3DM3KII-qr37XV58.js → diagram-Z3DM3KII-7M7zbHp_.js} +1 -1
  25. package/dist/{dialog-BtprQCUw.js → dialog-DzCj1qQv.js} +1 -1
  26. package/dist/{dropdown-menu-CkJ7ErY6.js → dropdown-menu-CdXE15an.js} +1214 -1208
  27. package/dist/{ebnfDiagram-PWID7BFC-BKOQb4J0.js → ebnfDiagram-PWID7BFC-DHH1qlmV.js} +2 -2
  28. package/dist/{erDiagram-RLTQ6QDP-CM15Vq68.js → erDiagram-RLTQ6QDP-fI_0dGef.js} +1 -1
  29. package/dist/{error-banner-DbRFOd2O.js → error-banner-DPc9eIw5.js} +3 -3
  30. package/dist/{error-entries-CMoaUX9V.js → error-entries-CxN-Nq3V.js} +524 -456
  31. package/dist/{feedback-button-DBUrE4OL.js → feedback-button-BqaeQcvX.js} +77 -77
  32. package/dist/{flowDiagram-HODETNUW-Dt3N5yFT.js → flowDiagram-HODETNUW-Brg9MA6i.js} +2 -2
  33. package/dist/{formats-gGospKWJ.js → formats-DbSvAPY-.js} +1 -1
  34. package/dist/{glide-data-editor-Cfv4HeOh.js → glide-data-editor-CiijPXA7.js} +2042 -2041
  35. package/dist/{glide-utils-Ba9WD2IN.js → glide-utils-BSw3SSHF.js} +29 -35
  36. package/dist/{globals-dIbBIR5-.js → globals-CpmSWKI_.js} +2 -2
  37. package/dist/{html-to-image-D_5CMreP.js → html-to-image-8sywF4my.js} +5452 -5751
  38. package/dist/{infoDiagram-27XIBGKW-C7axJMCl.js → infoDiagram-27XIBGKW-E9e403YT.js} +1 -1
  39. package/dist/{ishikawaDiagram-5VMMS53U-CdC9Eur7.js → ishikawaDiagram-5VMMS53U-C-RlYDRo.js} +1 -1
  40. package/dist/{kanban-definition-UXKFOSKX-BHnMIgD7.js → kanban-definition-UXKFOSKX-CLFl_uqK.js} +1 -1
  41. package/dist/main.js +6294 -6324
  42. package/dist/{mermaid-DFYN_PXd.js → mermaid-rd09e1JL.js} +35 -35
  43. package/dist/{mindmap-definition-YA3MSWOX-BagHoCGU.js → mindmap-definition-YA3MSWOX-BQ8TWtyB.js} +1 -1
  44. package/dist/{number-overlay-editor-CTiJp5Mj.js → number-overlay-editor-Ft4NiAEN.js} +1 -1
  45. package/dist/{pegDiagram-XKGWAZYB-8IIZczip.js → pegDiagram-XKGWAZYB-CN8UHFPi.js} +2 -2
  46. package/dist/pencil-DcT8AE0h.js +10 -0
  47. package/dist/{pieDiagram-E7YTZNPT-CE6dKBIr.js → pieDiagram-E7YTZNPT-DGuJ0EBd.js} +1 -1
  48. package/dist/{process-output-CGFNVC60.js → process-output-Dku5POvm.js} +3 -3
  49. package/dist/{railroadDiagram-O6MQD6OU-CkexPq3b.js → railroadDiagram-O6MQD6OU-BPDA8wy8.js} +2 -2
  50. package/dist/{requirementDiagram-BXWQKSXE-B0-OkuAe.js → requirementDiagram-BXWQKSXE-ChzLGbGW.js} +1 -1
  51. package/dist/{reveal-component-DH09ygHo.js → reveal-component-D0cfwbbl.js} +1094 -1094
  52. package/dist/{select-C33FVPPN.js → select-OxgozOC8.js} +1 -1
  53. package/dist/{sequenceDiagram-WJ2MYXX4-Dxysg8DX.js → sequenceDiagram-WJ2MYXX4-DFX-bE6O.js} +1 -1
  54. package/dist/{spec-DH1lmF7Q.js → spec-oJn0RhpQ.js} +2 -2
  55. package/dist/{stateDiagram-D77RDMKH-DTEN3-OJ.js → stateDiagram-D77RDMKH-BR7cI3wK.js} +2 -2
  56. package/dist/{stateDiagram-v2-MP3YSRHH-vktk3Xc5.js → stateDiagram-v2-MP3YSRHH-oGqB5UDI.js} +2 -2
  57. package/dist/{static-state-BldGd99T.js → static-state-CuV6Pc3a.js} +1 -1
  58. package/dist/style.css +1 -1
  59. package/dist/{swimlanes-42K2YHIH-Cjveh9OM.js → swimlanes-42K2YHIH-DwSZl1yC.js} +1 -1
  60. package/dist/{swimlanesDiagram-VR7AAH4N-Bdr7Ev_2.js → swimlanesDiagram-VR7AAH4N-BHlcd-Ri.js} +2 -2
  61. package/dist/{timeline-definition-24CTP7MA-KIuDcefn.js → timeline-definition-24CTP7MA-DMmP-G2O.js} +1 -1
  62. package/dist/{toast-CY1_Qv41.js → toast-DbBHmxmB.js} +2 -2
  63. package/dist/{useAsyncData-DsZMvNXn.js → useAsyncData-BYIAoMqn.js} +1 -1
  64. package/dist/{useDateFormatter-Dk_xFci4.js → useDateFormatter-ButWkdcK.js} +1 -1
  65. package/dist/{useDeepCompareMemoize-KMBBux8C.js → useDeepCompareMemoize-Bz0c5GN6.js} +1 -1
  66. package/dist/{useTheme-BZ2GGLgm.js → useTheme-DPLobSFs.js} +7 -7
  67. package/dist/{utils-DXkj82sK.js → utils-EBklsC5R.js} +31 -31
  68. package/dist/{vega-component-C-lqjV0q.js → vega-component-rxIxAAh9.js} +7 -7
  69. package/dist/{vennDiagram-4TSXK5OY-DrIOUHfb.js → vennDiagram-4TSXK5OY-Db8GtH1G.js} +1 -1
  70. package/dist/{wardleyDiagram-VM6X3IG4-CJNjf4OH.js → wardleyDiagram-VM6X3IG4-DmIiC3FU.js} +1 -1
  71. package/dist/{xychartDiagram-S5SC5T6Z-DEshFho-.js → xychartDiagram-S5SC5T6Z-DS9OPrNq.js} +1 -1
  72. package/package.json +1 -1
  73. package/src/__mocks__/executions.ts +195 -0
  74. package/src/__mocks__/notebook.ts +0 -1
  75. package/src/__tests__/CellStatus.test.tsx +19 -20
  76. package/src/components/chat/__tests__/chat-display.test.tsx +157 -86
  77. package/src/components/chat/__tests__/chat-utils.test.ts +42 -0
  78. package/src/components/chat/__tests__/turn-timing.test.ts +84 -0
  79. package/src/components/chat/__tests__/use-assistant-turn.test.ts +95 -0
  80. package/src/components/chat/__tests__/user-message.test.tsx +27 -0
  81. package/src/components/chat/acp/agent-panel.tsx +2 -0
  82. package/src/components/chat/agent-activity.tsx +132 -0
  83. package/src/components/chat/chat-display.tsx +125 -96
  84. package/src/components/chat/chat-panel.tsx +123 -106
  85. package/src/components/chat/chat-utils.ts +12 -24
  86. package/src/components/chat/tool-call/__tests__/tool-labels.test.ts +76 -0
  87. package/src/components/chat/tool-call/__tests__/tool-step.test.tsx +57 -0
  88. package/src/components/chat/tool-call/shared.ts +6 -0
  89. package/src/components/chat/tool-call/tool-call-view.tsx +22 -76
  90. package/src/components/chat/tool-call/tool-labels.ts +172 -0
  91. package/src/components/chat/tool-call/tool-step.tsx +145 -0
  92. package/src/components/chat/turn-timing.ts +73 -0
  93. package/src/components/chat/use-assistant-turn.ts +65 -0
  94. package/src/components/chat/use-chat-generation.ts +5 -4
  95. package/src/components/chat/user-message.tsx +145 -0
  96. package/src/components/dependency-graph/minimap-content.tsx +3 -2
  97. package/src/components/editor/__tests__/data-attributes.test.tsx +0 -7
  98. package/src/components/editor/__tests__/output-persistence.test.tsx +2 -2
  99. package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +19 -1
  100. package/src/components/editor/actions/useCellActionButton.tsx +10 -3
  101. package/src/components/editor/ai/completion-handlers.tsx +0 -37
  102. package/src/components/editor/alerts/stdin-blocking-alert.tsx +3 -1
  103. package/src/components/editor/cell/CellStatus.tsx +23 -19
  104. package/src/components/editor/cell/RunButton.tsx +16 -6
  105. package/src/components/editor/cell/StagedAICell.tsx +51 -144
  106. package/src/components/editor/cell/__tests__/useRunCells.test.ts +45 -0
  107. package/src/components/editor/cell/cell-context-menu.tsx +4 -1
  108. package/src/components/editor/cell/code/cell-editor.tsx +7 -5
  109. package/src/components/editor/cell/collapse.tsx +4 -0
  110. package/src/components/editor/cell/useRunCells.ts +18 -3
  111. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +193 -32
  112. package/src/components/editor/chrome/wrapper/app-chrome.tsx +2 -2
  113. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +145 -81
  114. package/src/components/editor/chrome/wrapper/pending-ai-changes-badge.tsx +25 -0
  115. package/src/components/editor/chrome/wrapper/sidebar.tsx +8 -4
  116. package/src/components/editor/header/status.tsx +4 -2
  117. package/src/components/editor/links/cell-link.tsx +4 -4
  118. package/src/components/editor/navigation/navigation.ts +3 -2
  119. package/src/components/editor/notebook-cell.tsx +85 -94
  120. package/src/components/editor/renderers/grid-layout/__tests__/grid-layout.test.tsx +75 -0
  121. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +22 -16
  122. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -1
  123. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +12 -33
  124. package/src/components/editor/stdin-blocking-alert.tsx +3 -1
  125. package/src/components/scratchpad/scratchpad.tsx +4 -1
  126. package/src/components/slides/minimap.tsx +4 -2
  127. package/src/components/slides/reveal-component.tsx +14 -10
  128. package/src/components/slides/slide-cell-view.tsx +28 -24
  129. package/src/components/slides/slide.tsx +3 -4
  130. package/src/components/ui/toast.tsx +1 -1
  131. package/src/core/ai/__tests__/staged-cells.test.ts +74 -126
  132. package/src/core/ai/staged-cells.ts +48 -38
  133. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +0 -389
  134. package/src/core/cells/__tests__/cell.test.ts +49 -154
  135. package/src/core/cells/__tests__/cells.test.ts +18 -127
  136. package/src/core/cells/__tests__/pending-delete-service.test.tsx +11 -20
  137. package/src/core/cells/__tests__/utils.test.ts +75 -247
  138. package/src/core/cells/actions.ts +5 -2
  139. package/src/core/cells/cell.ts +31 -133
  140. package/src/core/cells/cells.ts +14 -29
  141. package/src/core/cells/document.ts +3 -3
  142. package/src/core/cells/focus.ts +27 -6
  143. package/src/core/cells/layout.ts +1 -1
  144. package/src/core/cells/pending-delete-service.ts +5 -7
  145. package/src/core/cells/scrollCellIntoView.ts +6 -0
  146. package/src/core/cells/types.ts +13 -36
  147. package/src/core/cells/utils.ts +37 -68
  148. package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +59 -0
  149. package/src/core/codemirror/placeholder/extensions.ts +23 -0
  150. package/src/core/edit-app.tsx +2 -1
  151. package/src/core/executions/__tests__/atoms.test.ts +99 -0
  152. package/src/core/executions/__tests__/select.test.ts +268 -0
  153. package/src/core/executions/atoms.ts +206 -0
  154. package/src/core/executions/hooks.ts +31 -0
  155. package/src/core/executions/index.ts +31 -0
  156. package/src/core/executions/select.ts +175 -0
  157. package/src/core/export/__tests__/hooks.test.ts +0 -5
  158. package/src/core/islands/bootstrap.ts +4 -1
  159. package/src/core/islands/components/output-wrapper.tsx +5 -5
  160. package/src/core/kernel/handlers.ts +2 -11
  161. package/src/core/kernel/state.ts +0 -15
  162. package/src/core/lifecycle/render-policy.ts +12 -26
  163. package/src/core/network/__tests__/requests-lazy.test.ts +5 -5
  164. package/src/core/network/requests-lazy.ts +3 -3
  165. package/src/core/notebook/operations.ts +1 -1
  166. package/src/core/run-app.tsx +2 -1
  167. package/src/core/runtime/__tests__/adapter.test.ts +3 -3
  168. package/src/core/runtime/adapter.ts +4 -4
  169. package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +34 -0
  170. package/src/core/session/useNotebookSession.tsx +10 -5
  171. package/src/core/wasm/bridge.ts +1 -1
  172. package/src/css/app/Cell.css +7 -36
  173. package/src/plugins/core/registerReactComponent.tsx +4 -13
  174. package/src/plugins/impl/chat/chat-ui.tsx +2 -3
  175. package/src/plugins/impl/common/error-banner.tsx +5 -3
  176. package/src/stories/cell-status.stories.tsx +17 -10
  177. package/src/stories/cell.stories.tsx +0 -31
  178. package/src/stories/layout/vertical/one-column.stories.tsx +0 -9
  179. package/src/utils/time.ts +10 -0
  180. package/src/components/chat/reasoning-accordion.tsx +0 -61
  181. package/src/components/chat/tool-call/tool-activity-group.tsx +0 -49
  182. package/src/components/chat/tool-call/tool-error-card.tsx +0 -81
  183. package/src/components/chat/tool-call/tool-history-row.tsx +0 -147
  184. package/src/components/icons/loading-ellipsis.tsx +0 -46
@@ -27,20 +27,9 @@
27
27
  outline: none;
28
28
  }
29
29
 
30
- &:has(.mo-ai-generated-cell) {
31
- border-color: var(--blue-7);
32
- }
33
-
34
30
  /* Styling for cells marked for deletion by AI */
35
31
  &:has(.mo-ai-deleted-cell) {
36
- position: relative;
37
- border-color: var(--red-7);
38
-
39
- .output-area,
40
- .cm-gutters,
41
- .cm {
42
- background-color: var(--red-2);
43
- }
32
+ box-shadow: -2px 0 0 var(--red-7);
44
33
 
45
34
  /* Add strikethrough effect to the code */
46
35
  .cm-content {
@@ -218,14 +207,18 @@
218
207
 
219
208
  /* Focus state */
220
209
 
221
- &.focus-outline {
222
- transition: all 0.6s;
210
+ &.focus-outline,
211
+ &[data-ai-review-selected] {
223
212
  border-color: var(--blue-8) !important;
224
213
 
225
214
  /* custom shadow until our theme overrides can support colored shadow */
226
215
  @apply shadow-lg shadow-[var(--blue-8)];
227
216
  }
228
217
 
218
+ &.focus-outline {
219
+ transition: all 0.6s;
220
+ }
221
+
229
222
  /* Published - when its just the output */
230
223
 
231
224
  &.published {
@@ -303,20 +296,6 @@
303
296
  @apply bg-background;
304
297
  }
305
298
 
306
- .mo-ai-cell-footer {
307
- display: flex;
308
- align-items: center;
309
- justify-content: space-between;
310
- gap: 0.75rem;
311
- width: 100%;
312
- padding: 0.375rem 0.5rem;
313
- background: var(--gray-2);
314
- }
315
-
316
- .dark .mo-ai-cell-footer {
317
- background: var(--gray-3);
318
- }
319
-
320
299
  .dark .marimo-cell {
321
300
  @apply border-border;
322
301
 
@@ -355,14 +334,6 @@
355
334
  }
356
335
  }
357
336
 
358
- .dark .marimo-cell:has(.mo-ai-generated-cell) {
359
- border-color: var(--blue-8);
360
- }
361
-
362
- .dark .marimo-cell:has(.mo-ai-deleted-cell) {
363
- border-color: var(--red-8);
364
- }
365
-
366
337
  #cell-setup,
367
338
  #cell-setup .cm-editor,
368
339
  #cell-setup .cm-gutter {
@@ -24,9 +24,9 @@ import ReactDOM, { type Root } from "react-dom/client";
24
24
  import useEvent from "react-use-event-hook";
25
25
  import { type ZodSchema, z } from "zod";
26
26
  import { TooltipProvider } from "@/components/ui/tooltip";
27
- import { notebookAtom } from "@/core/cells/cells.ts";
28
27
  import { HTMLCellId } from "@/core/cells/ids.ts";
29
28
  import { isUninstantiated } from "@/core/cells/utils";
29
+ import { cellExecutionInputsAtom, cellExecutionView } from "@/core/executions";
30
30
  import { createInputEvent, MarimoValueUpdateEvent } from "@/core/dom/events";
31
31
  import { getUIElementObjectId } from "@/core/dom/ui-element";
32
32
  import { UIElementRegistry } from "@/core/dom/uiregistry";
@@ -205,18 +205,9 @@ function PluginSlotInternal<T>(
205
205
  if (cellId && !isStatic) {
206
206
  // If the cell is not initialized, throw an error
207
207
  // Continue if the cell is static, so we can propagate a clearer error message.
208
- const notebookState = store.get(notebookAtom);
209
- const cellRuntime = notebookState.cellRuntime[cellId];
210
- const cellData = notebookState.cellData[cellId];
211
-
212
- const cellNotInitialized = isUninstantiated({
213
- executionTime:
214
- cellRuntime.runElapsedTimeMs ?? cellData.lastExecutionTime,
215
- status: cellRuntime.status,
216
- errored: cellRuntime.errored,
217
- interrupted: cellRuntime.interrupted,
218
- stopped: cellRuntime.stopped,
219
- });
208
+ const cellNotInitialized = isUninstantiated(
209
+ cellExecutionView(store.get(cellExecutionInputsAtom), cellId),
210
+ );
220
211
 
221
212
  if (cellNotInitialized) {
222
213
  throw new CellNotInitializedError();
@@ -482,12 +482,11 @@ export const Chatbot: React.FC<Props> = (props) => {
482
482
  className={`max-w-[80%] p-3 rounded-lg ${
483
483
  message.role === "user"
484
484
  ? "bg-(--sky-11) text-(--slate-1) whitespace-pre-wrap"
485
- : "bg-(--slate-4) text-(--slate-12)"
485
+ : "bg-(--slate-4) text-(--slate-12) [--muted-foreground:var(--slate-11)]"
486
486
  }`}
487
487
  >
488
488
  {renderUIMessage({
489
489
  message,
490
- isStreamingReasoning: status === "streaming",
491
490
  isLast,
492
491
  isActive: isLoading,
493
492
  addToolApprovalResponse: isLast
@@ -514,7 +513,7 @@ export const Chatbot: React.FC<Props> = (props) => {
514
513
  );
515
514
  })}
516
515
 
517
- {isLoading && (
516
+ {isLoading && messages.at(-1)?.role !== "assistant" && (
518
517
  <div className="flex items-center justify-center mb-4">
519
518
  <Spinner size="small" />
520
519
  </div>
@@ -47,11 +47,13 @@ export const ErrorBanner = ({
47
47
  <AlertDialog open={open} onOpenChange={setOpen}>
48
48
  <AlertDialogContent className="max-w-[80%] max-h-[80%] overflow-hidden flex flex-col">
49
49
  <AlertDialogHeader>
50
- <AlertDialogTitle className="text-error">Error</AlertDialogTitle>
50
+ <AlertDialogTitle className="text-(--red-11)">
51
+ Error
52
+ </AlertDialogTitle>
51
53
  </AlertDialogHeader>
52
54
  <AlertDialogDescription
53
55
  asChild={true}
54
- className="text-error text-sm p-2 font-mono overflow-auto whitespace-pre-wrap"
56
+ className="text-(--red-11) text-sm p-2 font-mono overflow-auto whitespace-pre-wrap"
55
57
  >
56
58
  <pre>{message}</pre>
57
59
  </AlertDialogDescription>
@@ -72,7 +74,7 @@ const bannerStyle = cva(
72
74
  variants: {
73
75
  kind: {
74
76
  danger:
75
- "text-error border-(--red-6) shadow-md-solid shadow-error bg-(--red-1)",
77
+ "text-(--red-11) border-(--red-6) shadow-md-solid shadow-error bg-(--red-1)",
76
78
  info: "text-primary border-(--blue-6) shadow-md-solid shadow-accent bg-(--blue-1)",
77
79
  warn: "border-(--yellow-6) bg-(--yellow-2) dark:bg-(--yellow-4) text-(--yellow-11) dark:text-(--yellow-12)",
78
80
  },
@@ -5,6 +5,7 @@ import {
5
5
  type CellStatusComponentProps,
6
6
  } from "@/components/editor/cell/CellStatus";
7
7
  import { TooltipProvider } from "@/components/ui/tooltip";
8
+ import type { Milliseconds } from "@/utils/time";
8
9
 
9
10
  const meta: Meta<typeof CellStatusComponent> = {
10
11
  title: "CellStatusComponent",
@@ -39,7 +40,7 @@ Edited.args = {
39
40
  edited: true,
40
41
  interrupted: false,
41
42
  disabled: false,
42
- elapsedTime: 100,
43
+ elapsedTime: 100 as Milliseconds,
43
44
  };
44
45
 
45
46
  export const Interrupted = Template.bind({});
@@ -49,7 +50,7 @@ Interrupted.args = {
49
50
  edited: false,
50
51
  interrupted: true,
51
52
  disabled: false,
52
- elapsedTime: 50,
53
+ elapsedTime: 50 as Milliseconds,
53
54
  };
54
55
 
55
56
  export const Running = Template.bind({});
@@ -59,7 +60,7 @@ Running.args = {
59
60
  edited: false,
60
61
  interrupted: true,
61
62
  disabled: false,
62
- elapsedTime: 50,
63
+ elapsedTime: 50 as Milliseconds,
63
64
  };
64
65
 
65
66
  export const Queued = Template.bind({});
@@ -69,7 +70,7 @@ Queued.args = {
69
70
  edited: false,
70
71
  interrupted: true,
71
72
  disabled: false,
72
- elapsedTime: 50,
73
+ elapsedTime: 50 as Milliseconds,
73
74
  };
74
75
 
75
76
  export const Disabled = Template.bind({});
@@ -85,7 +86,8 @@ Disabled.args = {
85
86
  export const DisabledTransitively = Template.bind({});
86
87
  DisabledTransitively.args = {
87
88
  editing: true,
88
- status: "disabled-transitively",
89
+ status: "idle",
90
+ blocked: true,
89
91
  edited: false,
90
92
  interrupted: false,
91
93
  disabled: false,
@@ -95,7 +97,8 @@ DisabledTransitively.args = {
95
97
  export const DisabledTransitivelyAndEdited = Template.bind({});
96
98
  DisabledTransitivelyAndEdited.args = {
97
99
  editing: true,
98
- status: "disabled-transitively",
100
+ status: "idle",
101
+ blocked: true,
99
102
  edited: true,
100
103
  interrupted: false,
101
104
  disabled: false,
@@ -105,7 +108,8 @@ DisabledTransitivelyAndEdited.args = {
105
108
  export const Stale = Template.bind({});
106
109
  Stale.args = {
107
110
  editing: true,
108
- status: "disabled-transitively",
111
+ status: "idle",
112
+ blocked: true,
109
113
  staleInputs: true,
110
114
  edited: false,
111
115
  interrupted: false,
@@ -116,7 +120,8 @@ Stale.args = {
116
120
  export const StaleAndDisabled = Template.bind({});
117
121
  StaleAndDisabled.args = {
118
122
  editing: true,
119
- status: "disabled-transitively",
123
+ status: "idle",
124
+ blocked: true,
120
125
  staleInputs: true,
121
126
  edited: false,
122
127
  interrupted: false,
@@ -127,7 +132,8 @@ StaleAndDisabled.args = {
127
132
  export const EditedStaleAndDisabled = Template.bind({});
128
133
  EditedStaleAndDisabled.args = {
129
134
  editing: true,
130
- status: "disabled-transitively",
135
+ status: "idle",
136
+ blocked: true,
131
137
  staleInputs: true,
132
138
  interrupted: false,
133
139
  disabled: true,
@@ -137,7 +143,8 @@ EditedStaleAndDisabled.args = {
137
143
  export const EditedAndStale = Template.bind({});
138
144
  EditedAndStale.args = {
139
145
  editing: true,
140
- status: "disabled-transitively",
146
+ status: "idle",
147
+ blocked: true,
141
148
  edited: true,
142
149
  interrupted: false,
143
150
  disabled: false,
@@ -15,19 +15,14 @@ import { requestClientAtom } from "@/core/network/requests";
15
15
  import { resolveRequestClient } from "@/core/network/resolve";
16
16
  import type { CellConfig } from "@/core/network/types";
17
17
  import { ConnectionState } from "@/core/session/types";
18
- import type { Milliseconds, Seconds } from "@/utils/time";
19
18
  import { Cell as EditorCell } from "../components/editor/notebook-cell";
20
19
  import { TooltipProvider } from "../components/ui/tooltip";
21
20
 
22
21
  type Story = StoryObj<typeof Cell>;
23
22
 
24
23
  interface CellOverrides {
25
- runElapsedTimeMs?: Milliseconds;
26
24
  output?: CellRuntimeState["output"];
27
25
  edited?: boolean;
28
- interrupted?: boolean;
29
- errored?: boolean;
30
- status?: CellRuntimeState["status"];
31
26
  staleInputs?: boolean;
32
27
  config?: CellConfig;
33
28
  }
@@ -51,22 +46,14 @@ const Cell: React.FC<{
51
46
  column: null,
52
47
  },
53
48
  lastCodeRun: null,
54
- lastExecutionTime: null,
55
49
  },
56
50
  },
57
51
  cellIds: [cid],
58
52
  cellRuntime: {
59
53
  [cid]: createCellRuntimeState({
60
54
  output: overrides.output ?? null,
61
- runElapsedTimeMs: overrides.runElapsedTimeMs ?? (10 as Milliseconds),
62
- status: overrides.status ?? "idle",
63
55
  consoleOutputs: [],
64
- interrupted: overrides.interrupted ?? false,
65
- errored: overrides.errored ?? false,
66
- stopped: false,
67
56
  staleInputs: overrides.staleInputs ?? false,
68
- runStartTimestamp: 0 as Seconds,
69
- lastRunStartTimestamp: 0 as Seconds,
70
57
  debuggerActive: false,
71
58
  outline: null,
72
59
  }),
@@ -121,7 +108,6 @@ export const WithOutput: Story = {
121
108
  <div className="p-20 max-w-4xl">
122
109
  <Cell
123
110
  overrides={{
124
- runElapsedTimeMs: 20 as Milliseconds,
125
111
  output: {
126
112
  channel: "output",
127
113
  data: "<span class='markdown'><h1>Layout</h1>\n<p><code>marimo</code> provides functions to help you lay out your output, such as\nin rows and columns, accordions, tabs, and callouts. This tutorial\nshows some examples.</p></span>",
@@ -139,7 +125,6 @@ export const WithLargeOutput: Story = {
139
125
  <div className="p-20 max-w-4xl">
140
126
  <Cell
141
127
  overrides={{
142
- runElapsedTimeMs: 20 as Milliseconds,
143
128
  output: {
144
129
  channel: "output",
145
130
  data: "<span class='markdown'><h1>Layout</h1>\n<p><code>marimo</code> provides functions to help you lay out your output, such as\nin rows and columns, accordions, tabs, and callouts. This tutorial\nshows some examples.</p></span>".repeat(
@@ -160,7 +145,6 @@ export const UnsavedEditsOutput: Story = {
160
145
  <TooltipProvider>
161
146
  <Cell
162
147
  overrides={{
163
- runElapsedTimeMs: 20 as Milliseconds,
164
148
  edited: true,
165
149
  output: {
166
150
  channel: "output",
@@ -181,8 +165,6 @@ export const InterruptedOutput: Story = {
181
165
  <TooltipProvider>
182
166
  <Cell
183
167
  overrides={{
184
- runElapsedTimeMs: 20 as Milliseconds,
185
- interrupted: true,
186
168
  output: {
187
169
  channel: "output",
188
170
  data: "<span class='markdown'><h1>Layout</h1>\n<p><code>marimo</code> provides functions to help you lay out your output, such as\nin rows and columns, accordions, tabs, and callouts. This tutorial\nshows some examples.</p></span>",
@@ -201,8 +183,6 @@ export const WithError: Story = {
201
183
  <div className="p-20 max-w-4xl">
202
184
  <Cell
203
185
  overrides={{
204
- runElapsedTimeMs: 20 as Milliseconds,
205
- errored: true,
206
186
  output: {
207
187
  channel: "output",
208
188
  data: "<span class='markdown'><h1>Layout</h1>\n<p><code>marimo</code> provides functions to help you lay out your output, such as\nin rows and columns, accordions, tabs, and callouts. This tutorial\nshows some examples.</p></span>",
@@ -220,7 +200,6 @@ export const Disabled: Story = {
220
200
  <div className="p-20 max-w-4xl">
221
201
  <Cell
222
202
  overrides={{
223
- runElapsedTimeMs: 20 as Milliseconds,
224
203
  config: {
225
204
  disabled: true,
226
205
  hide_code: false,
@@ -243,8 +222,6 @@ export const DisabledTransitively: Story = {
243
222
  <div className="p-20 max-w-4xl">
244
223
  <Cell
245
224
  overrides={{
246
- runElapsedTimeMs: 20 as Milliseconds,
247
- status: "disabled-transitively",
248
225
  output: {
249
226
  channel: "output",
250
227
  data: "This data is stale because a parent is disabled",
@@ -262,8 +239,6 @@ export const StaleStatus: Story = {
262
239
  <div className="p-20 max-w-4xl">
263
240
  <Cell
264
241
  overrides={{
265
- runElapsedTimeMs: 20 as Milliseconds,
266
- status: "disabled-transitively",
267
242
  staleInputs: true,
268
243
  output: {
269
244
  channel: "output",
@@ -282,8 +257,6 @@ export const StaleAndEditedStatus: Story = {
282
257
  <div className="p-20 max-w-4xl">
283
258
  <Cell
284
259
  overrides={{
285
- runElapsedTimeMs: 20 as Milliseconds,
286
- status: "disabled-transitively",
287
260
  staleInputs: true,
288
261
  edited: true,
289
262
  output: {
@@ -303,13 +276,11 @@ export const DisabledAndStaleStatus: Story = {
303
276
  <div className="p-20 max-w-4xl">
304
277
  <Cell
305
278
  overrides={{
306
- runElapsedTimeMs: 20 as Milliseconds,
307
279
  config: {
308
280
  column: null,
309
281
  disabled: true,
310
282
  hide_code: false,
311
283
  },
312
- status: "disabled-transitively",
313
284
  staleInputs: true,
314
285
  output: {
315
286
  channel: "output",
@@ -328,8 +299,6 @@ export const Running: Story = {
328
299
  <div className="p-20 max-w-4xl">
329
300
  <Cell
330
301
  overrides={{
331
- runElapsedTimeMs: 20 as Milliseconds,
332
- status: "running",
333
302
  output: {
334
303
  channel: "output",
335
304
  data: "<span class='markdown'><h1>Layout</h1>\n<p><code>marimo</code> provides functions to help you lay out your output, such as\nin rows and columns, accordions, tabs, and callouts. This tutorial\nshows some examples.</p></span>",
@@ -14,7 +14,6 @@ import { connectionAtom } from "@/core/network/connection";
14
14
  import { requestClientAtom } from "@/core/network/requests";
15
15
  import { resolveRequestClient } from "@/core/network/resolve";
16
16
  import { ConnectionState } from "@/core/session/types";
17
- import type { Milliseconds, Seconds } from "@/utils/time";
18
17
  import { CellArray } from "../../../components/editor/renderers/cell-array";
19
18
  import { CellsRenderer } from "../../../components/editor/renderers/cells-renderer";
20
19
  import { TooltipProvider } from "../../../components/ui/tooltip";
@@ -50,7 +49,6 @@ LongReprA()`,
50
49
 
51
50
  print('hello')
52
51
  LongReprA()`,
53
- lastExecutionTime: null,
54
52
  },
55
53
  },
56
54
  cellIds: [cellId],
@@ -62,8 +60,6 @@ LongReprA()`,
62
60
  mimetype: "text/plain",
63
61
  timestamp: 1_686_863_710,
64
62
  },
65
- runElapsedTimeMs: 8 as Milliseconds,
66
- status: "idle",
67
63
  consoleOutputs: [
68
64
  {
69
65
  channel: "stdout",
@@ -72,12 +68,7 @@ LongReprA()`,
72
68
  timestamp: 1_686_863_705,
73
69
  },
74
70
  ],
75
- interrupted: false,
76
- errored: false,
77
- stopped: false,
78
71
  staleInputs: false,
79
- runStartTimestamp: 0 as Seconds,
80
- lastRunStartTimestamp: 0 as Seconds,
81
72
  debuggerActive: false,
82
73
  outline: null,
83
74
  }),
package/src/utils/time.ts CHANGED
@@ -31,6 +31,11 @@ export class Time {
31
31
  return new Time(Date.now() as Milliseconds);
32
32
  }
33
33
 
34
+ /** The instant an ISO 8601 timestamp names. */
35
+ public static parse(iso: string): Time {
36
+ return new Time(Date.parse(iso) as Milliseconds);
37
+ }
38
+
34
39
  private constructor(ms: Milliseconds) {
35
40
  this.ms = ms;
36
41
  }
@@ -39,6 +44,11 @@ export class Time {
39
44
  return this.ms;
40
45
  }
41
46
 
47
+ /** How long after `start` this instant is. */
48
+ public since(start: Time): Milliseconds {
49
+ return (this.ms - start.ms) as Milliseconds;
50
+ }
51
+
42
52
  public toSeconds(): Seconds {
43
53
  return (this.ms / 1000) as Seconds;
44
54
  }
@@ -1,61 +0,0 @@
1
- /* Copyright 2026 Marimo. All rights reserved. */
2
-
3
- import { BotMessageSquareIcon } from "lucide-react";
4
- import React from "react";
5
- import { ChatMarkdown } from "./chat-markdown";
6
- import {
7
- Accordion,
8
- AccordionContent,
9
- AccordionItem,
10
- AccordionTrigger,
11
- } from "@/components/ui/accordion";
12
-
13
- interface ReasoningAccordionProps {
14
- reasoning: string;
15
- index?: number;
16
- isStreaming?: boolean;
17
- }
18
-
19
- export const ReasoningAccordion: React.FC<ReasoningAccordionProps> = ({
20
- reasoning,
21
- index = 0,
22
- isStreaming = false,
23
- }) => {
24
- const [openItem, setOpenItem] = React.useState<string>("");
25
-
26
- // Some reasoning models emit a reasoning part with no surfaced content
27
- // (e.g. OpenAI's o-series, which hides chain-of-thought but still marks
28
- // its boundaries on the wire). pydantic-ai's Vercel adapter forwards the
29
- // empty start/end pair, producing a 0-char ReasoningUIPart. Skip it.
30
- if (!reasoning && !isStreaming) {
31
- return null;
32
- }
33
-
34
- return (
35
- <Accordion
36
- key={index}
37
- type="single"
38
- collapsible={true}
39
- className="w-full mb-2"
40
- value={isStreaming ? "reasoning" : openItem}
41
- onValueChange={setOpenItem}
42
- >
43
- <AccordionItem value="reasoning" className="border-0">
44
- <AccordionTrigger className="text-xs text-muted-foreground hover:bg-muted/50 px-2 py-1 h-auto rounded-sm [&[data-state=open]>svg]:rotate-180">
45
- <span className="flex items-center gap-2">
46
- <BotMessageSquareIcon className="h-3 w-3" />
47
- {isStreaming ? "Thinking" : "View reasoning"}
48
- {reasoning.length > 0 && ` (${reasoning.length} chars)`}
49
- </span>
50
- </AccordionTrigger>
51
- <AccordionContent className="pb-2 px-2">
52
- <div className="bg-muted/30 border border-muted/50 rounded-md p-3 text-muted-foreground relative">
53
- <div className="pr-6">
54
- <ChatMarkdown content={reasoning} />
55
- </div>
56
- </div>
57
- </AccordionContent>
58
- </AccordionItem>
59
- </Accordion>
60
- );
61
- };
@@ -1,49 +0,0 @@
1
- /* Copyright 2026 Marimo. All rights reserved. */
2
-
3
- import type { PropsWithChildren } from "react";
4
- import {
5
- Accordion,
6
- AccordionContent,
7
- AccordionItem,
8
- AccordionTrigger,
9
- } from "@/components/ui/accordion";
10
- import { formatToolName, type ToolState } from "./shared";
11
-
12
- interface ToolActivity {
13
- toolName: string;
14
- state: ToolState;
15
- }
16
-
17
- export function ToolActivityGroup({
18
- tools,
19
- isActive,
20
- children,
21
- }: PropsWithChildren<{ tools: ToolActivity[]; isActive: boolean }>) {
22
- const pending = tools.some((tool) => tool.state !== "output-available");
23
- const editing = tools.every(
24
- (tool) => formatToolName(tool.toolName) === "edit_notebook_tool",
25
- );
26
- const count = tools.length;
27
- const label = pending
28
- ? isActive
29
- ? editing
30
- ? "Editing notebook…"
31
- : "Working…"
32
- : "Stopped before completing all steps"
33
- : editing
34
- ? `Edited notebook · ${count} ${count === 1 ? "operation" : "operations"}`
35
- : `Completed ${count} ${count === 1 ? "step" : "steps"}`;
36
-
37
- return (
38
- <Accordion type="single" collapsible={true} className="my-1 w-full">
39
- <AccordionItem value="activity" className="border-0">
40
- <AccordionTrigger className="h-auto pl-0 pr-2 py-1 gap-2 rounded text-xs font-normal text-muted-foreground hover:bg-(--slate-2) hover:text-foreground hover:no-underline">
41
- {label}
42
- </AccordionTrigger>
43
- <AccordionContent className="pb-2 pl-3 border-l border-border">
44
- {children}
45
- </AccordionContent>
46
- </AccordionItem>
47
- </Accordion>
48
- );
49
- }
@@ -1,81 +0,0 @@
1
- /* Copyright 2026 Marimo. All rights reserved. */
2
-
3
- import { ChevronDownIcon, XCircleIcon } from "lucide-react";
4
- import React from "react";
5
- import { cn } from "@/utils/cn";
6
- import { formatToolName } from "./shared";
7
- import { ToolArgsRenderer } from "./tool-args";
8
-
9
- interface ToolErrorCardProps {
10
- toolName: string;
11
- input: unknown;
12
- errorText?: string;
13
- // When false, defaults to collapsed (the conversation has moved past this).
14
- isLive: boolean;
15
- className?: string;
16
- }
17
-
18
- export const ToolErrorCard: React.FC<ToolErrorCardProps> = ({
19
- toolName,
20
- input,
21
- errorText,
22
- isLive,
23
- className,
24
- }) => {
25
- const [open, setOpen] = React.useState(isLive);
26
-
27
- // Auto-collapse once when the conversation moves past this turn.
28
- // The user can still re-open manually afterwards; we only do this on the
29
- // live → not-live transition, never the reverse.
30
- const wasLive = React.useRef(isLive);
31
- React.useEffect(() => {
32
- if (wasLive.current && !isLive) {
33
- setOpen(false);
34
- }
35
- wasLive.current = isLive;
36
- }, [isLive]);
37
-
38
- return (
39
- <div
40
- className={cn(
41
- "rounded-md border border-(--red-6) bg-(--red-2)",
42
- className,
43
- )}
44
- >
45
- <button
46
- type="button"
47
- onClick={() => setOpen((prev) => !prev)}
48
- className="w-full flex items-center gap-2 px-3 py-2 text-xs text-(--red-11) hover:bg-(--red-3) rounded-md transition-colors"
49
- aria-expanded={open}
50
- >
51
- <XCircleIcon className="h-3.5 w-3.5 shrink-0" />
52
- <span className="flex-1 text-left">
53
- <span className="font-semibold">Failed:</span>{" "}
54
- <code className="font-mono">{formatToolName(toolName)}</code>
55
- </span>
56
- <ChevronDownIcon
57
- className={cn(
58
- "h-3.5 w-3.5 shrink-0 transition-transform",
59
- open && "rotate-180",
60
- )}
61
- />
62
- </button>
63
-
64
- {open && (
65
- <div className="px-3 pb-3 space-y-3 border-t border-(--red-6)/40 pt-3">
66
- <ToolArgsRenderer input={input} />
67
- {errorText && (
68
- <div>
69
- <h3 className="text-xs font-semibold text-(--red-11) mb-1">
70
- Error
71
- </h3>
72
- <pre className="bg-(--red-2) border border-(--red-6) rounded p-2 text-xs text-(--red-11) leading-relaxed overflow-auto scrollbar-thin max-h-64 whitespace-pre-wrap">
73
- {errorText}
74
- </pre>
75
- </div>
76
- )}
77
- </div>
78
- )}
79
- </div>
80
- );
81
- };