/* Copyright 2026 Marimo. All rights reserved. */ import { CheckIcon, CopyIcon } from "lucide-react"; import React, { useEffect, useState } from "react"; import { useAtomValue } from "jotai"; import { Button } from "@/components/ui/button"; import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { copyToClipboard } from "@/utils/copy"; import { Events } from "@/utils/events"; import { Tooltip } from "@/components/ui/tooltip"; import { asRemoteURL, useRuntimeManager } from "@/core/runtime/config"; import { API } from "@/core/network/api"; import { pairPreviewAtom } from "@/core/config/pair"; import { stableSessionIdAtom } from "@/core/kernel/session"; import { AGENT_LABELS, AGENT_TABS, type AgentTab, type ConnectionInfo, getFileFromURL, getRawPrompt, getTerminalCommand, maskToken, SKILL_INSTALL, TERMINAL_TABS, } from "./pair-with-agent-commands"; function useAuthToken(): string | null { const [token, setToken] = useState(null); useEffect(() => { fetch(asRemoteURL("/auth/token").href, { headers: API.headers(), }) .then((res) => res.ok ? (res.json() as Promise<{ token: string | null }>) : null, ) .then((data) => setToken(data?.token ?? null)) .catch(() => setToken(null)); }, []); return token; } export const PairWithAgentModal: React.FC<{ onClose: () => void; }> = ({ onClose }) => { const [activeTab, setActiveTab] = useState("claude"); const runtimeManager = useRuntimeManager(); const preview = useAtomValue(pairPreviewAtom); const stableSessionId = useAtomValue(stableSessionIdAtom); const commandStep = preview ? 1 : 2; const authToken = useAuthToken(); const hasToken = Boolean(authToken); const connection: ConnectionInfo = { url: runtimeManager.httpURL.toString(), file: preview ? undefined : getFileFromURL(window.location.href), session: preview ? (stableSessionId ?? undefined) : undefined, }; return ( Pair with an agent Use an AI coding agent to pair-program on this notebook.{" "} Learn more about pairing marimo with an agent .
setActiveTab(v as AgentTab)} > {AGENT_TABS.map((tab) => ( {AGENT_LABELS[tab]} ))} {TERMINAL_TABS.map((tab) => ( {!preview && ( )} {hasToken && authToken && ( )} ))} {!preview && ( )}
); }; const Step: React.FC<{ index: number; title: string; hint?: string; children: React.ReactNode; }> = ({ index, title, hint, children }) => (
{index}. {title} {hint && {hint}}
{children}
); const CommandBlock: React.FC<{ command: string; display?: string; multiline?: boolean; copyLabel?: string; }> = ({ command, display, multiline = false, copyLabel = "Copy command" }) => { const [copied, setCopied] = useState(false); const copy = Events.stopPropagation(async (e) => { e.preventDefault(); await copyToClipboard(command); setCopied(true); setTimeout(() => setCopied(false), 2000); }); if (multiline) { return (
          {display ?? command}
        
); } return (
{display ?? command}
); };