import { useState } from "react" import { CheckCircle2, ChevronDown, CircleSlash, Loader2, Save, ShieldCheck, Sparkles, Trash2, Wand2, } from "lucide-react" import { useDashboard } from "@/lib/dashboard" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Badge } from "@/components/ui/badge" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Label } from "@/components/ui/label" import { Switch } from "@/components/ui/switch" import { cn } from "@/lib/utils" import type { ActionSpec, AutomationDocument, AutomationRule, ConditionBlock, CooldownCondition, } from "@/lib/types" export function RuleStudioPanel() { const { rulesText, setRulesText, replaceRulesText, validate, validation, save, setRuleEnabled, deleteRule, compiler, compile, compiling, } = useDashboard() const [instruction, setInstruction] = useState( "When a cat appears in the image, notify me.", ) const [armedDelete, setArmedDelete] = useState(null) const [expandedRule, setExpandedRule] = useState(null) const document = validation?.ok ? validation.document : null const applyDocument = (nextDocument: AutomationDocument) => { void replaceRulesText(JSON.stringify(nextDocument, null, 2), true) } const updateRule = (ruleIndex: number, updater: (rule: AutomationRule) => void) => { if (!document) return const nextDocument = cloneDocument(document) const rule = nextDocument.rules[ruleIndex] if (!rule) return updater(rule) applyDocument(nextDocument) } return (
Compose Source Rules {validation?.ok && ( {validation.rules.length} )} {validation && (validation.ok ? ( valid ) : ( invalid ))}
{/* Compose: NL → rules */}

Describe the automation in plain language. It compiles to validated rules through{" "} {compiler.provider} — never executable code.

{compiler.provider}