@marimo-team/frontend 0.25.3-dev12 → 0.25.3-dev122
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/CellStatus-_Aw9_foI.js +1 -0
- package/dist/assets/{ConnectedDataExplorerComponent-TprnxZeJ.js → ConnectedDataExplorerComponent-BRgqbAsc.js} +1 -1
- package/dist/assets/{ErrorBoundary-CM13wrd8.js → ErrorBoundary-DxSzjvbx.js} +2 -2
- package/dist/assets/JsonOutput-B7pGj79O.js +11 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-B4fCknq1.js → LazyAnyLanguageCodeMirror-BPYE76jR.js} +2 -2
- package/dist/assets/MarimoErrorOutput-Bzo6Bkp5.js +10 -0
- package/dist/assets/{RenderHTML-DX6i99Op.js → RenderHTML-D6AC0IhC.js} +1 -1
- package/dist/assets/RunButton-BjYsPiKa.js +1 -0
- package/dist/assets/__vite-browser-external-BynxqS4w.js +1 -0
- package/dist/assets/__vite-browser-external-DTOT9NDN.js +1 -0
- package/dist/assets/{add-cell-with-ai-BpD_790A.js → add-cell-with-ai-CFrR1iW4.js} +6 -6
- package/dist/assets/{add-connection-dialog-B1BXCjex.js → add-connection-dialog-CyNAB_W2.js} +1 -1
- package/dist/assets/{agent-panel-CDFUc1uu.js → agent-panel-VOrccb5q.js} +3 -3
- package/dist/assets/ai-model-dropdown-Bfxv_zvu.js +13 -0
- package/dist/assets/{alert-dialog-BaPGzeOK.js → alert-dialog-C-sWmKva.js} +1 -1
- package/dist/assets/any-language-editor-DUMe1UCk.js +1 -0
- package/dist/assets/{app-config-button-AdV-QDD7.js → app-config-button-BRcjv8A_.js} +1 -1
- package/dist/assets/arrays-0R2reF2y.js +1 -0
- package/dist/assets/{blob-BG8yoQmx.js → blob-DTYOX-m5.js} +1 -1
- package/dist/assets/{button-COI-NGrx.js → button-D8gVKwe-.js} +1 -1
- package/dist/assets/{cache-panel-DTY1dqvi.js → cache-panel-BV-c7ed0.js} +1 -1
- package/dist/assets/{capabilities-BJvf-MD4.js → capabilities-Pq1YNPlK.js} +1 -1
- package/dist/assets/cell-editor-eKgYK8Bd.js +42 -0
- package/dist/assets/{cell-link-8Auigi8P.js → cell-link-D3rkqgbU.js} +1 -1
- package/dist/assets/{cells-C6YGYGdi.js → cells-2HETnlvE.js} +18 -18
- package/dist/assets/{chat-display-DhgI2MS9.js → chat-display-BrT4VJJK.js} +1 -1
- package/dist/assets/chat-panel-qpPNEwxV.js +4 -0
- package/dist/assets/chat-ui-SAdJxg-k.js +4 -0
- package/dist/assets/{circle-DXf-VWZG.js → circle-B6D_6D8w.js} +1 -1
- package/dist/assets/{code-visibility-BJImdpDi.js → code-visibility-DYDagVy7.js} +1 -1
- package/dist/assets/column-preview-yI7-INkZ.js +1 -0
- package/dist/assets/command-palette-DF-B_YpW.js +1 -0
- package/dist/assets/{common-Sl3uthjg.js → common-DgXKwblm.js} +1 -1
- package/dist/assets/components-CBE8cOLK.js +1 -0
- package/dist/assets/{components-3cou6Mka.js → components-CuMhY4Sf.js} +1 -1
- package/dist/assets/{components-CskjK6xZ.js → components-DCo7mAWO.js} +1 -1
- package/dist/assets/config-CD1IuZFJ.js +1 -0
- package/dist/assets/{config-DRIpOKqh.js → config-DMz7oN0r.js} +1 -1
- package/dist/assets/{config-CA1V-wjh.js → config-DpY86_Yq.js} +1 -1
- package/dist/assets/{copy-D8O_CYCG.js → copy-KlhazlhB.js} +1 -1
- package/dist/assets/{copy-icon-BIiRXh_3.js → copy-icon-8-a5vovc.js} +1 -1
- package/dist/assets/{createReducer-DgRODTW6.js → createReducer-CaI_Oa0v.js} +1 -1
- package/dist/assets/{datasource-DfbNb83e.js → datasource-D9JMcEAP.js} +1 -1
- package/dist/assets/{dates-CfmdTL6B.js → dates-CQMwFko2.js} +1 -1
- package/dist/assets/{dependency-graph-panel-L5cBE5sl.js → dependency-graph-panel-BVJWPCvw.js} +3 -3
- package/dist/assets/{dist-iaThVDkA.js → dist-jlhMTKo_.js} +1 -1
- package/dist/assets/{documentation-panel-D7S8JIc2.js → documentation-panel--wI4XHso.js} +1 -1
- package/dist/assets/{download-C03FOElq.js → download-Dod42wfD.js} +1 -1
- package/dist/assets/{dropdown-menu-C1rnl-0o.js → dropdown-menu-DS6umAnH.js} +1 -1
- package/dist/assets/edit-page-Uj9YSRMX.js +9 -0
- package/dist/assets/{error-banner-COZ7SfYV.js → error-banner-B5kzVf_0.js} +1 -1
- package/dist/assets/{error-entries-CLnPDv7b.js → error-entries-D00nWhWE.js} +1 -1
- package/dist/assets/{error-panel-D2xrYLue.js → error-panel-CcN_1PWf.js} +1 -1
- package/dist/assets/{es-Cqst59WX.js → es-N9SHpmG7.js} +1 -1
- package/dist/assets/{feedback-button-DzPunIqU.js → feedback-button-ByGgqUsX.js} +1 -1
- package/dist/assets/feedback-button-tbWwJ_t6.js +1 -0
- package/dist/assets/file-explorer-panel-eTEqtMPW.js +1 -0
- package/dist/assets/{file-name-input-B4fRaQkI.js → file-name-input-D5SfTNWh.js} +1 -1
- package/dist/assets/{floating-outline-B5MaM1JS.js → floating-outline-B-k3P_AO.js} +1 -1
- package/dist/assets/{formats-yZ06h1Pl.js → formats-zylfwejq.js} +1 -1
- package/dist/assets/{formatting-BqrP-n49.js → formatting-uom1es4b.js} +1 -1
- package/dist/assets/{fullscreen-B9tHcfpV.js → fullscreen-BWTs8pYZ.js} +1 -1
- package/dist/assets/{gallery-page-BefvdsM7.js → gallery-page-BzbMhDHi.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-2n7Ig5Jm.js → ganttDiagram-EL5Y4UJY-CYqkCfFG.js} +1 -1
- package/dist/assets/{glide-data-editor-C3eaYlXg.js → glide-data-editor-BMqhUrHI.js} +2 -2
- package/dist/assets/{glide-utils-CIrAxdjv.js → glide-utils-HFqhvWHI.js} +2 -2
- package/dist/assets/home-page-DJcYWiga.js +1 -0
- package/dist/assets/{hooks-DzML9nez.js → hooks-CGLb_CCz.js} +1 -1
- package/dist/assets/{html-to-image-DK9Zl1lU.js → html-to-image-D_0rd3_B.js} +1 -1
- package/dist/assets/index-BnhSnwvB.css +2 -0
- package/dist/assets/index-bSIORW11.js +30 -0
- package/dist/assets/{input-BoBxR50a.js → input-DmHMEZGh.js} +1 -1
- package/dist/assets/kiosk-mode-DFS6HopF.js +1 -0
- package/dist/assets/{layout-Ck1RoL1B.js → layout-C2XnLAfO.js} +5 -5
- package/dist/assets/linear-Bma8J3iM.js +1 -0
- package/dist/assets/links-DX2w97N9.js +1 -0
- package/dist/assets/{logs-panel-BRytaWaO.js → logs-panel-B3T1GFBk.js} +1 -1
- package/dist/assets/{markdown-renderer-DX0Xrrfy.js → markdown-renderer-BhiTvxtL.js} +1 -1
- package/dist/assets/{menu-items-BrwnTgyK.js → menu-items-BgUyNUpu.js} +1 -1
- package/dist/assets/{mermaid-C4EiVqcd.js → mermaid-BKXlWk4F.js} +2 -2
- package/dist/assets/{name-cell-input-DlpTvPLa.js → name-cell-input-CgAObR6N.js} +1 -1
- package/dist/assets/numbers-CsZVw3Dc.js +1 -0
- package/dist/assets/{objects-snlMn4yk.js → objects-rLPlQ3X_.js} +1 -1
- package/dist/assets/{once-Haz_uxEL.js → once-6KNTRW0u.js} +1 -1
- package/dist/assets/{outline-panel-B2WIpz-1.js → outline-panel-BhBb7Vqw.js} +1 -1
- package/dist/assets/{package-data-dv4FBHxR.js → package-data-CKPmBDtg.js} +1 -1
- package/dist/assets/packages-panel-Bt0xNpFl.js +1 -0
- package/dist/assets/{panel-accordion-state-BqSH5ttk.js → panel-accordion-state-ZsUdpAYn.js} +1 -1
- package/dist/assets/panels-DJghvIKo.js +1 -0
- package/dist/assets/precisionRound-BxlUs8G4.js +1 -0
- package/dist/assets/process-output-CeOMwE17.js +1 -0
- package/dist/assets/{quadrantDiagram-AXDQQJYC-yBhCDI7E.js → quadrantDiagram-AXDQQJYC-D9KH5Zge.js} +1 -1
- package/dist/assets/react-vega-BTNeboR2.js +189 -0
- package/dist/assets/{readonly-code-display-MnMEoYW5.js → readonly-code-display-TvOC7ESE.js} +1 -1
- package/dist/assets/{readonly-python-code-ggs4hAzC.js → readonly-python-code-Cqkfdeyo.js} +1 -1
- package/dist/assets/{renderShortcut-C1JwYcqW.js → renderShortcut-rUwGqKgC.js} +1 -1
- package/dist/assets/{requests-lt0JK8Jt.js → requests-BIFR-h4M.js} +1 -1
- package/dist/assets/requests-DuLJN9Tf.js +1 -0
- package/dist/assets/{reveal-component-PiV1eQk9.js → reveal-component-CwE6U9oJ.js} +37 -37
- package/dist/assets/run-page-CtonWTtJ.js +1 -0
- package/dist/assets/{runs-BLp5jezv.js → runs-C49hleBy.js} +1 -1
- package/dist/assets/{runtime-details-state-CoL-p0MC.js → runtime-details-state-CKqJSfSR.js} +1 -1
- package/dist/assets/{save-worker-BbUSwZRG.js → save-worker-UwdGcNK5.js} +2 -1
- package/dist/assets/scratchpad-panel-CwVBedfZ.js +1 -0
- package/dist/assets/{scroll-to-bottom-button-1FyowpWV.js → scroll-to-bottom-button-CIkON2WJ.js} +1 -1
- package/dist/assets/{secrets-panel-D7KN4tVs.js → secrets-panel-bcfEKxRx.js} +1 -1
- package/dist/assets/{select-DTBn5eTb.js → select-3CVGlYrC.js} +1 -1
- package/dist/assets/{session-DqoWmb7X.js → session-CMLIzZKw.js} +1 -1
- package/dist/assets/session-panel-CdHdKUCF.js +1 -0
- package/dist/assets/{snippets-panel-ClGHtEKQ.js → snippets-panel-DYLWOLYw.js} +1 -1
- package/dist/assets/{spec-BfSBcO5B.js → spec-DlH4Mp7d.js} +1 -1
- package/dist/assets/{state-uwRvJLb8.js → state-3mcyTS9q.js} +1 -1
- package/dist/assets/state-B_MCKzBL.js +1 -0
- package/dist/assets/{state-C3oDoyFe.js → state-C5WAeuTu.js} +1 -1
- package/dist/assets/{state-DxQnC_1I.js → state-Cv2JW3l9.js} +1 -1
- package/dist/assets/{state-DtGB7xeJ.js → state-DZN9vZ6z.js} +1 -1
- package/dist/assets/state-DgECPVFs.js +107 -0
- package/dist/assets/{strings-B2vv-ENv.js → strings-C25fhMR_.js} +1 -1
- package/dist/assets/{swiper-component-a07domrZ.js → swiper-component-CRGRy5_O.js} +1 -1
- package/dist/assets/{switch-CTaiAjrz.js → switch-DYjBfpNJ.js} +1 -1
- package/dist/assets/{tabs-BuQlZFbt.js → tabs-CY8E4r9U.js} +1 -1
- package/dist/assets/{terminal-wnSHYT8N.js → terminal-Ca-kubKb.js} +1 -1
- package/dist/assets/{time-MgToa8VM.js → time-DswSXBDk.js} +1 -1
- package/dist/assets/{toast-BGzLGnvw.js → toast-Gzxi-le_.js} +1 -1
- package/dist/assets/tooltip-Brya4Ghn.js +61 -0
- package/dist/assets/{tooltip-C9TuY18o.js → tooltip-CkGm8X7m.js} +1 -1
- package/dist/assets/tracing-B0J2ctTm.js +1 -0
- package/dist/assets/tracing-panel-C1OCpoeE.js +2 -0
- package/dist/assets/{tree-actions-DnUokmva.js → tree-actions-sjBxIglc.js} +1 -1
- package/dist/assets/{use-restore-focus-BxEGwIbk.js → use-restore-focus-DdS7Tl0F.js} +1 -1
- package/dist/assets/{useAddCell-IN24thff.js → useAddCell-CaXnFGki.js} +1 -1
- package/dist/assets/useAsyncData-qvoPYHtx.js +1 -0
- package/dist/assets/useBoolean-Dd2nWXFJ.js +1 -0
- package/dist/assets/useCellActionButton-CJ90CMEj.js +1 -0
- package/dist/assets/useDebounce-DwTQ_1Pu.js +1 -0
- package/dist/assets/{useDeepCompareMemoize-DFIVN9dn.js → useDeepCompareMemoize-B2DVK2De.js} +1 -1
- package/dist/assets/useDelayElapsed-BlsDT4TV.js +1 -0
- package/dist/assets/{useDeleteCell-fQlM46Y2.js → useDeleteCell-D9N85822.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-ImXYINm_.js → useDependencyPanelTab-CzAE0cm-.js} +1 -1
- package/dist/assets/{useEvent-Dfcbgjhg.js → useEvent-BDjgaBtz.js} +1 -1
- package/dist/assets/{useEventListener-D9cftcHj.js → useEventListener-CjDeLqFC.js} +1 -1
- package/dist/assets/{useIframeCapabilities-CwTkczVN.js → useIframeCapabilities-Czr9e4uG.js} +1 -1
- package/dist/assets/{useInstallPackage-BW06eter.js → useInstallPackage-wcDq9hYT.js} +1 -1
- package/dist/assets/{useInterval--x3s1VpI.js → useInterval-DJdQmXnq.js} +1 -1
- package/dist/assets/useNotebookActions-CAMEQ38y.js +1 -0
- package/dist/assets/{useRunCells-DSJPXE-j.js → useRunCells-DGakx8hj.js} +1 -1
- package/dist/assets/{useSplitCell-DQyMF5gd.js → useSplitCell-AK5BKPGM.js} +1 -1
- package/dist/assets/useStateForKey-CGMJQT8x.js +1 -0
- package/dist/assets/{useTheme-n8Dj1zH7.js → useTheme-BAA27lh7.js} +1 -1
- package/dist/assets/{utils-CaQYvazl.js → utils-DfElfBpz.js} +1 -1
- package/dist/assets/vega-component-BeyxAJad.js +1 -0
- package/dist/assets/{vega-embed-container-DJPNkHPb.js → vega-embed-container-DtArSJz1.js} +1 -1
- package/dist/assets/vega-loader.browser-Bu25TKax.js +6 -0
- package/dist/assets/worker-jm2VC7pS.js +159 -0
- package/dist/assets/{write-secret-modal-DzKAInL2.js → write-secret-modal-BEx-EUlh.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-KbGzG6-u.js → xychartDiagram-S5SC5T6Z-CeRnBS5e.js} +1 -1
- package/dist/index.html +81 -79
- package/package.json +12 -12
- package/src/__tests__/host-imports.test.ts +1 -0
- package/src/__tests__/mount.test.ts +0 -20
- package/src/components/app-config/ai-config.tsx +7 -2
- package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
- package/src/components/chat/acp/__tests__/state.test.ts +2 -2
- package/src/components/chat/acp/blocks.tsx +2 -2
- package/src/components/chat/chat-components.tsx +2 -0
- package/src/components/chat/chat-panel.tsx +9 -8
- package/src/components/chat/chat-utils.ts +4 -8
- package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
- package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
- package/src/components/data-table/__tests__/columns.test.tsx +105 -0
- package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
- package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
- package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
- package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
- package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
- package/src/components/data-table/cell-selection/feature.ts +2 -2
- package/src/components/data-table/cell-selection/types.ts +2 -2
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
- package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
- package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
- package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
- package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
- package/src/components/data-table/charts/charts.tsx +40 -30
- package/src/components/data-table/charts/storage.ts +16 -5
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
- package/src/components/data-table/column-summary/column-summary.tsx +2 -4
- package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
- package/src/components/data-table/columns.tsx +45 -46
- package/src/components/data-table/context-menu.tsx +36 -20
- package/src/components/data-table/data-table.tsx +7 -1
- package/src/components/data-table/date-popover.tsx +6 -4
- package/src/components/data-table/export-actions.tsx +76 -48
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +2 -2
- package/src/components/data-table/search-highlight.tsx +79 -0
- package/src/components/data-table/types.ts +1 -0
- package/src/components/data-table/url-detector.tsx +49 -9
- package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
- package/src/components/datasources/__tests__/column-preview.test.tsx +63 -2
- package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
- package/src/components/datasources/column-preview.tsx +8 -2
- package/src/components/datasources/datasources.tsx +47 -35
- package/src/components/debugger/debugger-code.tsx +5 -0
- package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
- package/src/components/dependency-graph/elements.ts +24 -21
- package/src/components/dependency-graph/panels.tsx +2 -1
- package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
- package/src/components/editor/SortableCell.tsx +1 -3
- package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +24 -0
- package/src/components/editor/actions/pair-with-agent-modal.tsx +18 -15
- package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
- package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
- package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
- package/src/components/editor/cell/CreateCellButton.tsx +8 -10
- package/src/components/editor/cell/DeleteButton.tsx +1 -0
- package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
- package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
- package/src/components/editor/cell/code/cell-editor.tsx +1 -1
- package/src/components/editor/cell/code/language-toggle.tsx +8 -7
- package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +30 -1
- package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +12 -18
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +58 -1
- package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
- package/src/components/editor/chrome/wrapper/storage.ts +1 -1
- package/src/components/editor/connections/components.tsx +1 -1
- package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
- package/src/components/editor/controls/command-palette.tsx +22 -10
- package/src/components/editor/dynamic-favicon.tsx +21 -40
- package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +12 -23
- package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
- package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
- package/src/components/editor/file-tree/file-explorer.tsx +10 -5
- package/src/components/editor/file-tree/file-viewer.tsx +4 -2
- package/src/components/editor/file-tree/use-file-search.ts +35 -21
- package/src/components/editor/notebook-banner.tsx +1 -0
- package/src/components/editor/output/MarimoTracebackOutput.tsx +2 -2
- package/src/components/editor/output/ansi-reduce.ts +33 -20
- package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
- package/src/components/editor/package-alert.tsx +6 -4
- package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
- package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
- package/src/components/home/components.tsx +17 -31
- package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
- package/src/components/icons/large-spinner.tsx +3 -14
- package/src/components/icons/spinner.tsx +1 -1
- package/src/components/mcp/mcp-status-indicator.tsx +1 -1
- package/src/components/pages/__tests__/home-page.test.tsx +116 -0
- package/src/components/pages/home-page.tsx +164 -91
- package/src/components/scratchpad/scratchpad.tsx +2 -2
- package/src/components/slides/reveal-component.tsx +4 -2
- package/src/components/slides/slide-cell-view.tsx +1 -1
- package/src/components/slides/slide-form.tsx +1 -0
- package/src/components/tracing/tracing.tsx +2 -2
- package/src/components/ui/alert-dialog.tsx +1 -1
- package/src/core/ai/context/providers/datasource.ts +6 -2
- package/src/core/ai/tools/base.ts +16 -7
- package/src/core/ai/tools/edit-notebook-tool.ts +47 -45
- package/src/core/ai/tools/registry.ts +13 -8
- package/src/core/ai/tools/sample-tool.ts +6 -7
- package/src/core/attachments/state.ts +5 -8
- package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -0
- package/src/core/cells/__tests__/cell.test.ts +39 -0
- package/src/core/cells/__tests__/cells.test.ts +3 -1
- package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
- package/src/core/cells/__tests__/notebook-outline.test.ts +113 -0
- package/src/core/cells/__tests__/session.test.ts +117 -36
- package/src/core/cells/cell.ts +14 -3
- package/src/core/cells/cells.ts +3 -1
- package/src/core/cells/pending-delete-service.ts +2 -6
- package/src/core/cells/session.ts +1 -1
- package/src/core/cells/types.ts +10 -1
- package/src/core/codemirror/__tests__/setup.test.ts +29 -29
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +15 -0
- package/src/core/codemirror/cells/extensions.ts +7 -3
- package/src/core/codemirror/keymaps/vim.ts +2 -6
- package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
- package/src/core/codemirror/language/extension.ts +8 -8
- package/src/core/codemirror/language/languages/markdown.ts +8 -6
- package/src/core/codemirror/language/languages/python.ts +16 -10
- package/src/core/codemirror/language/languages/sql/sql.ts +9 -7
- package/src/core/codemirror/language/panel/panel.tsx +1 -0
- package/src/core/codemirror/language/types.ts +7 -7
- package/src/core/codemirror/rtc/extension.ts +24 -12
- package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
- package/src/core/codemirror/rtc/loro/sync.ts +1 -0
- package/src/core/codemirror/utils.ts +1 -0
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +4 -4
- package/src/core/datasets/data-source-discovery.ts +4 -6
- package/src/core/document/__tests__/codemirror.test.ts +483 -0
- package/src/core/document/__tests__/draft.test.ts +322 -0
- package/src/core/document/__tests__/fixtures.ts +92 -0
- package/src/core/document/__tests__/hooks.test.tsx +386 -0
- package/src/core/document/__tests__/lifecycle-scenarios.test.ts +61 -0
- package/src/core/document/__tests__/model.test.ts +158 -0
- package/src/core/document/__tests__/protocol-fixtures.ts +38 -0
- package/src/core/document/__tests__/recovery-scenarios.test.ts +230 -0
- package/src/core/document/__tests__/scenario-fixture.ts +42 -0
- package/src/core/document/__tests__/scenarios.test.ts +205 -0
- package/src/core/document/__tests__/state.test.ts +438 -0
- package/src/core/document/__tests__/submission.test.ts +203 -0
- package/src/core/document/__tests__/test-host.test.ts +92 -0
- package/src/core/document/__tests__/test-host.ts +247 -0
- package/src/core/document/__tests__/test-notebook.ts +139 -0
- package/src/core/document/__tests__/user.ts +61 -0
- package/src/core/document/codemirror.ts +311 -0
- package/src/core/document/draft.ts +472 -0
- package/src/core/document/hooks.tsx +118 -0
- package/src/core/document/index.ts +22 -0
- package/src/core/document/model.ts +52 -0
- package/src/core/document/select.ts +41 -0
- package/src/core/document/state.ts +374 -0
- package/src/core/document/sync.ts +363 -0
- package/src/core/host/AGENTS.md +12 -2
- package/src/core/host/__tests__/attachments.test.ts +56 -0
- package/src/core/host/__tests__/document.test.ts +126 -0
- package/src/core/host/__tests__/fixtures.ts +41 -0
- package/src/core/host/__tests__/notebook-client.test.ts +511 -132
- package/src/core/host/__tests__/static.test.ts +167 -0
- package/src/core/host/__tests__/wasm.test.ts +152 -0
- package/src/core/host/backend.ts +10 -0
- package/src/core/host/connection.ts +1 -40
- package/src/core/host/notebook-client.ts +204 -133
- package/src/core/host/resources/attachments.ts +22 -0
- package/src/core/host/resources/document.ts +101 -0
- package/src/core/host/static.ts +70 -0
- package/src/core/host/wasm.ts +92 -0
- package/src/core/hotkeys/actions.ts +2 -4
- package/src/core/islands/__tests__/bootstrap.test.ts +0 -26
- package/src/core/islands/bootstrap.ts +0 -1
- package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
- package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
- package/src/core/network/connection.ts +4 -2
- package/src/core/network/useConnectionNotice.ts +8 -2
- package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
- package/src/core/runtime/__tests__/runtime.test.ts +15 -58
- package/src/core/runtime/runtime.ts +25 -42
- package/src/core/runtime/types.ts +0 -2
- package/src/core/state/__tests__/jotai.test.tsx +108 -0
- package/src/core/state/jotai.ts +1 -1
- package/src/core/static/__tests__/files.test.ts +38 -10
- package/src/core/static/files.ts +2 -0
- package/src/core/wasm/bridge.ts +38 -10
- package/src/core/wasm/store.ts +3 -3
- package/src/core/wasm/worker/bootstrap.ts +2 -1
- package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
- package/src/core/wasm/worker/types.ts +11 -0
- package/src/core/wasm/worker/worker.ts +48 -0
- package/src/core/websocket/__tests__/connection-state.test.ts +0 -12
- package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +153 -70
- package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +151 -428
- package/src/core/websocket/connection-state.ts +0 -10
- package/src/core/websocket/state.ts +7 -0
- package/src/core/websocket/transports/__tests__/notebook.test.ts +502 -0
- package/src/core/websocket/transports/notebook.ts +213 -0
- package/src/core/websocket/useNotebookClient.ts +38 -29
- package/src/core/websocket/useNotebookSession.tsx +1 -14
- package/src/css/globals.css +5 -0
- package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
- package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
- package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
- package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
- package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
- package/src/hooks/__tests__/useScript.test.tsx +77 -0
- package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
- package/src/hooks/useAsyncData.ts +3 -3
- package/src/hooks/useDataSourceDiscovery.ts +6 -4
- package/src/hooks/useDebounce.ts +6 -10
- package/src/hooks/useDeepCompareMemoize.ts +1 -1
- package/src/hooks/useDelayElapsed.ts +14 -10
- package/src/hooks/useElapsedTime.ts +3 -3
- package/src/hooks/useEventListener.ts +1 -2
- package/src/hooks/useInputHistory.ts +4 -7
- package/src/hooks/useInternalStateWithSync.ts +6 -6
- package/src/hooks/useResizeObserver.ts +4 -7
- package/src/hooks/useScript.ts +67 -70
- package/src/hooks/useStateForKey.ts +93 -0
- package/src/mount.tsx +0 -4
- package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
- package/src/plugins/core/registerReactComponent.tsx +1 -1
- package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataTablePlugin.tsx +29 -33
- package/src/plugins/impl/DropdownPlugin.tsx +2 -6
- package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
- package/src/plugins/impl/FormPlugin.tsx +1 -1
- package/src/plugins/impl/RangeSliderPlugin.tsx +0 -1
- package/src/plugins/impl/RefreshPlugin.tsx +1 -0
- package/src/plugins/impl/SliderPlugin.tsx +6 -8
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +117 -1
- package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
- package/src/plugins/impl/anywidget/__tests__/registry.test.ts +2 -0
- package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
- package/src/plugins/impl/anywidget/runtime.ts +21 -9
- package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
- package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
- package/src/plugins/impl/chat/chat-ui.tsx +12 -10
- package/src/plugins/impl/code/any-language-editor.tsx +2 -2
- package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
- package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
- package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
- package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
- package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
- package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
- package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
- package/src/plugins/impl/panel/utils.ts +17 -0
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
- package/src/plugins/impl/plotly/selection.ts +25 -19
- package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
- package/src/plugins/impl/vega/make-selectable.ts +4 -7
- package/src/plugins/layout/RoutesPlugin.tsx +1 -1
- package/src/stories/__tests__/editor-story.test.tsx +33 -0
- package/src/stories/button.stories.tsx +1 -0
- package/src/stories/editor.stories.tsx +24 -17
- package/src/stories/form-wrapper.stories.tsx +2 -2
- package/src/stories/select.stories.tsx +2 -2
- package/src/stories/switchable-multi-select.stories.tsx +1 -1
- package/src/utils/__tests__/arrays.test.ts +35 -0
- package/src/utils/__tests__/batch-requests.test.ts +3 -3
- package/src/utils/__tests__/numbers.test.ts +48 -1
- package/src/utils/__tests__/objects.test.ts +21 -0
- package/src/utils/arrays.ts +10 -0
- package/src/utils/blob.ts +1 -1
- package/src/utils/numbers.ts +28 -17
- package/src/utils/objects.ts +3 -7
- package/src/utils/once.ts +19 -19
- package/src/utils/tracer.ts +9 -5
- package/src/utils/zod-utils.ts +1 -3
- package/dist/assets/CellStatus-DVOHpdeJ.js +0 -1
- package/dist/assets/JsonOutput-Cx1iyibB.js +0 -11
- package/dist/assets/MarimoErrorOutput-s_5GOX8k.js +0 -10
- package/dist/assets/RunButton-BKoh0zYG.js +0 -1
- package/dist/assets/__vite-browser-external-CYO_P3S8.js +0 -1
- package/dist/assets/__vite-browser-external-FeDVGZU8.js +0 -1
- package/dist/assets/ai-model-dropdown-i1vfGeVi.js +0 -13
- package/dist/assets/any-language-editor-BdTWdMCI.js +0 -1
- package/dist/assets/arrays-BqUx5USx.js +0 -1
- package/dist/assets/cell-editor-BKJ06H5F.js +0 -21
- package/dist/assets/chat-panel-Cau71Ygr.js +0 -4
- package/dist/assets/chat-ui-C5ql1Up-.js +0 -4
- package/dist/assets/circle-play-CYIb0qT6.js +0 -1
- package/dist/assets/column-preview-BZ_iNhtJ.js +0 -1
- package/dist/assets/command-palette-DDC3kBet.js +0 -1
- package/dist/assets/components-YBmtV0p6.js +0 -1
- package/dist/assets/config-Dy28fDwn.js +0 -1
- package/dist/assets/edit-page-D_Rg0gQO.js +0 -9
- package/dist/assets/feedback-button-Kla7i5RT.js +0 -1
- package/dist/assets/file-explorer-panel-Uk4_QIJQ.js +0 -1
- package/dist/assets/home-page-hmvKlc1w.js +0 -4
- package/dist/assets/index-6b4mf8Ai.css +0 -2
- package/dist/assets/index-ptK1gxmo.js +0 -30
- package/dist/assets/kiosk-mode-BZECfg9k.js +0 -1
- package/dist/assets/linear-0eij_aAG.js +0 -1
- package/dist/assets/link-NuFVR7G9.js +0 -1
- package/dist/assets/links-DkkL9DVa.js +0 -1
- package/dist/assets/numbers-Mk3-CcoU.js +0 -1
- package/dist/assets/packages-panel-CI5ff9b-.js +0 -1
- package/dist/assets/panels-BCcZ_yLK.js +0 -107
- package/dist/assets/precisionRound-Bq_nmf5u.js +0 -1
- package/dist/assets/process-output-f3C3PD0Z.js +0 -1
- package/dist/assets/react-vega-C3rYGtP6.js +0 -189
- package/dist/assets/requests-CgSY1X4a.js +0 -1
- package/dist/assets/run-page-AfZhtEh1.js +0 -1
- package/dist/assets/scratchpad-panel-D2rWg4k8.js +0 -1
- package/dist/assets/session-panel-CnANhcTo.js +0 -1
- package/dist/assets/state-BAJYRhmO.js +0 -1
- package/dist/assets/state-CbjBtkdd.js +0 -3
- package/dist/assets/tooltip-mT3CGest.js +0 -61
- package/dist/assets/tracing-Dz2rYOFL.js +0 -1
- package/dist/assets/tracing-panel-DqQY9V91.js +0 -2
- package/dist/assets/useAsyncData-C7aJJz0Y.js +0 -1
- package/dist/assets/useBoolean-d0Tty94N.js +0 -1
- package/dist/assets/useCellActionButton-DmaFZ4oF.js +0 -1
- package/dist/assets/useDebounce-B_ccBZTp.js +0 -1
- package/dist/assets/useNotebookActions-DHt3s-ia.js +0 -1
- package/dist/assets/vega-component-IouMe13t.js +0 -1
- package/dist/assets/vega-loader.browser-CLRkNgm7.js +0 -6
- package/dist/assets/worker-DTQ7oH2A.js +0 -158
- package/dist/assets/ws-BXWY541V.js +0 -22
- package/src/core/host/__tests__/events.test.ts +0 -46
- package/src/core/host/__tests__/protocol.test.ts +0 -214
- package/src/core/host/events.ts +0 -60
- package/src/core/host/protocol.ts +0 -1943
- package/src/core/state/__tests__/jotai.test.ts +0 -25
- package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
- package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
- package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
- package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
- package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
- package/src/core/websocket/transports/basic.ts +0 -102
- package/src/core/websocket/transports/create.ts +0 -31
- package/src/core/websocket/transports/sse.ts +0 -308
- package/src/core/websocket/transports/transport.ts +0 -50
- package/src/core/websocket/transports/ws.ts +0 -98
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { CreateNewNotebook } from "../home-page";
|
|
6
|
+
|
|
7
|
+
function newNotebookKey(link: HTMLElement): string | null {
|
|
8
|
+
return new URL(
|
|
9
|
+
link.getAttribute("href") ?? "",
|
|
10
|
+
window.location.href,
|
|
11
|
+
).searchParams.get("file");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function activate(link: HTMLElement, type: string, init: MouseEventInit) {
|
|
15
|
+
fireEvent(link, new MouseEvent(type, { bubbles: true, ...init }));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("CreateNewNotebook", () => {
|
|
19
|
+
it("links to an untitled notebook", () => {
|
|
20
|
+
render(<CreateNewNotebook />);
|
|
21
|
+
const link = screen.getByRole("link", { name: /new notebook/i });
|
|
22
|
+
|
|
23
|
+
expect(newNotebookKey(link)).toMatch(/^__new__/);
|
|
24
|
+
expect(link).toHaveAttribute("target", "_blank");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it.each([
|
|
28
|
+
{ label: "click", type: "click", init: { button: 0, detail: 1 } },
|
|
29
|
+
// Enter on a focused link fires `click` with detail 0
|
|
30
|
+
{ label: "keyboard activation", type: "click", init: { detail: 0 } },
|
|
31
|
+
// ctrl/cmd-click opens a tab and still fires `click`
|
|
32
|
+
{ label: "ctrl-click", type: "click", init: { ctrlKey: true } },
|
|
33
|
+
{ label: "cmd-click", type: "click", init: { metaKey: true } },
|
|
34
|
+
// middle-click opens a tab without firing `click`
|
|
35
|
+
{ label: "middle-click", type: "auxclick", init: { button: 1 } },
|
|
36
|
+
// "Open link in new tab" from the context menu fires no click at all
|
|
37
|
+
{ label: "right-click", type: "contextmenu", init: { button: 2 } },
|
|
38
|
+
])("uses a fresh notebook key on every $label", ({ type, init }) => {
|
|
39
|
+
render(<CreateNewNotebook />);
|
|
40
|
+
const link = screen.getByRole("link", { name: /new notebook/i });
|
|
41
|
+
|
|
42
|
+
const keys = new Set<string | null>([newNotebookKey(link)]);
|
|
43
|
+
for (let i = 0; i < 2; i++) {
|
|
44
|
+
activate(link, type, init);
|
|
45
|
+
keys.add(newNotebookKey(link));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
expect(keys.size).toBe(3);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("never hands the browser a key that an earlier activation used", () => {
|
|
52
|
+
render(<CreateNewNotebook />);
|
|
53
|
+
const link = screen.getByRole("link", { name: /new notebook/i });
|
|
54
|
+
|
|
55
|
+
// The browser reads `href` after every listener ran. Record it there.
|
|
56
|
+
const followed: Array<string | null> = [];
|
|
57
|
+
const record = () => followed.push(newNotebookKey(link));
|
|
58
|
+
document.addEventListener("click", record);
|
|
59
|
+
document.addEventListener("auxclick", record);
|
|
60
|
+
try {
|
|
61
|
+
activate(link, "contextmenu", { button: 2 });
|
|
62
|
+
activate(link, "click", { button: 0 });
|
|
63
|
+
activate(link, "click", { button: 0 });
|
|
64
|
+
activate(link, "auxclick", { button: 1 });
|
|
65
|
+
activate(link, "contextmenu", { button: 2 });
|
|
66
|
+
activate(link, "click", { button: 0, metaKey: true });
|
|
67
|
+
} finally {
|
|
68
|
+
document.removeEventListener("click", record);
|
|
69
|
+
document.removeEventListener("auxclick", record);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
expect(followed).toHaveLength(4);
|
|
73
|
+
expect(new Set(followed).size).toBe(4);
|
|
74
|
+
for (const key of followed) {
|
|
75
|
+
expect(key).toMatch(/^__new__s_/);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("puts a fresh key into the drag payload", () => {
|
|
80
|
+
render(<CreateNewNotebook />);
|
|
81
|
+
const link = screen.getByRole("link", { name: /new notebook/i });
|
|
82
|
+
const before = newNotebookKey(link);
|
|
83
|
+
|
|
84
|
+
const payload = new Map<string, string>();
|
|
85
|
+
const dataTransfer = {
|
|
86
|
+
setData: (format: string, data: string) => payload.set(format, data),
|
|
87
|
+
};
|
|
88
|
+
fireEvent.dragStart(link, { dataTransfer });
|
|
89
|
+
|
|
90
|
+
const dragged = new URL(
|
|
91
|
+
payload.get("text/uri-list") ?? "",
|
|
92
|
+
window.location.href,
|
|
93
|
+
).searchParams.get("file");
|
|
94
|
+
expect(dragged).toMatch(/^__new__s_/);
|
|
95
|
+
expect(dragged).not.toBe(before);
|
|
96
|
+
expect(payload.get("text/plain")).toBe(payload.get("text/uri-list"));
|
|
97
|
+
// The link itself moves to the dragged key, so a later click rotates again
|
|
98
|
+
expect(newNotebookKey(link)).toBe(dragged);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("survives a re-render without reusing a key", () => {
|
|
102
|
+
const { rerender } = render(<CreateNewNotebook />);
|
|
103
|
+
const link = screen.getByRole("link", { name: /new notebook/i });
|
|
104
|
+
|
|
105
|
+
const keys = new Set<string | null>([newNotebookKey(link)]);
|
|
106
|
+
activate(link, "click", { button: 0 });
|
|
107
|
+
keys.add(newNotebookKey(link));
|
|
108
|
+
rerender(<CreateNewNotebook />);
|
|
109
|
+
keys.add(newNotebookKey(link));
|
|
110
|
+
activate(link, "click", { button: 0 });
|
|
111
|
+
keys.add(newNotebookKey(link));
|
|
112
|
+
|
|
113
|
+
// A re-render keeps the current key; only activations rotate it
|
|
114
|
+
expect(keys.size).toBe(3);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { useAtom, useSetAtom } from "jotai";
|
|
4
4
|
import {
|
|
5
|
-
BookTextIcon,
|
|
6
5
|
ChevronDownIcon,
|
|
7
6
|
ChevronRightIcon,
|
|
8
7
|
ChevronsDownUpIcon,
|
|
9
|
-
ClockIcon,
|
|
10
8
|
ExternalLinkIcon,
|
|
11
|
-
|
|
9
|
+
PlusIcon,
|
|
12
10
|
PowerOffIcon,
|
|
13
11
|
RefreshCcwIcon,
|
|
14
12
|
SearchIcon,
|
|
@@ -44,6 +42,7 @@ import { Button } from "@/components/ui/button";
|
|
|
44
42
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
45
43
|
import { DropdownMenuSeparator } from "@/components/ui/dropdown-menu";
|
|
46
44
|
import { Label } from "@/components/ui/label";
|
|
45
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
47
46
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
48
47
|
import { toast } from "@/components/ui/use-toast";
|
|
49
48
|
import { getSessionId, isSessionId } from "@/core/kernel/session";
|
|
@@ -64,7 +63,6 @@ import { ConfigButton } from "../app-config/app-config-button";
|
|
|
64
63
|
import { ErrorBoundary } from "../editor/boundary/ErrorBoundary";
|
|
65
64
|
import { ShutdownButton } from "../editor/controls/shutdown-button";
|
|
66
65
|
import {
|
|
67
|
-
Header,
|
|
68
66
|
OpenTutorialDropDown,
|
|
69
67
|
ResourceLinks,
|
|
70
68
|
TruncatedWorkspaceBanner,
|
|
@@ -83,6 +81,9 @@ function tabTarget(path: string) {
|
|
|
83
81
|
return `${getSessionId()}-${encodeURIComponent(path)}`;
|
|
84
82
|
}
|
|
85
83
|
|
|
84
|
+
const NOTEBOOK_TAB_CLASS =
|
|
85
|
+
"-mb-px rounded-none border-b-2 border-transparent px-1 py-3 text-(--gray-11) transition-colors hover:text-foreground focus-visible:ring-inset focus-visible:ring-offset-0 data-[state=active]:border-(--green-11) data-[state=active]:bg-transparent data-[state=active]:text-(--green-11) data-[state=active]:shadow-none";
|
|
86
|
+
|
|
86
87
|
const HomePage: React.FC = () => {
|
|
87
88
|
const [nonce, setNonce] = useState(0);
|
|
88
89
|
const { getRecentFiles, getRunningNotebooks } = useRequestClient();
|
|
@@ -123,28 +124,75 @@ const HomePage: React.FC = () => {
|
|
|
123
124
|
setRunningNotebooks: runningResponse.setData,
|
|
124
125
|
}}
|
|
125
126
|
>
|
|
126
|
-
<div className="
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
127
|
+
<div className="min-h-screen bg-background">
|
|
128
|
+
<header className="border-b border-border/60">
|
|
129
|
+
<div className="mx-auto flex max-w-7xl items-center justify-between gap-4 px-5 py-5 sm:px-10">
|
|
130
|
+
<img src="logo.png" alt="marimo" className="w-28" />
|
|
131
|
+
<div className="flex items-center gap-3">
|
|
132
|
+
<ConfigButton showAppConfig={false} />
|
|
133
|
+
<ShutdownButton
|
|
134
|
+
description={`This will shutdown the notebook server and terminate all running notebooks (${running.size}). You'll lose all data that's in memory.`}
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</header>
|
|
139
|
+
<main className="mx-auto max-w-7xl px-5 py-8 sm:px-10 sm:py-10">
|
|
140
|
+
<div className="mb-8">
|
|
141
|
+
<h1 className="text-2xl font-semibold tracking-tight">
|
|
142
|
+
Your notebooks
|
|
143
|
+
</h1>
|
|
144
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
145
|
+
Pick up where you left off, or start something new.
|
|
146
|
+
</p>
|
|
147
|
+
<div className="mt-5 flex items-center gap-3">
|
|
148
|
+
<CreateNewNotebook />
|
|
149
|
+
<OpenTutorialDropDown />
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
<Tabs defaultValue="workspace">
|
|
153
|
+
<TabsList
|
|
154
|
+
aria-label="Notebooks"
|
|
155
|
+
className="mb-5 flex h-auto w-full justify-start gap-6 rounded-none border-b border-border/70 bg-transparent p-0"
|
|
156
|
+
>
|
|
157
|
+
<TabsTrigger value="workspace" className={NOTEBOOK_TAB_CLASS}>
|
|
158
|
+
Workspace
|
|
159
|
+
</TabsTrigger>
|
|
160
|
+
<TabsTrigger value="recent" className={NOTEBOOK_TAB_CLASS}>
|
|
161
|
+
Recent
|
|
162
|
+
</TabsTrigger>
|
|
163
|
+
<TabsTrigger value="running" className={NOTEBOOK_TAB_CLASS}>
|
|
164
|
+
Running
|
|
165
|
+
<span className="ml-1.5 text-xs font-normal tabular-nums text-(--gray-11)">
|
|
166
|
+
{running.size}
|
|
167
|
+
</span>
|
|
168
|
+
</TabsTrigger>
|
|
169
|
+
</TabsList>
|
|
170
|
+
<TabsContent
|
|
171
|
+
value="workspace"
|
|
172
|
+
forceMount={true}
|
|
173
|
+
className="mt-0 data-[state=inactive]:hidden"
|
|
174
|
+
>
|
|
175
|
+
<ErrorBoundary>
|
|
176
|
+
<WorkspaceNotebooks
|
|
177
|
+
onRefreshRecents={recentsResponse.refetch}
|
|
178
|
+
/>
|
|
179
|
+
</ErrorBoundary>
|
|
180
|
+
</TabsContent>
|
|
181
|
+
<TabsContent value="recent" className="mt-0">
|
|
182
|
+
<NotebookList
|
|
183
|
+
files={recents.files}
|
|
184
|
+
emptyMessage="Notebooks you open will appear here."
|
|
185
|
+
/>
|
|
186
|
+
</TabsContent>
|
|
187
|
+
<TabsContent value="running" className="mt-0">
|
|
188
|
+
<NotebookList
|
|
189
|
+
files={[...running.values()]}
|
|
190
|
+
emptyMessage="No notebooks are running."
|
|
191
|
+
/>
|
|
192
|
+
</TabsContent>
|
|
193
|
+
</Tabs>
|
|
194
|
+
<ResourceLinks />
|
|
195
|
+
</main>
|
|
148
196
|
</div>
|
|
149
197
|
</RunningNotebooksContext>
|
|
150
198
|
</Suspense>
|
|
@@ -195,23 +243,37 @@ const WorkspaceNotebooks: React.FC<{ onRefreshRecents: () => void }> = ({
|
|
|
195
243
|
|
|
196
244
|
return (
|
|
197
245
|
<WorkspaceContext value={workspaceContextValue}>
|
|
198
|
-
<div className="flex flex-col gap-
|
|
246
|
+
<div className="flex min-w-0 flex-col gap-4">
|
|
199
247
|
{workspace.hasMore && (
|
|
200
248
|
<TruncatedWorkspaceBanner fileCount={workspace.fileCount} />
|
|
201
249
|
)}
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<div className="flex items-center gap-2">
|
|
250
|
+
<div className="overflow-hidden rounded-lg border border-border/70 bg-background">
|
|
251
|
+
<div className="flex flex-wrap items-center gap-3 border-b border-border/60 bg-muted/20 p-3">
|
|
252
|
+
<div className="min-w-40 flex-1">
|
|
206
253
|
<Input
|
|
207
254
|
id="search"
|
|
255
|
+
aria-label="Search workspace"
|
|
208
256
|
value={searchText}
|
|
209
|
-
icon={<SearchIcon size={
|
|
257
|
+
icon={<SearchIcon size={15} />}
|
|
210
258
|
onChange={(e) => setSearchText(e.target.value)}
|
|
211
|
-
placeholder="
|
|
212
|
-
className="mb-0 border-border"
|
|
259
|
+
placeholder="Find a notebook…"
|
|
260
|
+
className="mb-0 h-9 rounded-md border-border/60 bg-background font-sans shadow-none hover:shadow-none focus-visible:shadow-none"
|
|
213
261
|
/>
|
|
214
|
-
|
|
262
|
+
</div>
|
|
263
|
+
<Button
|
|
264
|
+
variant="ghost"
|
|
265
|
+
size="icon"
|
|
266
|
+
onClick={() => refetch()}
|
|
267
|
+
aria-label="Refresh workspace"
|
|
268
|
+
>
|
|
269
|
+
{isFetching ? (
|
|
270
|
+
<Spinner size="small" />
|
|
271
|
+
) : (
|
|
272
|
+
<RefreshCcwIcon className="w-4 h-4" />
|
|
273
|
+
)}
|
|
274
|
+
</Button>
|
|
275
|
+
<CollapseAllButton />
|
|
276
|
+
<div className="flex items-center gap-2">
|
|
215
277
|
<Checkbox
|
|
216
278
|
data-testid="include-markdown-checkbox"
|
|
217
279
|
id="include-markdown"
|
|
@@ -220,23 +282,14 @@ const WorkspaceNotebooks: React.FC<{ onRefreshRecents: () => void }> = ({
|
|
|
220
282
|
setIncludeMarkdown(Boolean(checked))
|
|
221
283
|
}
|
|
222
284
|
/>
|
|
223
|
-
<Label
|
|
285
|
+
<Label
|
|
286
|
+
htmlFor="include-markdown"
|
|
287
|
+
className="text-xs text-muted-foreground"
|
|
288
|
+
>
|
|
289
|
+
Include markdown
|
|
290
|
+
</Label>
|
|
224
291
|
</div>
|
|
225
|
-
|
|
226
|
-
>
|
|
227
|
-
Workspace
|
|
228
|
-
<Button
|
|
229
|
-
variant="text"
|
|
230
|
-
size="icon"
|
|
231
|
-
className="w-4 h-4 ml-1 p-0 opacity-70 hover:opacity-100"
|
|
232
|
-
onClick={() => refetch()}
|
|
233
|
-
aria-label="Refresh workspace"
|
|
234
|
-
>
|
|
235
|
-
<RefreshCcwIcon className="w-4 h-4" />
|
|
236
|
-
</Button>
|
|
237
|
-
{isFetching && <Spinner size="small" />}
|
|
238
|
-
</Header>
|
|
239
|
-
<div className="flex flex-col divide-y divide-(--slate-3) border rounded overflow-hidden max-h-192 overflow-y-auto shadow-sm bg-background">
|
|
292
|
+
</div>
|
|
240
293
|
<NotebookFileTree searchText={searchText} files={workspace.files} />
|
|
241
294
|
</div>
|
|
242
295
|
</div>
|
|
@@ -322,7 +375,7 @@ const NotebookFileTree: React.FC<{
|
|
|
322
375
|
await handleRename(id, name);
|
|
323
376
|
}}
|
|
324
377
|
padding={5}
|
|
325
|
-
rowHeight={
|
|
378
|
+
rowHeight={44}
|
|
326
379
|
indent={15}
|
|
327
380
|
overscanCount={1000}
|
|
328
381
|
// Hide the drop cursor
|
|
@@ -343,13 +396,15 @@ const Node = ({ node, style }: NodeRendererProps<FileInfo>) => {
|
|
|
343
396
|
: guessFileType(node.data.name);
|
|
344
397
|
|
|
345
398
|
const Icon = FILE_TYPE_ICONS[fileType];
|
|
346
|
-
const iconEl =
|
|
399
|
+
const iconEl = (
|
|
400
|
+
<Icon className="w-4 h-4 shrink-0 text-(--gray-11)" strokeWidth={1.5} />
|
|
401
|
+
);
|
|
347
402
|
const { root } = use(WorkspaceContext);
|
|
348
403
|
const { runningNotebooks } = use(RunningNotebooksContext);
|
|
349
404
|
|
|
350
405
|
const renderItem = () => {
|
|
351
406
|
const itemClassName =
|
|
352
|
-
"flex items-center pl-1 cursor-pointer hover:bg-
|
|
407
|
+
"flex items-center pl-1 cursor-pointer hover:bg-(--sage-3) hover:text-foreground rounded-l flex-1 overflow-hidden h-full pr-3 gap-2";
|
|
353
408
|
|
|
354
409
|
// Inline rename input; react-arborist flips `node.isEditing` when
|
|
355
410
|
// `node.edit()` is called from the FileActions menu.
|
|
@@ -413,7 +468,7 @@ const Node = ({ node, style }: NodeRendererProps<FileInfo>) => {
|
|
|
413
468
|
<div
|
|
414
469
|
style={style}
|
|
415
470
|
className={cn(
|
|
416
|
-
"flex items-center cursor-pointer ml-1 text-
|
|
471
|
+
"flex items-center cursor-pointer ml-1 text-sm text-foreground whitespace-nowrap group h-full",
|
|
417
472
|
)}
|
|
418
473
|
onClick={(evt) => {
|
|
419
474
|
evt.stopPropagation();
|
|
@@ -479,21 +534,19 @@ const FolderArrow = ({ node }: { node: NodeApi<FileInfo> }) => {
|
|
|
479
534
|
};
|
|
480
535
|
|
|
481
536
|
const NotebookList: React.FC<{
|
|
482
|
-
header: React.ReactNode;
|
|
483
537
|
files: MarimoFile[];
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
return null;
|
|
487
|
-
}
|
|
488
|
-
|
|
538
|
+
emptyMessage: string;
|
|
539
|
+
}> = ({ files, emptyMessage }) => {
|
|
489
540
|
return (
|
|
490
|
-
<div className="flex flex-col
|
|
491
|
-
{
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
541
|
+
<div className="flex max-h-[500px] min-h-40 min-w-0 flex-col divide-y divide-border/50 overflow-y-auto rounded-lg border border-border/60">
|
|
542
|
+
{files.length === 0 && (
|
|
543
|
+
<p className="px-4 py-6 text-sm text-muted-foreground">
|
|
544
|
+
{emptyMessage}
|
|
545
|
+
</p>
|
|
546
|
+
)}
|
|
547
|
+
{files.map((file) => {
|
|
548
|
+
return <MarimoFileComponent key={file.path} file={file} />;
|
|
549
|
+
})}
|
|
497
550
|
</div>
|
|
498
551
|
);
|
|
499
552
|
};
|
|
@@ -511,17 +564,19 @@ const MarimoFileComponent = ({ file }: { file: MarimoFile }) => {
|
|
|
511
564
|
: asURL(`?file=${encodeURIComponent(file.path)}`);
|
|
512
565
|
|
|
513
566
|
const isMarkdown = file.path.endsWith(".md");
|
|
567
|
+
const Icon = FILE_TYPE_ICONS[guessFileType(file.name)];
|
|
514
568
|
|
|
515
569
|
return (
|
|
516
570
|
<a
|
|
517
|
-
className="py-
|
|
571
|
+
className="py-3 px-4 hover:bg-(--sage-3) transition-colors cursor-pointer group relative flex gap-3 items-center focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring"
|
|
518
572
|
key={file.path}
|
|
519
573
|
href={href.toString()}
|
|
520
574
|
target={tabTarget(file.initializationId || file.path)}
|
|
521
575
|
>
|
|
522
|
-
<
|
|
523
|
-
|
|
524
|
-
|
|
576
|
+
<Icon className="h-4 w-4 shrink-0 text-(--gray-11)" strokeWidth={1.5} />
|
|
577
|
+
<div className="flex min-w-0 flex-col gap-1 flex-1">
|
|
578
|
+
<span className="flex items-center gap-2 text-sm font-medium">
|
|
579
|
+
<span className="truncate">{file.name}</span>
|
|
525
580
|
{isMarkdown && (
|
|
526
581
|
<span className="opacity-80">
|
|
527
582
|
<MarkdownIcon />
|
|
@@ -530,7 +585,7 @@ const MarimoFileComponent = ({ file }: { file: MarimoFile }) => {
|
|
|
530
585
|
</span>
|
|
531
586
|
<p
|
|
532
587
|
title={file.path}
|
|
533
|
-
className="text-
|
|
588
|
+
className="text-xs text-muted-foreground overflow-hidden whitespace-nowrap text-ellipsis"
|
|
534
589
|
>
|
|
535
590
|
{file.path}
|
|
536
591
|
</p>
|
|
@@ -541,8 +596,8 @@ const MarimoFileComponent = ({ file }: { file: MarimoFile }) => {
|
|
|
541
596
|
<SessionShutdownButton filePath={file.path} />
|
|
542
597
|
</div>
|
|
543
598
|
<ExternalLinkIcon
|
|
544
|
-
size={
|
|
545
|
-
className="group-hover:opacity-100
|
|
599
|
+
size={14}
|
|
600
|
+
className="opacity-40 group-hover:opacity-100"
|
|
546
601
|
/>
|
|
547
602
|
</div>
|
|
548
603
|
{!!file.lastModified && (
|
|
@@ -571,7 +626,8 @@ const SessionShutdownButton: React.FC<{ filePath: string }> = ({
|
|
|
571
626
|
<Button
|
|
572
627
|
size={"icon"}
|
|
573
628
|
variant="outline"
|
|
574
|
-
|
|
629
|
+
aria-label="Shutdown notebook"
|
|
630
|
+
className="border-transparent text-muted-foreground shadow-none hover:border-destructive hover:bg-(--red-1) hover:text-destructive"
|
|
575
631
|
onClick={(e) => {
|
|
576
632
|
e.stopPropagation();
|
|
577
633
|
e.preventDefault();
|
|
@@ -611,23 +667,40 @@ const SessionShutdownButton: React.FC<{ filePath: string }> = ({
|
|
|
611
667
|
);
|
|
612
668
|
};
|
|
613
669
|
|
|
614
|
-
const CreateNewNotebook: React.FC = () => {
|
|
615
|
-
|
|
670
|
+
export const CreateNewNotebook: React.FC = () => {
|
|
671
|
+
// Reusing a `__new__` key reattaches to an old session; rotate it per open
|
|
672
|
+
const [url, setUrl] = useState(newNotebookURL);
|
|
673
|
+
const rotateUrl = () => {
|
|
674
|
+
const next = newNotebookURL();
|
|
675
|
+
setUrl(next);
|
|
676
|
+
return next;
|
|
677
|
+
};
|
|
678
|
+
const rotateDragPayload = (event: React.DragEvent<HTMLAnchorElement>) => {
|
|
679
|
+
// The browser copies the href into the drag payload before this handler
|
|
680
|
+
// runs, so the rotated URL must be written into the payload by hand
|
|
681
|
+
const next = rotateUrl();
|
|
682
|
+
event.dataTransfer.setData("text/uri-list", next);
|
|
683
|
+
event.dataTransfer.setData("text/plain", next);
|
|
684
|
+
};
|
|
616
685
|
return (
|
|
617
|
-
<
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
"
|
|
622
|
-
href={url}
|
|
623
|
-
target="_blank"
|
|
624
|
-
rel="noreferrer"
|
|
686
|
+
<Button
|
|
687
|
+
asChild={true}
|
|
688
|
+
size="sm"
|
|
689
|
+
className="gap-2 rounded-md border-(--brand) bg-(--brand) text-(--brand-foreground) shadow-none hover:bg-(--brand-hover)"
|
|
625
690
|
>
|
|
626
|
-
<
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
691
|
+
<a
|
|
692
|
+
href={url}
|
|
693
|
+
target="_blank"
|
|
694
|
+
rel="noreferrer"
|
|
695
|
+
onClick={rotateUrl}
|
|
696
|
+
onAuxClick={rotateUrl}
|
|
697
|
+
onContextMenu={rotateUrl}
|
|
698
|
+
onDragStart={rotateDragPayload}
|
|
699
|
+
>
|
|
700
|
+
<PlusIcon className="h-4 w-4" />
|
|
701
|
+
New notebook
|
|
702
|
+
</a>
|
|
703
|
+
</Button>
|
|
631
704
|
);
|
|
632
705
|
};
|
|
633
706
|
|
|
@@ -135,9 +135,9 @@ export const ScratchPad: React.FC = () => {
|
|
|
135
135
|
return (
|
|
136
136
|
<div className="absolute inset-0 z-100 bg-background p-3 border-none overflow-auto">
|
|
137
137
|
<div className="overflow-auto flex flex-col gap-3">
|
|
138
|
-
{history.map((item
|
|
138
|
+
{history.map((item) => (
|
|
139
139
|
<div
|
|
140
|
-
key={
|
|
140
|
+
key={item}
|
|
141
141
|
className="border rounded-md hover:shadow-sm cursor-pointer hover:border-input overflow-hidden"
|
|
142
142
|
onClick={() => handleSelectHistoryItem(item)}
|
|
143
143
|
>
|
|
@@ -404,13 +404,15 @@ const SubslideView = ({
|
|
|
404
404
|
if (block.isFragment) {
|
|
405
405
|
const cumulative = cumulativeByBlock.get(i);
|
|
406
406
|
return (
|
|
407
|
-
<Fragment key={
|
|
407
|
+
<Fragment key={block.cells[0].id} as="div">
|
|
408
408
|
{rendered}
|
|
409
409
|
{cumulative && <NotesAside text={cumulative} />}
|
|
410
410
|
</Fragment>
|
|
411
411
|
);
|
|
412
412
|
}
|
|
413
|
-
return
|
|
413
|
+
return (
|
|
414
|
+
<ReactFragment key={block.cells[0].id}>{rendered}</ReactFragment>
|
|
415
|
+
);
|
|
414
416
|
})}
|
|
415
417
|
</div>
|
|
416
418
|
</SlideScrollContainer>
|
|
@@ -117,7 +117,7 @@ export const SlideCellView = ({ cell }: { cell: RuntimeCell }) => {
|
|
|
117
117
|
/>
|
|
118
118
|
<LanguageToggles
|
|
119
119
|
code={cell.code}
|
|
120
|
-
|
|
120
|
+
editorViewRef={editorViewRef}
|
|
121
121
|
currentLanguageAdapter={languageAdapter}
|
|
122
122
|
onAfterToggle={afterToggleLanguage}
|
|
123
123
|
className="flex items-center gap-1"
|
|
@@ -450,6 +450,7 @@ export const SlideSidebar = ({
|
|
|
450
450
|
)}
|
|
451
451
|
<Tooltip content={isConfigOpen ? "Collapse panel" : "Expand panel"}>
|
|
452
452
|
<Button
|
|
453
|
+
aria-label={isConfigOpen ? "Collapse panel" : "Expand panel"}
|
|
453
454
|
variant="ghost"
|
|
454
455
|
size="icon"
|
|
455
456
|
className="h-7 w-7 text-muted-foreground hover:text-foreground"
|
|
@@ -145,11 +145,11 @@ const TraceBlock: React.FC<{
|
|
|
145
145
|
isMostRecentRun: boolean;
|
|
146
146
|
chartPosition: ChartPosition;
|
|
147
147
|
theme: ResolvedTheme;
|
|
148
|
-
}> = ({ run, isMostRecentRun, chartPosition, isExpanded, theme }) => {
|
|
148
|
+
}> = ({ run, isMostRecentRun, chartPosition, isExpanded: expanded, theme }) => {
|
|
149
149
|
const setExpandedRuns = useSetAtom(expandedRunsAtom);
|
|
150
150
|
// We prefer the user's last click, but if they haven't clicked on this run,
|
|
151
151
|
// we expand the most recent run by default, otherwise we collapse it.
|
|
152
|
-
isExpanded =
|
|
152
|
+
const isExpanded = expanded ?? isMostRecentRun;
|
|
153
153
|
|
|
154
154
|
const onToggleExpanded = () => {
|
|
155
155
|
setExpandedRuns((prev) => {
|
|
@@ -28,7 +28,7 @@ AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName;
|
|
|
28
28
|
const AlertDialogOverlay = React.forwardRef<
|
|
29
29
|
React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
|
|
30
30
|
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
|
|
31
|
-
>(({ className, children, ...props }, ref) => (
|
|
31
|
+
>(({ className, children: _children, ...props }, ref) => (
|
|
32
32
|
<AlertDialogPrimitive.Overlay
|
|
33
33
|
className={cn(
|
|
34
34
|
"fixed inset-0 z-50 bg-background/80 backdrop-blur-xs transition-opacity animate-in fade-in",
|
|
@@ -98,8 +98,12 @@ export class DatasourceContextProvider extends AIContextProvider<DatasourceConte
|
|
|
98
98
|
public formatContext(item: DatasourceContextItem): string {
|
|
99
99
|
const data = item.data;
|
|
100
100
|
// Remove certain fields that are not needed in the context
|
|
101
|
-
const {
|
|
102
|
-
|
|
101
|
+
const {
|
|
102
|
+
name,
|
|
103
|
+
display_name: _displayName,
|
|
104
|
+
source: _source,
|
|
105
|
+
...filteredDatasource
|
|
106
|
+
} = data.connection;
|
|
103
107
|
|
|
104
108
|
let datasource = filteredDatasource;
|
|
105
109
|
const isInternalEngine = INTERNAL_SQL_ENGINES.has(name as ConnectionName);
|
|
@@ -20,9 +20,11 @@ export type StatusValue = "success" | "error" | "warning";
|
|
|
20
20
|
* @example
|
|
21
21
|
* throw new ToolExecutionError(
|
|
22
22
|
* "Failed to fetch data",
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* {
|
|
24
|
+
* code: "FETCH_ERROR",
|
|
25
|
+
* isRetryable: true,
|
|
26
|
+
* suggestedFix: "Check your network connection",
|
|
27
|
+
* }
|
|
26
28
|
* );
|
|
27
29
|
*/
|
|
28
30
|
export class ToolExecutionError extends Error {
|
|
@@ -33,10 +35,17 @@ export class ToolExecutionError extends Error {
|
|
|
33
35
|
|
|
34
36
|
public constructor(
|
|
35
37
|
message: string,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
{
|
|
39
|
+
code = "TOOL_ERROR",
|
|
40
|
+
isRetryable = false,
|
|
41
|
+
suggestedFix,
|
|
42
|
+
meta,
|
|
43
|
+
}: {
|
|
44
|
+
code?: string;
|
|
45
|
+
isRetryable?: boolean;
|
|
46
|
+
suggestedFix?: string;
|
|
47
|
+
meta?: Record<string, unknown>;
|
|
48
|
+
} = {},
|
|
40
49
|
) {
|
|
41
50
|
super(message);
|
|
42
51
|
this.name = "ToolExecutionError";
|