// Command palette — scenarios, steps, scenes, recents, real actions. import { useEffect, useMemo } from "react"; import { Command } from "cmdk"; import { useApp, scenarioById } from "../state/store"; import { Play, Branch, Bot, Check, Home, HistoryIcon, Layers, Search, Refresh, Cog, User } from "./icons"; export default function CommandBar() { const open = useApp((s) => s.cmdOpen); const setOpen = useApp((s) => s.setCmdOpen); const setScenarioId = useApp((s) => s.setScenarioId); const setSelectedStepId = useApp((s) => s.setSelectedStepId); const setScene = useApp((s) => s.setScene); const recents = useApp((s) => s.recents); const scenarioId = useApp((s) => s.scenarioId); const pushRecent = useApp((s) => s.pushRecent); const scenarios = useApp((s) => s.scenarios); const mode = useApp((s) => s.mode); const setMode = useApp((s) => s.setMode); const refreshLive = useApp((s) => s.refreshLive); const startInstance = useApp((s) => s.startInstance); const executeAction = useApp((s) => s.executeAction); const pushToast = useApp((s) => s.pushToast); const setConsoleOpen = useApp((s) => s.setConsoleOpen); const setTheme = useApp((s) => s.setTheme); const theme = useApp((s) => s.theme); const actor = useApp((s) => s.actor); const sc = scenarioById(scenarioId); useEffect(() => { const onKey = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setOpen(!open); } if (e.key === "Escape" && open) setOpen(false); }; document.addEventListener("keydown", onKey); return () => document.removeEventListener("keydown", onKey); }, [open, setOpen]); const stepItems = useMemo(() => sc?.steps ?? [], [sc]); if (!open) return null; const close = () => setOpen(false); const canActLive = mode === "live" && actor?.user_id && sc?.live && sc.headlineTx; const firstActionId = sc?.steps.find((s) => s.state === "running")?.actions?.[0]?.id; return (
e.stopPropagation()} label="Command bar">
esc
No matches. {recents.length > 0 && ( {recents.map((r, i) => ( { pushRecent(r); close(); }}> {r} ))} )} { setScene("landing"); close(); }}> Landing { setScene("mission"); close(); }}> Mission Control { setScene("history"); close(); }}> Run History { setScene("studio"); close(); }}> Process Wizard design & publish a new process { setScene("settings"); close(); }}> Settings {mode === "live" ? ( { refreshLive(); close(); }}> Refresh live scenarios re-fetch demo.flow-master.ai ) : ( { setMode("live"); close(); }}> Switch to LIVE mode (fetch demo.flow-master.ai) in-browser )} { setMode("snapshot"); close(); }}> Switch to SNAPSHOT mode bundled JSON { setConsoleOpen(true); close(); }}> Open live API console stream every fetch { setTheme(theme === "dark" ? "light" : "dark"); close(); }}> Toggle theme {theme === "dark" ? "→ light" : "→ dark"} {sc?.live ? ( { close(); if (mode !== "live") { pushToast("warn", "Switch to LIVE mode to start a real instance."); return; } await startInstance(sc.defKey, `Started via Mission Control · ${new Date().toLocaleString()}`); }} > Start new instance of "{sc.defName}" POST /api/runtime/transactions ) : ( Start new instance switch to a LIVE scenario first )} {canActLive && firstActionId && ( { close(); await executeAction(sc!.headlineTx!, firstActionId); }} > Execute "{firstActionId}" on headline tx {sc?.headlineTx?.slice(0, 8)} · real )} { setScene("settings"); close(); }}> Sign in as different user Settings → identity {scenarios.map((s) => ( { setScenarioId(s.id); setScene("mission"); close(); }} > {s.family.label} {s.live ? "live" : "blueprint"} · {s.defName} ))} {sc && ( {stepItems.map((st) => ( { setSelectedStepId(st.id); setScene("mission"); close(); }} > {st.name} {st.kind} ))} )} { close(); pushToast("info", `Sidekick dispatch endpoint not yet wired — see Studio for process-level changes.`); }} > Dispatch sidekick agent coming soon
); }