@marimo-team/islands 0.25.3-dev250 → 0.25.3-dev251
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedDataExplorerComponent-BBihxHrr.js → ConnectedDataExplorerComponent-DGOAQFtf.js} +11 -11
- package/dist/{ErrorBoundary-Ks8L_DFj.js → ErrorBoundary-CZ19wGWT.js} +7 -7
- package/dist/{abnfDiagram-VCTEODGH-DBcJVxYP.js → abnfDiagram-VCTEODGH-DzrZZXRD.js} +2 -2
- package/dist/{any-language-editor-jGaR0EAo.js → any-language-editor-Be7dA2VK.js} +3 -3
- package/dist/{architectureDiagram-5GKGNRK7-BcHZXF4S.js → architectureDiagram-5GKGNRK7-iF_snyFL.js} +1 -1
- package/dist/{button-B6RjDKJx.js → button-0-RqY1DW.js} +2 -1
- package/dist/{capabilities-CkVzWJEX.js → capabilities-B6yy_CBN.js} +1 -1
- package/dist/{chat-ui-DgaVxFrc.js → chat-ui-zbfp80GW.js} +1547 -1482
- package/dist/{check-Z_vtI3OL.js → check-CSvxZk5I.js} +1 -1
- package/dist/{chunk-IMKFNOWR-CTZlwBAA.js → chunk-IMKFNOWR-B7xytD4B.js} +1 -1
- package/dist/{chunk-SHT3W25Y-53g_RZHm.js → chunk-SHT3W25Y-I8ZFP5L1.js} +1 -1
- package/dist/{chunk-SVP7TREG-P6abNGV_.js → chunk-SVP7TREG-Di-uAPdT.js} +1 -1
- package/dist/{chunk-TICWLB2K-BTJJqkyF.js → chunk-TICWLB2K-BFpUy0ud.js} +1 -1
- package/dist/{classDiagram-ZZMXUADV-BUGqOrTm.js → classDiagram-ZZMXUADV-Cqm4JGpx.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-CXpQvO-s.js → classDiagram-v2-VYDZK3BY-DFHRJpN3.js} +2 -2
- package/dist/{code-visibility-CCCqFZYh.js → code-visibility-D2D_sL1T.js} +4 -4
- package/dist/{common-JXDK9IjO.js → common-DSIM5DHJ.js} +262 -262
- package/dist/{config-DbjzjwxX.js → config-mwEjAmvP.js} +2 -2
- package/dist/{copy-icon-CG57cxwb.js → copy-icon-DD8bdw4L.js} +3 -3
- package/dist/{createReducer-DePYJ0F3.js → createReducer-Bx81cw8_.js} +1 -1
- package/dist/{cynefinDiagram-5FMLGOSQ-DOcnl8wW.js → cynefinDiagram-5FMLGOSQ-cuGOeTBC.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-CuHR9QfG.js → dagre-GXQ25YYZ-DJ76aC4k.js} +1 -1
- package/dist/{data-grid-overlay-editor-QAJSeJpH.js → data-grid-overlay-editor-ByfOIO6H.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-BPiG4kso.js → diagram-S7CK7UJ4-DLLc0sw7.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-_piBOvOC.js → diagram-UQ7AKVKN-Tz_d6qmk.js} +1 -1
- package/dist/{diagram-VX7I27RA-DCzVeJ8M.js → diagram-VX7I27RA-D7SzPrDN.js} +1 -1
- package/dist/{diagram-Z3DM3KII-D64CF1jQ.js → diagram-Z3DM3KII-qr37XV58.js} +1 -1
- package/dist/{dialog-DsZ49mmU.js → dialog-BHYPX87J.js} +3 -3
- package/dist/{dropdown-menu-BRiE7Vnp.js → dropdown-menu-Blu7V6Mk.js} +6 -6
- package/dist/{ebnfDiagram-PWID7BFC-BapQPML-.js → ebnfDiagram-PWID7BFC-BKOQb4J0.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-CNQvC2_Q.js → erDiagram-RLTQ6QDP-CM15Vq68.js} +1 -1
- package/dist/{error-banner-IsonnvA0.js → error-banner-DbRFOd2O.js} +2 -2
- package/dist/{error-entries-CRPfxMqm.js → error-entries-BuIE3Ius.js} +9 -9
- package/dist/{feedback-button-Bg7zGcid.js → feedback-button-VT03EJ1h.js} +7 -7
- package/dist/{flowDiagram-HODETNUW-BBt6S6oe.js → flowDiagram-HODETNUW-Dt3N5yFT.js} +2 -2
- package/dist/{formats-BK4VefeF.js → formats-gGospKWJ.js} +2 -2
- package/dist/{glide-data-editor-BuFe7QfV.js → glide-data-editor-C94G7kD7.js} +10 -10
- package/dist/{glide-utils-CQddGpa-.js → glide-utils-qbkRZpEy.js} +3 -3
- package/dist/{globals-8EK96XwF.js → globals-D7JZ5hgJ.js} +2 -2
- package/dist/{html-to-image-Gx4q3ZoD.js → html-to-image-BXrAd5q8.js} +460 -455
- package/dist/{infoDiagram-27XIBGKW-Hd8Ifz82.js → infoDiagram-27XIBGKW-C7axJMCl.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-CP7hnHWx.js → ishikawaDiagram-5VMMS53U-CdC9Eur7.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-CX91sa9b.js → kanban-definition-UXKFOSKX-BHnMIgD7.js} +1 -1
- package/dist/{loader-BisjOLiW.js → loader-BVEtQ4F3.js} +1 -1
- package/dist/main.js +236 -236
- package/dist/{mermaid-Djb3Ni9t.js → mermaid-DFYN_PXd.js} +35 -35
- package/dist/{mindmap-definition-YA3MSWOX-DgCNo07O.js → mindmap-definition-YA3MSWOX-BagHoCGU.js} +1 -1
- package/dist/{number-overlay-editor-BDJF1c8h.js → number-overlay-editor-CdcscCHp.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-SGJhnIKo.js → pegDiagram-XKGWAZYB-8IIZczip.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-1stXIWCQ.js → pieDiagram-E7YTZNPT-CE6dKBIr.js} +1 -1
- package/dist/{process-output-D2ISIyIs.js → process-output-D2ZjxrHe.js} +4 -4
- package/dist/{railroadDiagram-O6MQD6OU-DY1mojzB.js → railroadDiagram-O6MQD6OU-CkexPq3b.js} +2 -2
- package/dist/{requirementDiagram-BXWQKSXE-gHzhUp0D.js → requirementDiagram-BXWQKSXE-B0-OkuAe.js} +1 -1
- package/dist/{reveal-component-B_hNJfj-.js → reveal-component-Cr9euMM2.js} +8 -8
- package/dist/{select-BSxlITBo.js → select-CcidPqlM.js} +5 -5
- package/dist/{sequenceDiagram-WJ2MYXX4-rjPtD9fB.js → sequenceDiagram-WJ2MYXX4-Dxysg8DX.js} +1 -1
- package/dist/{spec-Dq8RNplp.js → spec-ZwfZcgsm.js} +4 -4
- package/dist/{stateDiagram-D77RDMKH-DMNxjUxV.js → stateDiagram-D77RDMKH-DTEN3-OJ.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-CumAaqGo.js → stateDiagram-v2-MP3YSRHH-vktk3Xc5.js} +2 -2
- package/dist/{strings-BGW-fXVJ.js → strings-BYJNyKmg.js} +3 -3
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-BU14_Tej.js → swimlanes-42K2YHIH-Cjveh9OM.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-CieAnPqJ.js → swimlanesDiagram-VR7AAH4N-Bdr7Ev_2.js} +2 -2
- package/dist/{swiper-component-Dir1o8ml.js → swiper-component-Dvj-goaD.js} +2 -2
- package/dist/{timeline-definition-24CTP7MA-CrVj4E1K.js → timeline-definition-24CTP7MA-KIuDcefn.js} +1 -1
- package/dist/{toast-BWIPi3aF.js → toast-CkB5Jq9K.js} +4 -4
- package/dist/{tooltip-C3UnvsRe.js → tooltip-Bzl4k00l.js} +2 -2
- package/dist/{use-restore-focus-BWO0z1lo.js → use-restore-focus-CmflVLWJ.js} +1 -1
- package/dist/{useDateFormatter-ChB4eyim.js → useDateFormatter-CYo5fm8s.js} +2 -2
- package/dist/{useIframeCapabilities-cMNQ80CK.js → useIframeCapabilities-BIolGsF1.js} +1 -1
- package/dist/{useLifecycle-BquH9ET-.js → useLifecycle-GNgvNwI-.js} +2 -2
- package/dist/{useTheme-DgOLVISn.js → useTheme-BZ2GGLgm.js} +141 -139
- package/dist/{vega-component-Bwg_Kuh-.js → vega-component-DOtem7Hf.js} +7 -7
- package/dist/{vennDiagram-4TSXK5OY-ZLxQ8yhm.js → vennDiagram-4TSXK5OY-DrIOUHfb.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-D88pcLY1.js → wardleyDiagram-VM6X3IG4-CJNjf4OH.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-_13d4g8g.js → xychartDiagram-S5SC5T6Z-DEshFho-.js} +1 -1
- package/package.json +1 -1
- package/src/__tests__/fixtures/pair-config.ts +1 -1
- package/src/components/app-config/__tests__/state.test.tsx +50 -0
- package/src/components/app-config/ai-config.tsx +1 -1
- package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
- package/src/components/chat/__tests__/chat-display.test.tsx +125 -0
- package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
- package/src/components/chat/__tests__/chat-utils.test.ts +51 -1
- package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
- package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
- package/src/components/chat/acp/agent-panel.tsx +4 -3
- package/src/components/chat/acp/blocks.tsx +10 -10
- package/src/components/chat/acp/common.tsx +4 -5
- package/src/components/chat/acp/model-selector.tsx +1 -1
- package/src/components/chat/capabilities-popover.tsx +1 -6
- package/src/components/chat/chat-components.tsx +7 -4
- package/src/components/chat/chat-display.tsx +51 -6
- package/src/components/chat/chat-history-popover.tsx +6 -1
- package/src/components/chat/chat-markdown.tsx +15 -0
- package/src/components/chat/chat-panel.tsx +105 -119
- package/src/components/chat/chat-typography.css +108 -0
- package/src/components/chat/chat-utils.ts +8 -3
- package/src/components/chat/notebook-access-selector.tsx +1 -1
- package/src/components/chat/reasoning-accordion.tsx +3 -3
- package/src/components/chat/tool-call/tool-activity-group.tsx +49 -0
- package/src/components/chat/tool-call/tool-history-row.tsx +3 -30
- package/src/components/chat/tool-call/tool-result.tsx +1 -1
- package/src/components/chat/use-chat-generation.ts +19 -0
- package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +18 -37
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +5 -8
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +5 -19
- package/src/components/editor/actions/pair-with-agent-commands.ts +0 -1
- package/src/components/editor/actions/pair-with-agent-modal.tsx +7 -11
- package/src/components/editor/actions/pair-with-agent.tsx +3 -31
- package/src/components/editor/actions/useCellActionButton.tsx +1 -1
- package/src/components/editor/ai/ai-completion-editor.tsx +1 -1
- package/src/components/editor/ai/prompt-input.tsx +189 -0
- package/src/components/editor/cell/StagedAICell.tsx +3 -3
- package/src/components/editor/cell/code/cell-editor.tsx +14 -1
- package/src/components/editor/chrome/panels/panel-header.tsx +13 -0
- package/src/components/editor/chrome/types.ts +1 -1
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +53 -45
- package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +89 -72
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +5 -8
- package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
- package/src/components/editor/renderers/__tests__/add-cell-buttons.test.tsx +18 -0
- package/src/components/editor/renderers/cell-array.tsx +10 -67
- package/src/components/markdown/markdown-renderer.tsx +35 -20
- package/src/components/mcp/mcp-status-indicator.tsx +18 -14
- package/src/core/ai/__tests__/staged-cells.test.ts +1 -467
- package/src/core/ai/context/context.ts +2 -0
- package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
- package/src/core/ai/context/providers/cell.ts +54 -0
- package/src/core/ai/staged-cells.ts +4 -280
- package/src/core/ai/state.ts +3 -0
- package/src/core/codemirror/__tests__/setup.test.ts +32 -0
- package/src/core/codemirror/cells/state.ts +1 -0
- package/src/core/codemirror/cm.ts +5 -1
- package/src/core/codemirror/config/types.ts +1 -1
- package/src/core/codemirror/language/languages/python.ts +3 -3
- package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +16 -0
- package/src/core/codemirror/placeholder/extensions.ts +57 -19
- package/src/core/hotkeys/hotkeys.ts +2 -1
- package/src/core/notebook/document/__tests__/codemirror.test.ts +1 -0
- package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +1 -1
- package/src/plugins/impl/chat/chat-ui.tsx +1 -1
- package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
- package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
- package/src/components/editor/ai/staged-cell-submission.ts +0 -46
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -66
|
@@ -4,6 +4,7 @@ import React, {
|
|
|
4
4
|
Suspense,
|
|
5
5
|
useEffect,
|
|
6
6
|
useMemo,
|
|
7
|
+
useState,
|
|
7
8
|
} from "react";
|
|
8
9
|
import {
|
|
9
10
|
type ImperativePanelHandle,
|
|
@@ -33,6 +34,7 @@ import { cn } from "@/utils/cn";
|
|
|
33
34
|
import { ErrorBoundary } from "../../boundary/ErrorBoundary";
|
|
34
35
|
import { raf2 } from "../../navigation/focus-utils";
|
|
35
36
|
import { ContextAwarePanel } from "../panels/context-aware-panel/context-aware-panel";
|
|
37
|
+
import { PanelHeaderActionsContext } from "../panels/panel-header";
|
|
36
38
|
import { PanelSectionProvider } from "../panels/panel-context";
|
|
37
39
|
import { RuntimeStatusToggle } from "../panels/runtime-status-toggle";
|
|
38
40
|
import { useTheme } from "@/theme/useTheme";
|
|
@@ -327,99 +329,114 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
327
329
|
cache: <LazyCachePanel.Component />,
|
|
328
330
|
};
|
|
329
331
|
|
|
332
|
+
const [headerActionsTarget, setHeaderActionsTarget] =
|
|
333
|
+
useState<HTMLDivElement | null>(null);
|
|
334
|
+
|
|
330
335
|
const helpPaneBody = (
|
|
331
336
|
<ErrorBoundary>
|
|
332
337
|
<PanelSectionProvider value="sidebar">
|
|
333
|
-
<
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
338
|
+
<PanelHeaderActionsContext.Provider
|
|
339
|
+
value={
|
|
340
|
+
selectedPanel === "ai" && (!agentsEnabled || aiPanelTab === "chat")
|
|
341
|
+
? headerActionsTarget
|
|
342
|
+
: null
|
|
343
|
+
}
|
|
344
|
+
>
|
|
345
|
+
<div className="@container flex flex-col h-full flex-1 overflow-hidden mr-[-4px]">
|
|
346
|
+
<div className="p-3 border-b flex shrink-0 flex-wrap justify-between items-center gap-y-1">
|
|
347
|
+
{selectedPanel === "dependencies" ? (
|
|
348
|
+
<div className="flex items-center justify-between flex-1">
|
|
349
|
+
<span className="text-sm text-(--slate-11) uppercase tracking-wide font-semibold">
|
|
350
|
+
Dependencies
|
|
351
|
+
</span>
|
|
352
|
+
<Tabs
|
|
353
|
+
value={dependencyPanelTab}
|
|
354
|
+
onValueChange={(value) => {
|
|
355
|
+
if (value === "minimap" || value === "graph") {
|
|
356
|
+
setDependencyPanelTab(value);
|
|
357
|
+
}
|
|
358
|
+
}}
|
|
359
|
+
>
|
|
360
|
+
<TabsList>
|
|
361
|
+
<TabsTrigger
|
|
362
|
+
value="minimap"
|
|
363
|
+
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
364
|
+
>
|
|
365
|
+
Minimap
|
|
366
|
+
</TabsTrigger>
|
|
367
|
+
<TabsTrigger
|
|
368
|
+
value="graph"
|
|
369
|
+
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
370
|
+
>
|
|
371
|
+
Graph
|
|
372
|
+
</TabsTrigger>
|
|
373
|
+
</TabsList>
|
|
374
|
+
</Tabs>
|
|
375
|
+
</div>
|
|
376
|
+
) : selectedPanel === "ai" && agentsEnabled ? (
|
|
340
377
|
<Tabs
|
|
341
|
-
value={
|
|
378
|
+
value={aiPanelTab}
|
|
342
379
|
onValueChange={(value) => {
|
|
343
|
-
if (value === "
|
|
344
|
-
|
|
380
|
+
if (value === "chat" || value === "agents") {
|
|
381
|
+
setAiPanelTab(value);
|
|
345
382
|
}
|
|
346
383
|
}}
|
|
347
384
|
>
|
|
348
385
|
<TabsList>
|
|
349
386
|
<TabsTrigger
|
|
350
|
-
value="
|
|
387
|
+
value="chat"
|
|
351
388
|
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
352
389
|
>
|
|
353
|
-
|
|
390
|
+
Chat
|
|
354
391
|
</TabsTrigger>
|
|
355
392
|
<TabsTrigger
|
|
356
|
-
value="
|
|
393
|
+
value="agents"
|
|
357
394
|
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
358
395
|
>
|
|
359
|
-
|
|
396
|
+
Agents
|
|
360
397
|
</TabsTrigger>
|
|
361
398
|
</TabsList>
|
|
362
399
|
</Tabs>
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
400
|
+
) : (
|
|
401
|
+
<span className="text-sm text-(--slate-11) uppercase tracking-wide font-semibold flex-1">
|
|
402
|
+
{selectedPanel === "ai" ? "Chat" : selectedPanel}
|
|
403
|
+
</span>
|
|
404
|
+
)}
|
|
405
|
+
<div
|
|
406
|
+
ref={setHeaderActionsTarget}
|
|
407
|
+
className="sidebar-panel-actions ml-auto min-w-0"
|
|
408
|
+
/>
|
|
409
|
+
{selectedPanel === "packages" && (
|
|
410
|
+
<RuntimeStatusToggle section="sidebar" />
|
|
411
|
+
)}
|
|
412
|
+
<Button
|
|
413
|
+
data-testid="close-helper-pane"
|
|
414
|
+
className="m-0"
|
|
415
|
+
size="xs"
|
|
416
|
+
variant="text"
|
|
417
|
+
onClick={() => setIsSidebarOpen(false)}
|
|
372
418
|
>
|
|
373
|
-
<
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
419
|
+
<XIcon className="w-4 h-4" />
|
|
420
|
+
</Button>
|
|
421
|
+
</div>
|
|
422
|
+
<Suspense>
|
|
423
|
+
<TooltipProvider>
|
|
424
|
+
{Object.entries(SIDEBAR_PANELS).map(([key, Panel]) => (
|
|
425
|
+
<LazyActivity
|
|
426
|
+
key={key}
|
|
427
|
+
mode={
|
|
428
|
+
isSidebarOpen && selectedPanel === key
|
|
429
|
+
? "visible"
|
|
430
|
+
: "hidden"
|
|
431
|
+
}
|
|
383
432
|
>
|
|
384
|
-
|
|
385
|
-
</
|
|
386
|
-
|
|
387
|
-
</
|
|
388
|
-
|
|
389
|
-
<span className="text-sm text-(--slate-11) uppercase tracking-wide font-semibold flex-1">
|
|
390
|
-
{selectedPanel}
|
|
391
|
-
</span>
|
|
392
|
-
)}
|
|
393
|
-
{selectedPanel === "packages" && (
|
|
394
|
-
<RuntimeStatusToggle section="sidebar" />
|
|
395
|
-
)}
|
|
396
|
-
<Button
|
|
397
|
-
data-testid="close-helper-pane"
|
|
398
|
-
className="m-0"
|
|
399
|
-
size="xs"
|
|
400
|
-
variant="text"
|
|
401
|
-
onClick={() => setIsSidebarOpen(false)}
|
|
402
|
-
>
|
|
403
|
-
<XIcon className="w-4 h-4" />
|
|
404
|
-
</Button>
|
|
433
|
+
{Panel}
|
|
434
|
+
</LazyActivity>
|
|
435
|
+
))}
|
|
436
|
+
</TooltipProvider>
|
|
437
|
+
</Suspense>
|
|
405
438
|
</div>
|
|
406
|
-
|
|
407
|
-
<TooltipProvider>
|
|
408
|
-
{Object.entries(SIDEBAR_PANELS).map(([key, Panel]) => (
|
|
409
|
-
<LazyActivity
|
|
410
|
-
key={key}
|
|
411
|
-
mode={
|
|
412
|
-
isSidebarOpen && selectedPanel === key
|
|
413
|
-
? "visible"
|
|
414
|
-
: "hidden"
|
|
415
|
-
}
|
|
416
|
-
>
|
|
417
|
-
{Panel}
|
|
418
|
-
</LazyActivity>
|
|
419
|
-
))}
|
|
420
|
-
</TooltipProvider>
|
|
421
|
-
</Suspense>
|
|
422
|
-
</div>
|
|
439
|
+
</PanelHeaderActionsContext.Provider>
|
|
423
440
|
</PanelSectionProvider>
|
|
424
441
|
</ErrorBoundary>
|
|
425
442
|
);
|
|
@@ -562,7 +579,7 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
562
579
|
{/* Panel content */}
|
|
563
580
|
<Suspense fallback={<div />}>
|
|
564
581
|
<PanelSectionProvider value="developer-panel">
|
|
565
|
-
<div className="flex-1 overflow-hidden">
|
|
582
|
+
<div className="flex flex-col flex-1 min-h-0 overflow-hidden">
|
|
566
583
|
{Object.entries(DEVELOPER_PANELS).map(([key, Panel]) => (
|
|
567
584
|
<LazyActivity
|
|
568
585
|
key={key}
|
|
@@ -4,11 +4,8 @@ import { useAtomValue, useStore } from "jotai";
|
|
|
4
4
|
import { ChevronDown, ChevronUp, SparklesIcon } from "lucide-react";
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
stagedGenerationInProgressAtom,
|
|
10
|
-
useStagedCells,
|
|
11
|
-
} from "@/core/ai/staged-cells";
|
|
7
|
+
import { stagedAICellsAtom, useStagedCells } from "@/core/ai/staged-cells";
|
|
8
|
+
import { chatGenerationInProgressAtom } from "@/core/ai/state";
|
|
12
9
|
import type { CellId } from "@/core/cells/ids";
|
|
13
10
|
import { getNextIndex } from "@/utils/arrays";
|
|
14
11
|
import { cn } from "@/utils/cn";
|
|
@@ -24,7 +21,7 @@ export const PendingAICells: React.FC = () => {
|
|
|
24
21
|
const [currentIndex, setCurrentIndex] = useState<number | null>(null);
|
|
25
22
|
|
|
26
23
|
const stagedAiCells = useAtomValue(stagedAICellsAtom);
|
|
27
|
-
const
|
|
24
|
+
const isGenerating = useAtomValue(chatGenerationInProgressAtom);
|
|
28
25
|
const listStagedCells = [...stagedAiCells.keys()];
|
|
29
26
|
const store = useStore();
|
|
30
27
|
const { deleteStagedCell, removeStagedCell } = useStagedCells(store);
|
|
@@ -108,7 +105,7 @@ export const PendingAICells: React.FC = () => {
|
|
|
108
105
|
<AcceptCompletionButton
|
|
109
106
|
multipleCompletions={true}
|
|
110
107
|
onAccept={acceptAllCompletions}
|
|
111
|
-
isLoading={
|
|
108
|
+
isLoading={isGenerating}
|
|
112
109
|
label="Keep all"
|
|
113
110
|
size="xs"
|
|
114
111
|
buttonStyles="h-6.5"
|
|
@@ -118,7 +115,7 @@ export const PendingAICells: React.FC = () => {
|
|
|
118
115
|
<RejectCompletionButton
|
|
119
116
|
multipleCompletions={true}
|
|
120
117
|
onDecline={rejectAllCompletions}
|
|
121
|
-
disabled={
|
|
118
|
+
disabled={isGenerating}
|
|
122
119
|
size="xs"
|
|
123
120
|
label="Discard all"
|
|
124
121
|
className="h-6.5"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { useSetAtom, useStore } from "jotai";
|
|
4
|
+
import useEvent from "react-use-event-hook";
|
|
5
|
+
import { useAIConfigActions } from "@/core/ai/config";
|
|
6
|
+
import { CellContextProvider } from "@/core/ai/context/providers/cell";
|
|
7
|
+
import { pendingAiPromptAtom } from "@/core/ai/state";
|
|
8
|
+
import type { CellId } from "@/core/cells/ids";
|
|
9
|
+
import { aiAtom } from "@/core/config/config";
|
|
10
|
+
import { Logger } from "@/utils/Logger";
|
|
11
|
+
import { useChromeActions } from "../state";
|
|
12
|
+
import { aiPanelTabAtom } from "./useAiPanel";
|
|
13
|
+
|
|
14
|
+
export function useAskAiAboutCell() {
|
|
15
|
+
const store = useStore();
|
|
16
|
+
const { openApplication } = useChromeActions();
|
|
17
|
+
const setAiPanelTab = useSetAtom(aiPanelTabAtom);
|
|
18
|
+
const { saveModeChange } = useAIConfigActions();
|
|
19
|
+
const setPendingPrompt = useSetAtom(pendingAiPromptAtom);
|
|
20
|
+
|
|
21
|
+
return useEvent(async (cellId: CellId) => {
|
|
22
|
+
const mode = store.get(aiAtom)?.mode;
|
|
23
|
+
if (mode !== "agent" && mode !== "code_mode") {
|
|
24
|
+
await saveModeChange("agent").catch(() =>
|
|
25
|
+
Logger.error("Failed to save mode change"),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
setPendingPrompt({
|
|
29
|
+
prompt: `@${new CellContextProvider(store).asURI(cellId)} `,
|
|
30
|
+
submit: false,
|
|
31
|
+
append: true,
|
|
32
|
+
});
|
|
33
|
+
setAiPanelTab("chat");
|
|
34
|
+
openApplication("ai");
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { render, screen } from "@testing-library/react";
|
|
4
|
+
import { createStore, Provider } from "jotai";
|
|
5
|
+
import { expect, it } from "vitest";
|
|
6
|
+
import type { CellColumnId } from "@/core/cells/layout";
|
|
7
|
+
import { AddCellButtons } from "../cell-array";
|
|
8
|
+
|
|
9
|
+
it("offers only cell languages in the add-cell tray", () => {
|
|
10
|
+
render(
|
|
11
|
+
<Provider store={createStore()}>
|
|
12
|
+
<AddCellButtons columnId={"column-1" as CellColumnId} />
|
|
13
|
+
</Provider>,
|
|
14
|
+
);
|
|
15
|
+
expect(
|
|
16
|
+
screen.getAllByRole("button").map((button) => button.textContent),
|
|
17
|
+
).toEqual(["Python", "Markdown", "SQL"]);
|
|
18
|
+
});
|
|
@@ -6,27 +6,18 @@ import {
|
|
|
6
6
|
verticalListSortingStrategy,
|
|
7
7
|
} from "@dnd-kit/sortable";
|
|
8
8
|
import { useAtomValue } from "jotai";
|
|
9
|
-
import {
|
|
10
|
-
DatabaseIcon,
|
|
11
|
-
SparklesIcon,
|
|
12
|
-
SquareCodeIcon,
|
|
13
|
-
SquareMIcon,
|
|
14
|
-
} from "lucide-react";
|
|
9
|
+
import { DatabaseIcon, SquareCodeIcon, SquareMIcon } from "lucide-react";
|
|
15
10
|
import { useEffect } from "react";
|
|
16
|
-
import { useOpenSettingsToTab } from "@/components/app-config/state";
|
|
17
11
|
import { StartupLogsAlert } from "@/components/editor/alerts/startup-logs-alert";
|
|
18
12
|
import { Cell } from "@/components/editor/notebook-cell";
|
|
19
13
|
import { PackageAlert } from "@/components/editor/package-alert";
|
|
20
14
|
import { SortableCellsProvider } from "@/components/sort/SortableCellsProvider";
|
|
21
15
|
import { Button } from "@/components/ui/button";
|
|
22
|
-
import { Tooltip } from "@/components/ui/tooltip";
|
|
23
16
|
import { maybeAddMarimoImport } from "@/core/cells/add-missing-import";
|
|
24
17
|
import { SETUP_CELL_ID } from "@/core/cells/ids";
|
|
25
18
|
import { LanguageAdapters } from "@/core/codemirror/language/LanguageAdapters";
|
|
26
19
|
import { MARKDOWN_INITIAL_HIDE_CODE } from "@/core/codemirror/language/languages/markdown";
|
|
27
|
-
import { aiEnabledAtom, aiFeaturesEnabledAtom } from "@/core/config/config";
|
|
28
20
|
import { canInteractWithAppAtom } from "@/core/network/connection";
|
|
29
|
-
import { useBoolean } from "@/hooks/useBoolean";
|
|
30
21
|
import { cn } from "@/utils/cn";
|
|
31
22
|
import { Functions } from "@/utils/functions";
|
|
32
23
|
import { type CellColumnId, findColumn, useLayout } from "@/core/cells/layout";
|
|
@@ -38,7 +29,6 @@ import type { AppConfig, UserConfig } from "../../../core/config/config-schema";
|
|
|
38
29
|
import type { AppMode } from "../../../core/mode";
|
|
39
30
|
import { useHotkey } from "../../../hooks/useHotkey";
|
|
40
31
|
import { type Theme, useTheme } from "../../../theme/useTheme";
|
|
41
|
-
import { AddCellWithAI } from "../ai/add-cell-with-ai";
|
|
42
32
|
import { NotStartedConnectionAlert } from "../alerts/connecting-alert";
|
|
43
33
|
import { FloatingOutline } from "../chrome/panels/outline/floating-outline";
|
|
44
34
|
import { useChromeActions } from "../chrome/state";
|
|
@@ -259,29 +249,26 @@ const CellColumn: React.FC<{
|
|
|
259
249
|
);
|
|
260
250
|
};
|
|
261
251
|
|
|
262
|
-
const AddCellButtons: React.FC<{
|
|
252
|
+
export const AddCellButtons: React.FC<{
|
|
263
253
|
columnId: CellColumnId;
|
|
264
254
|
className?: string;
|
|
265
255
|
}> = ({ columnId, className }) => {
|
|
266
256
|
const { createCell } = useCellActions();
|
|
267
|
-
const [isAiButtonOpen, isAiButtonOpenActions] = useBoolean(false);
|
|
268
|
-
const aiEnabled = useAtomValue(aiEnabledAtom);
|
|
269
|
-
const aiFeaturesEnabled = useAtomValue(aiFeaturesEnabledAtom);
|
|
270
257
|
const canInteractWithApp = useAtomValue(canInteractWithAppAtom);
|
|
271
|
-
const { handleClick } = useOpenSettingsToTab();
|
|
272
258
|
|
|
273
259
|
const buttonClass = cn(
|
|
274
260
|
"mb-0 rounded-none sm:px-4 md:px-5 lg:px-8 tracking-wide no-wrap whitespace-nowrap",
|
|
275
261
|
"font-semibold opacity-70 hover:opacity-90 uppercase text-xs",
|
|
276
262
|
);
|
|
277
263
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
264
|
+
return (
|
|
265
|
+
<div className="flex justify-center mt-4 pt-6 pb-32 group gap-4 w-full print:hidden">
|
|
266
|
+
<div
|
|
267
|
+
className={cn(
|
|
268
|
+
"border border-border rounded transition-all duration-200 overflow-hidden divide-x divide-border flex w-fit shadow-sm-solid-shade",
|
|
269
|
+
className,
|
|
270
|
+
)}
|
|
271
|
+
>
|
|
285
272
|
<Button
|
|
286
273
|
className={buttonClass}
|
|
287
274
|
variant="text"
|
|
@@ -327,50 +314,6 @@ const AddCellButtons: React.FC<{
|
|
|
327
314
|
<DatabaseIcon className="mr-2 size-4 shrink-0" />
|
|
328
315
|
SQL
|
|
329
316
|
</Button>
|
|
330
|
-
{aiEnabled && (
|
|
331
|
-
<Tooltip
|
|
332
|
-
content={
|
|
333
|
-
aiFeaturesEnabled ? null : (
|
|
334
|
-
<span>AI provider not found or Edit model not selected</span>
|
|
335
|
-
)
|
|
336
|
-
}
|
|
337
|
-
delayDuration={100}
|
|
338
|
-
asChild={false}
|
|
339
|
-
>
|
|
340
|
-
<Button
|
|
341
|
-
className={buttonClass}
|
|
342
|
-
variant="text"
|
|
343
|
-
size="sm"
|
|
344
|
-
disabled={!canInteractWithApp}
|
|
345
|
-
onClick={
|
|
346
|
-
aiFeaturesEnabled
|
|
347
|
-
? isAiButtonOpenActions.toggle
|
|
348
|
-
: () => handleClick("ai", "ai-providers")
|
|
349
|
-
}
|
|
350
|
-
>
|
|
351
|
-
<SparklesIcon className="mr-2 size-4 shrink-0" />
|
|
352
|
-
Generate with AI
|
|
353
|
-
</Button>
|
|
354
|
-
</Tooltip>
|
|
355
|
-
)}
|
|
356
|
-
</>
|
|
357
|
-
);
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
return (
|
|
361
|
-
<div className="flex justify-center mt-4 pt-6 pb-32 group gap-4 w-full print:hidden">
|
|
362
|
-
<div
|
|
363
|
-
className={cn(
|
|
364
|
-
"border border-border rounded transition-all duration-200 overflow-hidden divide-x divide-border flex",
|
|
365
|
-
!isAiButtonOpen && "w-fit shadow-sm-solid-shade",
|
|
366
|
-
isAiButtonOpen &&
|
|
367
|
-
"w-full max-w-4xl shadow-md-solid-shade shadow-(color:--blue-3)",
|
|
368
|
-
className,
|
|
369
|
-
// Always show the AI input when it's open
|
|
370
|
-
isAiButtonOpen && "opacity-100",
|
|
371
|
-
)}
|
|
372
|
-
>
|
|
373
|
-
{renderBody()}
|
|
374
317
|
</div>
|
|
375
318
|
</div>
|
|
376
319
|
);
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { EditorView } from "@codemirror/view";
|
|
4
4
|
import { useAtomValue } from "jotai";
|
|
5
|
-
import {
|
|
6
|
-
import { memo, Suspense, useState } from "react";
|
|
5
|
+
import { createContext, memo, Suspense, useContext, useState } from "react";
|
|
7
6
|
import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
|
|
8
7
|
import {
|
|
9
8
|
defaultRehypePlugins,
|
|
@@ -25,6 +24,8 @@ import "./markdown-renderer.css";
|
|
|
25
24
|
|
|
26
25
|
const extensions = [EditorView.lineWrapping];
|
|
27
26
|
|
|
27
|
+
const NotebookInsertionContext = createContext(true);
|
|
28
|
+
|
|
28
29
|
interface CodeBlockProps {
|
|
29
30
|
code: string;
|
|
30
31
|
language: string | undefined;
|
|
@@ -91,13 +92,13 @@ const InsertCodeBlockButton = ({ code, language }: CodeBlockProps) => {
|
|
|
91
92
|
return (
|
|
92
93
|
<Button size="xs" variant="outline" onClick={handleInsertCode}>
|
|
93
94
|
Add to Notebook
|
|
94
|
-
<BetweenHorizontalStartIcon className="ml-2 h-4 w-4" />
|
|
95
95
|
</Button>
|
|
96
96
|
);
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
const CodeBlock = ({ code, language }: CodeBlockProps) => {
|
|
100
100
|
const { theme } = useTheme();
|
|
101
|
+
const allowNotebookInsertion = useContext(NotebookInsertionContext);
|
|
101
102
|
const [value, setValue] = useState(code);
|
|
102
103
|
|
|
103
104
|
if (value !== code) {
|
|
@@ -122,11 +123,13 @@ const CodeBlock = ({ code, language }: CodeBlockProps) => {
|
|
|
122
123
|
onChange={setValue}
|
|
123
124
|
/>
|
|
124
125
|
</Suspense>
|
|
125
|
-
<div className="flex justify-end mt-
|
|
126
|
+
<div className="flex justify-end mt-3 gap-2">
|
|
126
127
|
<CopyButton size="xs" variant="outline" onClick={handleCopyCode}>
|
|
127
128
|
Copy
|
|
128
129
|
</CopyButton>
|
|
129
|
-
|
|
130
|
+
{allowNotebookInsertion && (
|
|
131
|
+
<InsertCodeBlockButton code={value} language={language} />
|
|
132
|
+
)}
|
|
130
133
|
</div>
|
|
131
134
|
</div>
|
|
132
135
|
);
|
|
@@ -174,8 +177,10 @@ const COMPONENTS: Components = {
|
|
|
174
177
|
if (language && typeof children === "string") {
|
|
175
178
|
const code = children.trim();
|
|
176
179
|
return (
|
|
177
|
-
<div>
|
|
178
|
-
<div className="text-xs text-muted-foreground pl-1">
|
|
180
|
+
<div className="my-4">
|
|
181
|
+
<div className="mb-1 text-xs text-muted-foreground pl-1">
|
|
182
|
+
{language}
|
|
183
|
+
</div>
|
|
179
184
|
<CodeBlock code={code} language={language} />
|
|
180
185
|
</div>
|
|
181
186
|
);
|
|
@@ -199,17 +204,27 @@ const useMathPlugin = () => {
|
|
|
199
204
|
return plugins;
|
|
200
205
|
};
|
|
201
206
|
|
|
202
|
-
export const MarkdownRenderer = memo(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
207
|
+
export const MarkdownRenderer = memo(
|
|
208
|
+
({
|
|
209
|
+
content,
|
|
210
|
+
allowNotebookInsertion = true,
|
|
211
|
+
}: {
|
|
212
|
+
content: string;
|
|
213
|
+
allowNotebookInsertion?: boolean;
|
|
214
|
+
}) => {
|
|
215
|
+
const plugins = useMathPlugin();
|
|
216
|
+
return (
|
|
217
|
+
<NotebookInsertionContext.Provider value={allowNotebookInsertion}>
|
|
218
|
+
<Streamdown
|
|
219
|
+
components={COMPONENTS}
|
|
220
|
+
plugins={plugins}
|
|
221
|
+
rehypePlugins={REHYPE_PLUGINS}
|
|
222
|
+
className="mo-markdown-renderer"
|
|
223
|
+
>
|
|
224
|
+
{content}
|
|
225
|
+
</Streamdown>
|
|
226
|
+
</NotebookInsertionContext.Provider>
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
);
|
|
215
230
|
MarkdownRenderer.displayName = "MarkdownRenderer";
|
|
@@ -11,7 +11,7 @@ import { useMCPStatus } from "./hooks";
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* MCP Status indicator component
|
|
14
|
-
* Shows
|
|
14
|
+
* Shows connection details and highlights states that need attention
|
|
15
15
|
*/
|
|
16
16
|
export const MCPStatusIndicator: React.FC = () => {
|
|
17
17
|
const { data: status, refetch, isFetching } = useMCPStatus();
|
|
@@ -41,13 +41,17 @@ export const MCPStatusIndicator: React.FC = () => {
|
|
|
41
41
|
<Popover>
|
|
42
42
|
<Tooltip content="MCP Status">
|
|
43
43
|
<PopoverTrigger asChild={true}>
|
|
44
|
-
<Button
|
|
44
|
+
<Button
|
|
45
|
+
className="chat-control"
|
|
46
|
+
aria-label="MCP status"
|
|
47
|
+
variant="text"
|
|
48
|
+
size="icon"
|
|
49
|
+
>
|
|
45
50
|
<PlugIcon
|
|
46
51
|
className={cn(
|
|
47
|
-
"h-4 w-4",
|
|
48
|
-
status?.status === "
|
|
49
|
-
status?.status === "
|
|
50
|
-
status?.status === "error" && hasServers && "text-red-500",
|
|
52
|
+
"h-4 w-4 text-muted-foreground",
|
|
53
|
+
status?.status === "partial" && "text-(--amber-11)",
|
|
54
|
+
status?.status === "error" && hasServers && "text-destructive",
|
|
51
55
|
)}
|
|
52
56
|
/>
|
|
53
57
|
</Button>
|
|
@@ -79,7 +83,7 @@ export const MCPStatusIndicator: React.FC = () => {
|
|
|
79
83
|
</div>
|
|
80
84
|
)}
|
|
81
85
|
{status.error && (
|
|
82
|
-
<div className="text-xs text-
|
|
86
|
+
<div className="text-xs text-destructive bg-destructive/10 p-2 rounded">
|
|
83
87
|
{status.error}
|
|
84
88
|
</div>
|
|
85
89
|
)}
|
|
@@ -129,13 +133,13 @@ export const McpStatusText: React.FC<{
|
|
|
129
133
|
<span
|
|
130
134
|
className={cn(
|
|
131
135
|
"text-xs font-medium",
|
|
132
|
-
status === "ok" && "text-
|
|
133
|
-
status === "partial" && "text-
|
|
134
|
-
status === "error" && "text-
|
|
135
|
-
status === "failed" && "text-
|
|
136
|
-
status === "disconnected" && "text-
|
|
137
|
-
status === "pending" && "text-
|
|
138
|
-
status === "connected" && "text-
|
|
136
|
+
status === "ok" && "text-muted-foreground",
|
|
137
|
+
status === "partial" && "text-(--amber-11)",
|
|
138
|
+
status === "error" && "text-destructive",
|
|
139
|
+
status === "failed" && "text-destructive",
|
|
140
|
+
status === "disconnected" && "text-muted-foreground",
|
|
141
|
+
status === "pending" && "text-(--amber-11)",
|
|
142
|
+
status === "connected" && "text-muted-foreground",
|
|
139
143
|
)}
|
|
140
144
|
>
|
|
141
145
|
{status}
|