"use client"; import { useState, useCallback } from "react"; import { Badge } from "@kandev/ui/badge"; import { Button } from "@kandev/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@kandev/ui/table"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@kandev/ui/card"; import { Separator } from "@kandev/ui/separator"; import { IconTrash, IconTestPipe, IconLoader2, IconCheck, IconX, IconSparkles, } from "@tabler/icons-react"; import { useSprites } from "@/hooks/domains/settings/use-sprites"; import { useAppStore } from "@/components/state-provider"; import { testSpritesConnection, destroySprite, destroyAllSprites, } from "@/lib/api/domains/sprites-api"; import type { SpritesInstance, SpritesTestResult, SpritesTestStep } from "@/lib/types/http-sprites"; export function SpritesConnectionCard({ secretId }: { secretId?: string }) { const { status } = useSprites(secretId); const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState(null); const handleTest = useCallback(async () => { setTesting(true); setTestResult(null); try { const result = await testSpritesConnection(secretId); setTestResult(result); } catch { setTestResult({ success: false, steps: [], total_duration_ms: 0, sprite_name: "", error: "Failed to connect to backend", }); } finally { setTesting(false); } }, [secretId]); return (
Connection Sprites.dev provides ephemeral cloud sandboxes for running agents remotely.
{status?.token_configured ? (

API token is configured. {status.connected ? ` ${status.instance_count} active sprite${status.instance_count !== 1 ? "s" : ""}.` : " Unable to connect."}

) : (

Configure a SPRITES_API_TOKEN environment variable in the executor profile, referencing a secret with your Sprites.dev API token.

)}
{testResult && }
); } function TokenBadge({ configured, connected }: { configured: boolean; connected: boolean }) { if (!configured) { return Not Configured; } if (connected) { return ( Connected ); } return Disconnected; } function TestResultDisplay({ result }: { result: SpritesTestResult }) { return (
{result.success ? ( ) : ( )} {result.success ? "Connection test passed" : "Connection test failed"} ({result.total_duration_ms}ms)
{result.steps.map((step: SpritesTestStep) => ( ))} {result.error && !result.steps.some((s) => s.error) && (

{result.error}

)}
); } function StepRow({ step }: { step: SpritesTestStep }) { return (
{step.success ? ( ) : ( )} {step.name} ({step.duration_ms}ms) {step.error && {step.error}}
); } export function SpritesInstancesCard({ secretId }: { secretId?: string }) { const { instances, loading } = useSprites(secretId); const removeSpritesInstance = useAppStore((state) => state.removeSpritesInstance); const [destroying, setDestroying] = useState(null); const [destroyingAll, setDestroyingAll] = useState(false); const handleDestroy = useCallback( async (name: string) => { setDestroying(name); try { await destroySprite(name, secretId); removeSpritesInstance(name); } finally { setDestroying(null); } }, [secretId, removeSpritesInstance], ); const handleDestroyAll = useCallback(async () => { setDestroyingAll(true); try { await destroyAllSprites(secretId); for (const inst of instances) { removeSpritesInstance(inst.name); } } finally { setDestroyingAll(false); } }, [secretId, instances, removeSpritesInstance]); return (
Running Sprites Active Kandev sprites. Sprites are destroyed when agents stop.
{instances.length > 0 && ( )}
); } function InstancesContent({ loading, instances, destroying, onDestroy, }: { loading: boolean; instances: SpritesInstance[]; destroying: string | null; onDestroy: (name: string) => void; }) { if (loading) { return (
Loading...
); } if (instances.length === 0) { return

No active sprites.

; } return ( Name Health Uptime {instances.map((inst) => ( {inst.name} {formatUptime(inst.uptime_seconds)} ))}
); } function HealthBadge({ status }: { status: string }) { const label = status.charAt(0).toUpperCase() + status.slice(1); switch (status) { case "running": return ( {label} ); case "cold": return ( {label} ); case "starting": return {label}; case "stopped": case "stopping": case "failed": return {label}; default: return {label}; } } function formatUptime(seconds: number): string { if (seconds < 60) return `${seconds}s`; const mins = Math.floor(seconds / 60); if (mins < 60) return `${mins}m`; const hours = Math.floor(mins / 60); const remainMins = mins % 60; return `${hours}h ${remainMins}m`; } export function SpritesSettings() { return (

Sprites.dev

Manage Sprites.dev remote sandbox integration for running agents in isolated cloud environments.

); }