import React from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { toast } from 'sonner'; import { useCommandsStore, type CommandConfig } from '@/stores/useCommandsStore'; import { RiCheckLine, RiInformationLine, RiSaveLine, RiTerminalBoxLine } from '@remixicon/react'; import { cn } from '@/lib/utils'; import { ModelSelector } from '../agents/ModelSelector'; import { AgentSelector } from './AgentSelector'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; export const CommandsPage: React.FC = () => { const { selectedCommandName, getCommandByName, createCommand, updateCommand, commands } = useCommandsStore(); const selectedCommand = selectedCommandName ? getCommandByName(selectedCommandName) : null; const isNewCommand = selectedCommandName && !selectedCommand; const [name, setName] = React.useState(''); const [description, setDescription] = React.useState(''); const [agent, setAgent] = React.useState(''); const [model, setModel] = React.useState(''); const [template, setTemplate] = React.useState(''); const [subtask, setSubtask] = React.useState(false); const [isSaving, setIsSaving] = React.useState(false); React.useEffect(() => { if (isNewCommand) { setName(selectedCommandName || ''); setDescription(''); setAgent(''); setModel(''); setTemplate(''); setSubtask(false); } else if (selectedCommand) { setName(selectedCommand.name); setDescription(selectedCommand.description || ''); setAgent(selectedCommand.agent || ''); setModel(selectedCommand.model || ''); setTemplate(selectedCommand.template || ''); setSubtask(selectedCommand.subtask || false); } }, [selectedCommand, isNewCommand, selectedCommandName, commands]); const handleSave = async () => { if (!name.trim()) { toast.error('Command name is required'); return; } if (!template.trim()) { toast.error('Command template is required'); return; } setIsSaving(true); try { const trimmedAgent = agent.trim(); const trimmedModel = model.trim(); const trimmedTemplate = template.trim(); const config: CommandConfig = { name: name.trim(), description: description.trim() || undefined, agent: trimmedAgent === '' ? null : trimmedAgent, model: trimmedModel === '' ? null : trimmedModel, template: trimmedTemplate, subtask, }; let success: boolean; if (isNewCommand) { success = await createCommand(config); } else { success = await updateCommand(name, config); } if (success) { toast.success(isNewCommand ? 'Command created successfully' : 'Command updated successfully'); } else { toast.error(isNewCommand ? 'Failed to create command' : 'Failed to update command'); } } catch (error) { console.error('Error saving command:', error); toast.error('An error occurred while saving'); } finally { setIsSaving(false); } }; if (!selectedCommandName) { return (

Select a command from the sidebar

or create a new one

); } return ( {}

{isNewCommand ? 'New Command' : name}

{}

Basic Information

Configure command identity and metadata

setName(e.target.value)} placeholder="my-command" disabled={!isNewCommand} />

Used with slash (/) prefix in chat