"use client"; import { useEffect, useState, useCallback } from "react"; import { useRouter } from "next/navigation"; import { Award, BarChart3, Beaker, Bot, Calendar, Clock, FlaskConical, GitBranch, Inbox, Layers, Mic, RefreshCw, Search, Sparkles, Target, } from "lucide-react"; import type { LucideIcon } from "lucide-react"; interface CmdItem { id: string; label: string; icon: LucideIcon; href: string; category: string; } const COMMANDS: CmdItem[] = [ { id: "today", label: "Today", icon: Calendar, href: "/today", category: "Navigate" }, { id: "inbox", label: "Inbox", icon: Inbox, href: "/inbox", category: "Navigate" }, { id: "foundry", label: "Foundry", icon: FlaskConical, href: "/foundry", category: "Navigate" }, { id: "experiment", label: "Experiment", icon: Beaker, href: "/experiment", category: "Navigate" }, { id: "results", label: "Results", icon: BarChart3, href: "/results", category: "Navigate" }, { id: "golden-nodes", label: "Golden Nodes", icon: Award, href: "/golden-nodes", category: "Navigate" }, { id: "spin-lifecycle", label: "SPIN Lifecycle", icon: RefreshCw, href: "/spin-lifecycle", category: "Navigate" }, { id: "spinor-rl", label: "SPINOR-RL", icon: GitBranch, href: "/spinor-rl", category: "Navigate" }, { id: "voice", label: "Voice", icon: Mic, href: "/voice-demo", category: "Navigate" }, { id: "autopilot", label: "Autopilot", icon: Bot, href: "/autopilot", category: "Navigate" }, { id: "history", label: "History", icon: Clock, href: "/history", category: "Navigate" }, { id: "allocate", label: "Plant Daily Seed", icon: Target, href: "/today?action=allocate", category: "Action" }, { id: "research", label: "Run LLM Prior-Art Research", icon: Search, href: "/today?action=research", category: "Action" }, { id: "record", label: "Record Experiment Outcome", icon: Sparkles, href: "/experiment", category: "Action" }, ]; export function CommandPalette() { const [open, setOpen] = useState(false); const [query, setQuery] = useState(""); const [active, setActive] = useState(0); const router = useRouter(); const filtered = COMMANDS.filter((c) => c.label.toLowerCase().includes(query.toLowerCase()) || c.category.toLowerCase().includes(query.toLowerCase()) ); const handleSelect = useCallback((item: CmdItem) => { router.push(item.href); setOpen(false); setQuery(""); setActive(0); }, [router]); useEffect(() => { const handler = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === "k") { e.preventDefault(); setOpen((v) => !v); } if (e.key === "Escape") { setOpen(false); setQuery(""); } if (open) { if (e.key === "ArrowDown") { e.preventDefault(); setActive((a) => Math.min(a + 1, filtered.length - 1)); } if (e.key === "ArrowUp") { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); } if (e.key === "Enter" && filtered[active]) { e.preventDefault(); handleSelect(filtered[active]); } } }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [open, active, filtered, handleSelect]); if (!open) return null; const categories = [...new Set(filtered.map((c) => c.category))]; return ( <>
setOpen(false)} />
{ setQuery(e.target.value); setActive(0); }} placeholder="Search commands, pages, actions…" className="flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground" /> ESC
{filtered.length === 0 ? (

No results for "{query}"

) : ( categories.map((cat) => (

{cat}

{filtered.filter((c) => c.category === cat).map((item) => { const idx = filtered.indexOf(item); const Icon = item.icon; return (
handleSelect(item)} onMouseEnter={() => setActive(idx)} > {item.label} ↵
); })}
)) )}
); }