import React, { useState } from "react"; import { motion } from "framer-motion"; import { ArrowLeft, Save, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Toast, ToastContainer } from "@/components/ui/toast"; import { api, type Agent } from "@/lib/api"; import { cn } from "@/lib/utils"; import MDEditor from "@uiw/react-md-editor"; import { AGENT_ICONS, type AgentIconName } from "./CCAgents"; import { AgentSandboxSettings } from "./AgentSandboxSettings"; interface CreateAgentProps { /** * Optional agent to edit (if provided, component is in edit mode) */ agent?: Agent; /** * Callback to go back to the agents list */ onBack: () => void; /** * Callback when agent is created/updated */ onAgentCreated: () => void; /** * Optional className for styling */ className?: string; } /** * CreateAgent component for creating or editing a CC agent * * @example * setView('list')} onAgentCreated={handleCreated} /> */ export const CreateAgent: React.FC = ({ agent, onBack, onAgentCreated, className, }) => { const [name, setName] = useState(agent?.name || ""); const [selectedIcon, setSelectedIcon] = useState((agent?.icon as AgentIconName) || "bot"); const [systemPrompt, setSystemPrompt] = useState(agent?.system_prompt || ""); const [defaultTask, setDefaultTask] = useState(agent?.default_task || ""); const [model, setModel] = useState(agent?.model || "sonnet"); const [sandboxEnabled, setSandboxEnabled] = useState(agent?.sandbox_enabled ?? true); const [enableFileRead, setEnableFileRead] = useState(agent?.enable_file_read ?? true); const [enableFileWrite, setEnableFileWrite] = useState(agent?.enable_file_write ?? true); const [enableNetwork, setEnableNetwork] = useState(agent?.enable_network ?? false); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null); const isEditMode = !!agent; const handleSave = async () => { if (!name.trim()) { setError("Agent name is required"); return; } if (!systemPrompt.trim()) { setError("System prompt is required"); return; } try { setSaving(true); setError(null); if (isEditMode && agent.id) { await api.updateAgent( agent.id, name, selectedIcon, systemPrompt, defaultTask || undefined, model, sandboxEnabled, enableFileRead, enableFileWrite, enableNetwork ); } else { await api.createAgent( name, selectedIcon, systemPrompt, defaultTask || undefined, model, sandboxEnabled, enableFileRead, enableFileWrite, enableNetwork ); } onAgentCreated(); } catch (err) { console.error("Failed to save agent:", err); setError(isEditMode ? "Failed to update agent" : "Failed to create agent"); setToast({ message: isEditMode ? "Failed to update agent" : "Failed to create agent", type: "error" }); } finally { setSaving(false); } }; const handleBack = () => { if ((name !== (agent?.name || "") || selectedIcon !== (agent?.icon || "bot") || systemPrompt !== (agent?.system_prompt || "") || defaultTask !== (agent?.default_task || "") || model !== (agent?.model || "sonnet") || sandboxEnabled !== (agent?.sandbox_enabled ?? true) || enableFileRead !== (agent?.enable_file_read ?? true) || enableFileWrite !== (agent?.enable_file_write ?? true) || enableNetwork !== (agent?.enable_network ?? false)) && !confirm("You have unsaved changes. Are you sure you want to leave?")) { return; } onBack(); }; return (
{/* Header */}

{isEditMode ? "Edit CC Agent" : "Create CC Agent"}

{isEditMode ? "Update your Claude Code agent" : "Create a new Claude Code agent"}

{/* Error display */} {error && ( {error} )} {/* Form */}
{/* Agent Name */}
setName(e.target.value)} className="max-w-md" />
{/* Icon Picker */}
{(Object.keys(AGENT_ICONS) as AgentIconName[]).map((iconName) => { const Icon = AGENT_ICONS[iconName]; return ( ); })}
{/* Model Selection */}
{/* Default Task */}
setDefaultTask(e.target.value)} className="max-w-md" />

This will be used as the default task placeholder when executing the agent

{/* Sandbox Settings */} { if ('sandbox_enabled' in updates) setSandboxEnabled(updates.sandbox_enabled!); if ('enable_file_read' in updates) setEnableFileRead(updates.enable_file_read!); if ('enable_file_write' in updates) setEnableFileWrite(updates.enable_file_write!); if ('enable_network' in updates) setEnableNetwork(updates.enable_network!); }} /> {/* System Prompt Editor */}

Define the behavior and capabilities of your CC Agent

setSystemPrompt(val || "")} preview="edit" height={400} visibleDragbar={false} />
{/* Toast Notification */} {toast && ( setToast(null)} /> )}
); };