= ["fast", "deep", "creative", "code", "agent"];
+
+ return (
+ }>
+ Models
+
+ {models.map((model) => )}
+
+ Modes
+
+ {modes.map((mode) => )}
+
+
+ );
+}
+
+function ExportModal() {
+ const artifacts = useAppStore((s) => s.artifacts);
+ const timeline = useAppStore((s) => s.timeline);
+
+ return (
+ }>
+
+
Artifacts{artifacts.length}
+
Timeline events{timeline.length}
+
FormatReport bundle
+
+
+
+ );
+}
+
+function ApprovalModal() {
+ const metrics = useAppStore((s) => s.metrics);
+ const setModalOpen = useAppStore((s) => s.setModalOpen);
+ const setDrawerOpen = useAppStore((s) => s.setDrawerOpen);
+
+ return (
+ }>
+
+
Latency{Math.round(metrics.latencyMs)}ms
+
Pipeline{Math.round(metrics.pipelineSuccess)}%
+
Risk{metrics.latencyMs > 110 ? "high" : "medium"}
+
+
+
+
+
+ );
+}
+
+function ShortcutsModal() {
+ const shortcuts = [
+ ["Cmd/Ctrl + K", "Command palette"],
+ ["Cmd/Ctrl + L", "Focus composer"],
+ ["Cmd/Ctrl + Enter", "Run command"],
+ ["Escape", "Close overlays / collapse panels"],
+ ];
+ return (
+ }>
+
+ {shortcuts.map(([key, label]) =>
{key}{label})}
+
+
+ );
+}
+
+function CompareModal() {
+ const artifacts = useAppStore((s) => s.artifacts);
+ const first = artifacts[0];
+ const second = artifacts[1] ?? artifacts[0];
+
+ return (
+ }>
+
+ {[first, second].map((artifact, index) => (
+
+ Branch {index + 1}
+ {artifact?.title ?? "No branch"}
+ {artifact?.content.slice(0, 300) ?? "Generate an artifact to compare branches."}
+
+ ))}
+
+
+ );
+}
+
+function StopConfirmModal() {
+ const cancelActiveTasks = useAppStore((s) => s.cancelActiveTasks);
+ const setModalOpen = useAppStore((s) => s.setModalOpen);
+ const tasks = useAppStore((s) => s.tasks.filter((task) => ["queued", "planning", "running", "waiting"].includes(task.status)));
+
+ return (
+ }>
+ Active tasks{tasks.length}Stopping cancels running work while preserving timeline, artifacts, and context.
+
+
+ );
+}
+
+export function ProductModalStack({ modalId }: { modalId: ModalId }) {
+ if (modalId === "add-widget") return ;
+ if (modalId === "context-picker") return ;
+ if (modalId === "model-selector") return ;
+ if (modalId === "export") return ;
+ if (modalId === "approval") return ;
+ if (modalId === "shortcuts") return ;
+ if (modalId === "compare") return ;
+ if (modalId === "stop-confirm") return ;
+ return null;
+}
diff --git a/frontend/src/components/surfaces/SettingsDrawer.tsx b/frontend/src/components/surfaces/SettingsDrawer.tsx
new file mode 100644
index 0000000..47d88af
--- /dev/null
+++ b/frontend/src/components/surfaces/SettingsDrawer.tsx
@@ -0,0 +1,42 @@
+import { Cpu, Settings, SlidersHorizontal } from "lucide-react";
+import { useAppStore } from "../../store/useAppStore";
+import { ProductDrawerShell } from "./SurfaceShell";
+
+export function SettingsDrawer() {
+ const mode = useAppStore((s) => s.mode);
+ const composer = useAppStore((s) => s.composer);
+ const performanceOverlayOpen = useAppStore((s) => s.performanceOverlayOpen);
+ const setPerformanceOverlayOpen = useAppStore((s) => s.setPerformanceOverlayOpen);
+ const layoutEditMode = useAppStore((s) => s.layoutEditMode);
+ const setLayoutEditMode = useAppStore((s) => s.setLayoutEditMode);
+
+ const rows = [
+ ["System mode", mode],
+ ["Selected model", composer.selectedModel],
+ ["Run mode", composer.selectedMode],
+ ["Tools", composer.selectedTools.join(" / ")],
+ ];
+
+ return (
+ }>
+
+ {rows.map(([label, value]) => (
+
+ {label}
+ {value}
+
+ ))}
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/surfaces/SurfaceShell.tsx b/frontend/src/components/surfaces/SurfaceShell.tsx
new file mode 100644
index 0000000..c276413
--- /dev/null
+++ b/frontend/src/components/surfaces/SurfaceShell.tsx
@@ -0,0 +1,85 @@
+import type { ReactNode } from "react";
+import { motion } from "motion/react";
+import { X } from "lucide-react";
+import { useAppStore } from "../../store/useAppStore";
+import type { ModalId } from "../../types/app";
+
+export function ProductDrawerShell({
+ title,
+ subtitle,
+ icon,
+ children,
+}: {
+ title: string;
+ subtitle: string;
+ icon: ReactNode;
+ children: ReactNode;
+}) {
+ const setDrawerOpen = useAppStore((s) => s.setDrawerOpen);
+
+ return (
+
+
+ {icon}
+
+ {title}
+ {subtitle}
+
+
+
+ {children}
+
+ );
+}
+
+export function ProductModalShell({
+ modalId,
+ title,
+ subtitle,
+ icon,
+ children,
+}: {
+ modalId: ModalId;
+ title: string;
+ subtitle: string;
+ icon: ReactNode;
+ children: ReactNode;
+}) {
+ const setModalOpen = useAppStore((s) => s.setModalOpen);
+
+ return (
+
+
+ {icon}
+
+ {title}
+ {subtitle}
+
+
+
+ {children}
+
+ );
+}
diff --git a/frontend/src/engine/commandPaletteRegistry.ts b/frontend/src/engine/commandPaletteRegistry.ts
index d288d6b..0e25377 100644
--- a/frontend/src/engine/commandPaletteRegistry.ts
+++ b/frontend/src/engine/commandPaletteRegistry.ts
@@ -1,4 +1,4 @@
-import type { PanelId, SystemMode } from "../types/app";
+import type { DrawerId, ModalId, PanelId, SystemMode } from "../types/app";
import { handleSubmitCommand } from "./taskRunner";
import { useAppStore } from "../store/useAppStore";
import { mockupStateBank } from "./mockupStateBank";
@@ -46,6 +46,36 @@ function setModeAction(mode: SystemMode, title: string): CommandPaletteAction {
};
}
+function openDrawerAction(id: DrawerId, title: string, subtitle: string, keywords: string[], kind: CommandPaletteActionKind = "workspace"): CommandPaletteAction {
+ return {
+ id: `open-drawer-${id}`,
+ kind,
+ title,
+ subtitle,
+ keywords: ["drawer", "open", title, ...(keywords ?? [])],
+ run: () => {
+ const store = useAppStore.getState();
+ store.setDrawerOpen(id);
+ store.setCommandPaletteOpen(false);
+ },
+ };
+}
+
+function openModalAction(id: ModalId, title: string, subtitle: string, keywords: string[], kind: CommandPaletteActionKind = "workspace"): CommandPaletteAction {
+ return {
+ id: `open-modal-${id}`,
+ kind,
+ title,
+ subtitle,
+ keywords: ["modal", "open", title, ...(keywords ?? [])],
+ run: () => {
+ const store = useAppStore.getState();
+ store.setModalOpen(id);
+ store.setCommandPaletteOpen(false);
+ },
+ };
+}
+
export function getCommandPaletteActions(): CommandPaletteAction[] {
const store = useAppStore.getState();
return [
@@ -96,6 +126,18 @@ export function getCommandPaletteActions(): CommandPaletteAction[] {
s.setCommandPaletteOpen(false);
},
},
+ {
+ id: "open-dashboard",
+ kind: "workspace",
+ title: "Return to Dashboard",
+ subtitle: "Bring floating panels back to the front",
+ keywords: ["dashboard", "return", "panels", "system"],
+ run: () => {
+ const s = useAppStore.getState();
+ s.setWorkspaceView("dashboard");
+ s.setCommandPaletteOpen(false);
+ },
+ },
{
id: "open-agent-queue",
kind: "agent",
@@ -120,6 +162,30 @@ export function getCommandPaletteActions(): CommandPaletteAction[] {
s.setCommandPaletteOpen(false);
},
},
+ openDrawerAction("settings", "Open Settings", "Motion, memory, backend, and operator preferences", ["settings", "preferences", "motion", "backend"], "workspace"),
+ openDrawerAction("notifications", "Open Notifications", "Alerts, tool results, task completions, and workspace events", ["notifications", "alerts", "events", "toast"], "debug"),
+ openDrawerAction("artifact-inspector", "Open Artifact Inspector", "Inspect generated work and source context", ["artifact", "inspector", "export", "canvas"], "workspace"),
+ openModalAction("add-widget", "Add Widget", "Create a semantic panel from a metric, memory, or command", ["widget", "panel", "create", "add"], "workspace"),
+ openModalAction("context-picker", "Open Context Picker", "Attach panels and memory to the next command", ["context", "picker", "attach", "panels"], "run"),
+ openModalAction("model-selector", "Open Model Selector", "Choose model and reasoning mode", ["model", "selector", "mode", "router"], "run"),
+ openModalAction("export", "Export Workspace", "Package artifacts, timeline, and current state", ["export", "download", "bundle"], "workspace"),
+ openModalAction("approval", "Open Deployment Approval", "Review rollout risk and approval gates", ["approval", "deploy", "canary", "risk"], "tool"),
+ openModalAction("shortcuts", "Open Keyboard Shortcuts", "Show fast control commands", ["keyboard", "shortcuts", "hotkeys"], "workspace"),
+ openModalAction("compare", "Open Branch Compare", "Compare generated artifact branches", ["compare", "branch", "artifact", "diff"], "workspace"),
+ openModalAction("stop-confirm", "Confirm Stop Active Run", "Cancel active agent work with a clear checkpoint", ["stop", "cancel", "run", "task"], "debug"),
+ {
+ id: "expand-temporal-memory",
+ kind: "memory",
+ title: "Expand Temporal Memory",
+ subtitle: "Open the large timeline scrub and replay surface",
+ keywords: ["temporal", "memory", "timeline", "state", "22", "expand"],
+ run: () => {
+ const s = useAppStore.getState();
+ s.expandPanel("memory-ribbon", true);
+ s.setMode("reviewing");
+ s.setCommandPaletteOpen(false);
+ },
+ },
{
id: "toggle-performance",
kind: "debug",
diff --git a/frontend/src/engine/remoteLLMAdapter.ts b/frontend/src/engine/remoteLLMAdapter.ts
index c31c03d..bb48eaa 100644
--- a/frontend/src/engine/remoteLLMAdapter.ts
+++ b/frontend/src/engine/remoteLLMAdapter.ts
@@ -1,29 +1,60 @@
import type { LLMAdapter, LLMStreamEvent } from "../types/llm";
import { useAppStore } from "../store/useAppStore";
import { serializeWorkspaceForLLM } from "./workspaceSerializer";
+import { mockLLMAdapter } from "./mockLLMAdapter";
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "";
+const ORANGEBOX_RUN_PATH = "/api/v4/see-suite/agent/run";
+
+async function* fallbackToAelidVisualMode(input: Parameters[0], reason: string): AsyncIterable {
+ yield {
+ type: "state",
+ mode: "reviewing",
+ energy: 0.62,
+ contextPanelIds: ["project-nexus", "system-health", "memory-ribbon"],
+ };
+
+ yield {
+ type: "token",
+ token: `OrangeBOX is not connected (${reason}). AELID is running in visual/local mode. `,
+ };
+
+ for await (const event of mockLLMAdapter.run(input)) {
+ yield event;
+ }
+}
export const remoteLLMAdapter: LLMAdapter = {
async *run(input) {
const state = useAppStore.getState();
const lastUser = [...input.messages].reverse().find((message) => message.role === "user");
const base = API_BASE_URL || window.location.origin;
- const response = await fetch(`${base}/api/v4/see-suite/agent/run`, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- workspaceId: state.workspaceId,
- sessionId: "session-local-dev",
- command: lastUser?.content ?? "",
- messages: input.messages,
- workspace: serializeWorkspaceForLLM(state),
- }),
- signal: input.abortSignal,
- });
+
+ let response: Response;
+
+ try {
+ response = await fetch(`${base}${ORANGEBOX_RUN_PATH}`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ module: "AELID",
+ moduleName: "AtomEons Living Intelligence Dashboard",
+ workspaceId: state.workspaceId,
+ sessionId: "session-local-dev",
+ command: lastUser?.content ?? "",
+ messages: input.messages,
+ workspace: serializeWorkspaceForLLM(state),
+ }),
+ signal: input.abortSignal,
+ });
+ } catch (error) {
+ const reason = error instanceof Error ? error.message : "fetch failed";
+ yield* fallbackToAelidVisualMode(input, reason);
+ return;
+ }
if (!response.ok || !response.body) {
- yield { type: "error", error: `Remote run failed: ${response.status}` };
+ yield* fallbackToAelidVisualMode(input, `HTTP ${response.status}`);
return;
}
@@ -44,7 +75,7 @@ export const remoteLLMAdapter: LLMAdapter = {
try {
yield JSON.parse(line.replace(/^data:\s*/, "")) as LLMStreamEvent;
} catch {
- yield { type: "error", error: "Failed to parse stream event." };
+ yield { type: "error", error: "Failed to parse OrangeBOX stream event." };
}
}
}
diff --git a/frontend/src/hooks/useStartupStateCleanup.ts b/frontend/src/hooks/useStartupStateCleanup.ts
new file mode 100644
index 0000000..bffdf59
--- /dev/null
+++ b/frontend/src/hooks/useStartupStateCleanup.ts
@@ -0,0 +1,15 @@
+import { useEffect } from "react";
+import { useAppStore } from "../store/useAppStore";
+
+export function useStartupStateCleanup() {
+ useEffect(() => {
+ const params = new URLSearchParams(window.location.search);
+ const requestedState = params.get("state") ?? params.get("mockupState");
+ if (requestedState) return;
+
+ const state = useAppStore.getState();
+ if (state.mode === "calm" && !state.activeMockupStateId && state.activeCausalPath) {
+ state.setActiveCausalPath(undefined);
+ }
+ }, []);
+}
diff --git a/frontend/src/store/useAppStore.ts b/frontend/src/store/useAppStore.ts
index db9b074..64c9f7f 100644
--- a/frontend/src/store/useAppStore.ts
+++ b/frontend/src/store/useAppStore.ts
@@ -120,7 +120,7 @@ export const useAppStore = create((set, get) => ({
focusPanelId: undefined,
panels: seedPanels,
agents: seedAgents,
- activeCausalPath: createLatencyCausalPath(),
+ activeCausalPath: undefined,
timeline: persisted?.timeline ?? seedTimeline,
messages: persisted?.messages ?? seedMessages,
tasks: [],
@@ -145,10 +145,9 @@ export const useAppStore = create((set, get) => ({
pendingApprovals: [],
eventToasts: [],
performanceOverlayOpen: false,
- chatDockExpanded: false,
+ chatDockExpanded: true,
layoutEditMode: false,
activeMockupStateId: undefined,
-
setWorkspaceId: (workspaceId) => set({ workspaceId }),
setMode: (mode) => set({ mode }),
setWorkspaceView: (workspaceView) => set({ workspaceView }),
@@ -161,8 +160,8 @@ export const useAppStore = create((set, get) => ({
panels: state.panels.map((panel) => ({ ...panel, dimmed: false, highlighted: false })),
};
}
- const focusedPanel = state.panels.find((panel) => panel.id === panelId);
- const related = new Set(focusedPanel ? [focusedPanel.id, ...focusedPanel.connectedTo] : [panelId]);
+ const focused = state.panels.find((panel) => panel.id === panelId);
+ const related = new Set(focused ? [focused.id, ...focused.connectedTo] : [panelId]);
return {
focusPanelId: panelId,
panels: state.panels.map((panel) => ({
@@ -170,10 +169,7 @@ export const useAppStore = create((set, get) => ({
dimmed: !related.has(panel.id),
highlighted: related.has(panel.id) && panel.id !== panelId,
})),
- composer: {
- ...state.composer,
- contextPanelIds: Array.from(related).slice(0, 4),
- },
+ composer: { ...state.composer, contextPanelIds: Array.from(related).slice(0, 4) },
};
}),
clearFocus: () =>
@@ -183,271 +179,154 @@ export const useAppStore = create((set, get) => ({
})),
expandPanel: (panelId, expanded) =>
set((state) => ({
- panels: state.panels.map((panel) => ({ ...panel, expanded: panel.id === panelId ? expanded : false })),
+ panels: state.panels.map((panel) => (panel.id === panelId ? { ...panel, expanded } : panel)),
focusPanelId: expanded ? panelId : state.focusPanelId,
})),
- collapseAllPanels: () =>
- set((state) => ({
- panels: state.panels.map((panel) => ({ ...panel, expanded: false })),
- })),
- setPanelSeverity: (panelId, severity) =>
- set((state) => ({
- panels: state.panels.map((panel) => (panel.id === panelId ? { ...panel, severity } : panel)),
- })),
- setComposerValue: (value) =>
- set((state) => ({
- composer: { ...state.composer, value, slashMenuOpen: value.startsWith("/") },
- mode: state.composer.isFocused ? "listening" : state.mode,
- })),
- setComposerFocus: (isFocused) =>
- set((state) => ({
- composer: { ...state.composer, isFocused },
- mode: isFocused && state.mode === "calm" ? "listening" : !isFocused && state.mode === "listening" ? "calm" : state.mode,
- })),
+ collapseAllPanels: () => set((state) => ({ panels: state.panels.map((panel) => ({ ...panel, expanded: false })) })),
+ setPanelSeverity: (panelId, severity) => set((state) => ({ panels: state.panels.map((panel) => (panel.id === panelId ? { ...panel, severity } : panel)) })),
+ setComposerValue: (value) => set((state) => ({ composer: { ...state.composer, value, slashMenuOpen: value.startsWith("/") } })),
+ setComposerFocus: (isFocused) => set((state) => ({ composer: { ...state.composer, isFocused }, mode: isFocused ? "listening" : state.mode })),
setSelectedMode: (selectedMode) => set((state) => ({ composer: { ...state.composer, selectedMode } })),
setSelectedModel: (selectedModel) => set((state) => ({ composer: { ...state.composer, selectedModel } })),
toggleTool: (tool) =>
- set((state) => {
- const selectedTools = state.composer.selectedTools.includes(tool)
- ? state.composer.selectedTools.filter((item) => item !== tool)
- : [...state.composer.selectedTools, tool];
- return { composer: { ...state.composer, selectedTools } };
- }),
+ set((state) => ({
+ composer: {
+ ...state.composer,
+ selectedTools: state.composer.selectedTools.includes(tool)
+ ? state.composer.selectedTools.filter((item) => item !== tool)
+ : [...state.composer.selectedTools, tool],
+ },
+ })),
setContextPanels: (contextPanelIds) => set((state) => ({ composer: { ...state.composer, contextPanelIds } })),
setSlashMenuOpen: (slashMenuOpen) => set((state) => ({ composer: { ...state.composer, slashMenuOpen } })),
setPlanPreview: (planPreview) => set((state) => ({ composer: { ...state.composer, planPreview } })),
- addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })),
- updateMessage: (id, patch) =>
- set((state) => ({
- messages: state.messages.map((message) => (message.id === id ? { ...message, ...patch } : message)),
- })),
+ addMessage: (message) => set((state) => ({ messages: [...state.messages, message].slice(-100) })),
+ updateMessage: (id, patch) => set((state) => ({ messages: state.messages.map((message) => (message.id === id ? { ...message, ...patch } : message)) })),
addTimelineEvent: (event) => set((state) => ({ timeline: [...state.timeline, event].slice(-120) })),
- addTask: (task) => set((state) => ({ tasks: [...state.tasks, task].slice(-40) })),
- updateTask: (id, patch) =>
+ addTask: (task) => set((state) => ({ tasks: [...state.tasks, task].slice(-80) })),
+ updateTask: (id, patch) => set((state) => ({ tasks: state.tasks.map((task) => (task.id === id ? { ...task, ...patch } : task)) })),
+ completeTask: (id) =>
set((state) => ({
- tasks: state.tasks.map((task) => (task.id === id ? { ...task, ...patch } : task)),
+ tasks: state.tasks.map((task) => (task.id === id ? { ...task, status: "complete", progress: 100, completedAt: Date.now() } : task)),
+ agents: state.agents.map((agent) => (agent.taskId === id ? { ...agent, state: "complete", taskId: undefined, energy: 0.68 } : agent)),
})),
- completeTask: (id) =>
- set((state) => {
- const completedTask = state.tasks.find((task) => task.id === id);
- return {
- tasks: state.tasks.map((task) =>
- task.id === id ? { ...task, status: "complete", progress: 100, completedAt: Date.now() } : task,
- ),
- agents: completedTask
- ? state.agents.map((agent) =>
- agent.id === completedTask.assignedAgentId ? { ...agent, state: "complete", taskId: undefined, energy: 0.68 } : agent,
- )
- : state.agents,
- };
- }),
cancelActiveTasks: () =>
set((state) => ({
- mode: state.activeCausalPath ? "alert" : "calm",
- energy: state.activeCausalPath ? 0.82 : 0.55,
+ mode: "calm",
+ energy: 0.55,
tasks: state.tasks.map((task) =>
["queued", "planning", "running", "waiting"].includes(task.status)
- ? { ...task, status: "cancelled", progress: Math.min(task.progress, 99), completedAt: Date.now() }
+ ? { ...task, status: "cancelled", completedAt: Date.now() }
: task,
),
- agents: state.agents.map((agent) => ({
- ...agent,
- state: agent.state === "working" || agent.state === "thinking" || agent.state === "blocked" ? "idle" : agent.state,
- taskId: undefined,
- energy: Math.max(0.42, agent.energy * 0.7),
- })),
+ agents: state.agents.map((agent) => ({ ...agent, state: agent.state === "blocked" ? "blocked" : "idle", taskId: undefined, energy: 0.48 })),
})),
- updateAgent: (id, patch) =>
- set((state) => ({ agents: state.agents.map((agent) => (agent.id === id ? { ...agent, ...patch } : agent)) })),
+ updateAgent: (id, patch) => set((state) => ({ agents: state.agents.map((agent) => (agent.id === id ? { ...agent, ...patch } : agent)) })),
setActiveCausalPath: (activeCausalPath) => set({ activeCausalPath, mode: activeCausalPath ? "alert" : "calm" }),
triggerLatencyScenario: () =>
set((state) => {
- const activeCausalPath = createLatencyCausalPath();
- const activeIds: PanelId[] = ["realtime-insights", "data-stream", "model-performance", "system-health", "activity-feed", "causality"];
+ const path = createLatencyCausalPath();
return {
- activeCausalPath,
mode: "alert",
energy: 1,
- composer: { ...state.composer, contextPanelIds: activeIds.slice(0, 4) },
+ activeCausalPath: path,
panels: state.panels.map((panel) => {
- if (panel.id === "realtime-insights") return { ...panel, dimmed: false, severity: "warning" };
- if (panel.id === "system-health") return { ...panel, dimmed: false, severity: "critical" };
- if (panel.id === "data-stream") return { ...panel, dimmed: false, severity: "warning" };
- return { ...panel, dimmed: !activeIds.includes(panel.id), highlighted: activeIds.includes(panel.id) };
- }),
- agents: state.agents.map((agent) => {
- if (agent.id === "watcher") return { ...agent, state: "working", energy: 1, connectedPanel: "realtime-insights" };
- if (agent.id === "analyst") return { ...agent, state: "thinking", energy: 0.92, connectedPanel: "causality" };
- return { ...agent, energy: Math.max(0.42, agent.energy * 0.76) };
+ if (["realtime-insights", "data-stream", "system-health"].includes(panel.id)) return { ...panel, severity: "warning", dimmed: false };
+ if (panel.id === "causality") return { ...panel, severity: "critical", dimmed: false };
+ return { ...panel, dimmed: !["model-performance", "activity-feed", "smart-suggestions"].includes(panel.id) };
}),
+ agents: state.agents.map((agent) =>
+ agent.id === "watcher" || agent.id === "analyst" ? { ...agent, state: "working", energy: 1, connectedPanel: "causality" } : { ...agent, energy: 0.48 },
+ ),
timeline: [
...state.timeline,
- createTimelineEvent({
- title: "Latency anomaly activated",
- description: "Causal path generated across gateway, model, resource, and user impact signals.",
- type: "alert",
- severity: "warning",
- relatedPanelIds: activeIds,
- }),
- ],
- eventToasts: [
- ...state.eventToasts.slice(-4),
- { id: createId("toast"), title: "Causal path generated", description: activeCausalPath.title, severity: "warning", createdAt: Date.now() },
- ],
+ createTimelineEvent({ title: "Latency anomaly traced", description: path.title, type: "alert", severity: "warning", relatedPanelIds: ["causality", "data-stream", "system-health"] }),
+ ].slice(-120),
};
}),
clearCausality: () =>
set((state) => ({
- activeCausalPath: undefined,
mode: "calm",
energy: 0.55,
+ activeCausalPath: undefined,
panels: state.panels.map((panel) => ({ ...panel, dimmed: false, highlighted: false, severity: undefined })),
- agents: state.agents.map((agent) => ({
- ...agent,
- state: agent.id === "watcher" || agent.id === "analyst" ? "watching" : "idle",
- energy: 0.55,
- taskId: undefined,
- })),
+ agents: state.agents.map((agent) => ({ ...agent, state: agent.id === "watcher" ? "watching" : "idle", taskId: undefined, energy: 0.55 })),
})),
tickMetrics: () =>
set((state) => {
- const alertActive = state.mode === "alert";
- const thinkingActive = ["thinking", "analyzing", "generating"].includes(state.mode);
- const metrics: SystemMetrics = {
- cpu: jitterMetric(state.metrics.cpu + (alertActive ? 1.2 : thinkingActive ? 0.5 : 0), alertActive ? 6 : 3, 12, 98),
- memory: jitterMetric(state.metrics.memory + (thinkingActive ? 0.4 : 0), 3, 20, 96),
- gpu: jitterMetric(state.metrics.gpu + (state.mode === "generating" ? 1 : 0), 5, 10, 98),
- network: jitterMetric(state.metrics.network + (alertActive ? 1.4 : 0), 6, 18, 99),
- latencyMs: jitterMetric(state.metrics.latencyMs + (alertActive ? 8 : -1.5), alertActive ? 28 : 8, 24, alertActive ? 220 : 120),
- throughputTbs: jitterMetric(state.metrics.throughputTbs, 0.16, 1.2, 3.8),
- eventsPerSecondM: jitterMetric(state.metrics.eventsPerSecondM, 0.24, 0.8, 3.4),
- modelAccuracy: jitterMetric(state.metrics.modelAccuracy, 0.18, 88, 98),
- precision: jitterMetric(state.metrics.precision, 0.22, 86, 98),
- recall: jitterMetric(state.metrics.recall, 0.22, 86, 98),
- f1: jitterMetric(state.metrics.f1, 0.18, 86, 98),
- activeStreams: Math.round(jitterMetric(state.metrics.activeStreams, 3, 14, 42)),
- pipelineSuccess: jitterMetric(state.metrics.pipelineSuccess - (alertActive ? 0.12 : 0), 0.25, 92, 99.8),
+ const metrics = {
+ ...state.metrics,
+ cpu: jitterMetric(state.metrics.cpu + (state.mode === "alert" ? 1.2 : 0), 5, 12, 98),
+ memory: jitterMetric(state.metrics.memory, 3, 20, 96),
+ gpu: jitterMetric(state.metrics.gpu + (state.mode === "generating" ? 1.3 : 0), 5, 10, 99),
+ network: jitterMetric(state.metrics.network + (state.mode === "alert" ? 1.8 : 0), 5, 18, 99),
+ latencyMs: Math.round(jitterMetric(state.metrics.latencyMs + (state.mode === "alert" ? 3.8 : -0.6), state.mode === "alert" ? 18 : 5, 28, state.mode === "alert" ? 260 : 90)),
};
- return { metrics, metricHistory: [...state.metricHistory.slice(-48), { timestamp: Date.now(), system: metrics }] };
- }),
- ingestMetricSnapshot: (incoming) =>
- set((state) => {
- const metrics = { ...state.metrics, ...incoming };
- return { metrics, metricHistory: [...state.metricHistory.slice(-48), { timestamp: Date.now(), system: metrics }] };
+ return { metrics, metricHistory: [...state.metricHistory.slice(-40), { timestamp: Date.now(), system: metrics }] };
}),
+ ingestMetricSnapshot: (incoming) => set((state) => {
+ const metrics = { ...state.metrics, ...incoming };
+ return { metrics, metricHistory: [...state.metricHistory.slice(-40), { timestamp: Date.now(), system: metrics }] };
+ }),
setDrawerOpen: (activeDrawer) => set({ activeDrawer }),
setModalOpen: (activeModal) => set({ activeModal }),
- setCommandPaletteOpen: (commandPaletteOpen) =>
- set({ commandPaletteOpen, commandPaletteQuery: commandPaletteOpen ? get().commandPaletteQuery : "" }),
+ setCommandPaletteOpen: (commandPaletteOpen) => set({ commandPaletteOpen, commandPaletteQuery: commandPaletteOpen ? get().commandPaletteQuery : "" }),
setCommandPaletteQuery: (commandPaletteQuery) => set({ commandPaletteQuery }),
- addPendingApproval: (approval) =>
- set((state) => ({
- pendingApprovals: [...state.pendingApprovals.filter((item) => item.id !== approval.id), approval],
- activeDrawer: "tool-approval",
- })),
- resolveApproval: (id, status) =>
- set((state) => ({
- pendingApprovals: state.pendingApprovals.map((approval) => (approval.id === id ? { ...approval, status } : approval)),
- })),
- addEventToast: (toast) =>
- set((state) => ({ eventToasts: [...state.eventToasts.slice(-4), { ...toast, id: createId("toast"), createdAt: Date.now() }] })),
+ addPendingApproval: (approval) => set((state) => ({ pendingApprovals: [...state.pendingApprovals.filter((item) => item.id !== approval.id), approval], activeDrawer: "tool-approval" })),
+ resolveApproval: (id, status) => set((state) => ({ pendingApprovals: state.pendingApprovals.map((approval) => (approval.id === id ? { ...approval, status } : approval)) })),
+ addEventToast: (toast) => set((state) => ({ eventToasts: [...state.eventToasts.slice(-4), { ...toast, id: createId("toast"), createdAt: Date.now() }] })),
dismissEventToast: (id) => set((state) => ({ eventToasts: state.eventToasts.filter((toast) => toast.id !== id) })),
setPerformanceOverlayOpen: (performanceOverlayOpen) => set({ performanceOverlayOpen }),
setChatDockExpanded: (chatDockExpanded) => set({ chatDockExpanded }),
- setLayoutEditMode: (layoutEditMode) => set({ layoutEditMode, mode: layoutEditMode ? "reviewing" : get().mode }),
+ setLayoutEditMode: (layoutEditMode) => set({ layoutEditMode }),
setActiveMockupState: (activeMockupStateId) => set({ activeMockupStateId }),
- resetToBaseline: () =>
- set(() => {
- const metrics = baselineMetrics();
- return {
- mode: "calm",
- workspaceView: "dashboard",
- energy: 0.78,
- focusPanelId: undefined,
- panels: baselinePanels(),
- agents: baselineAgents(),
- activeCausalPath: undefined,
- timeline: baselineTimeline(),
- messages: baselineMessages(),
- tasks: [],
- metrics,
- metricHistory: [{ timestamp: Date.now(), system: metrics }],
- composer: {
- value: "",
- isFocused: false,
- selectedModel: "GPT-5.5",
- selectedMode: "deep",
- selectedTools: defaultSelectedTools,
- contextPanelIds: ["project-nexus", "system-health"],
- slashMenuOpen: false,
- planPreview: undefined,
- },
- artifacts: [],
- activeArtifactId: undefined,
- activeDrawer: undefined,
- activeModal: undefined,
- commandPaletteOpen: false,
- commandPaletteQuery: "",
- pendingApprovals: [],
- eventToasts: [],
- performanceOverlayOpen: false,
- chatDockExpanded: false,
- layoutEditMode: false,
- activeMockupStateId: undefined,
- };
- }),
- resetToDemoBaseline: () =>
- set(() => {
- const metrics = baselineMetrics();
- return {
- workspaceView: "dashboard",
- mode: "calm",
- energy: 0.78,
- focusPanelId: undefined,
- panels: demoPanels(),
- agents: baselineAgents(),
- activeCausalPath: createLatencyCausalPath(),
- tasks: [],
- timeline: baselineTimeline(),
- messages: baselineMessages(),
- metrics,
- metricHistory: [{ timestamp: Date.now(), system: metrics }],
- composer: {
- value: "",
- isFocused: false,
- selectedModel: "GPT-5.5",
- selectedMode: "deep",
- selectedTools: defaultSelectedTools,
- contextPanelIds: ["project-nexus", "system-health"],
- slashMenuOpen: false,
- planPreview: undefined,
- },
- artifacts: [],
- activeArtifactId: undefined,
- activeDrawer: undefined,
- activeModal: undefined,
- commandPaletteOpen: false,
- commandPaletteQuery: "",
- pendingApprovals: [],
- eventToasts: [],
- performanceOverlayOpen: false,
- chatDockExpanded: false,
- layoutEditMode: false,
- activeMockupStateId: undefined,
- };
- }),
- addArtifact: (artifact) =>
- set((state) => ({
- artifacts: [
- ...state.artifacts.filter((item) => item.id !== artifact.id),
- { ...artifact, createdAt: artifact.createdAt ?? Date.now(), updatedAt: artifact.updatedAt ?? Date.now() },
- ],
- activeArtifactId: artifact.id,
- workspaceView: "canvas",
- })),
- updateArtifact: (id, patch) =>
- set((state) => ({
- artifacts: state.artifacts.map((artifact) => (artifact.id === id ? { ...artifact, ...patch, updatedAt: Date.now() } : artifact)),
- })),
+ resetToBaseline: () => set({
+ mode: "calm",
+ workspaceView: "dashboard",
+ energy: 0.55,
+ focusPanelId: undefined,
+ panels: baselinePanels(),
+ agents: baselineAgents(),
+ activeCausalPath: undefined,
+ tasks: [],
+ metrics: baselineMetrics(),
+ metricHistory: [{ timestamp: Date.now(), system: baselineMetrics() }],
+ activeDrawer: undefined,
+ activeModal: undefined,
+ commandPaletteOpen: false,
+ commandPaletteQuery: "",
+ pendingApprovals: [],
+ eventToasts: [],
+ performanceOverlayOpen: false,
+ layoutEditMode: false,
+ activeMockupStateId: undefined,
+ }),
+ resetToDemoBaseline: () => set({
+ mode: "calm",
+ workspaceView: "dashboard",
+ energy: 0.72,
+ panels: demoPanels(),
+ agents: baselineAgents(),
+ timeline: baselineTimeline(),
+ messages: baselineMessages(),
+ tasks: [],
+ metrics: baselineMetrics(),
+ metricHistory: [{ timestamp: Date.now(), system: baselineMetrics() }],
+ activeCausalPath: undefined,
+ activeDrawer: undefined,
+ activeModal: undefined,
+ commandPaletteOpen: false,
+ commandPaletteQuery: "",
+ pendingApprovals: [],
+ eventToasts: [],
+ performanceOverlayOpen: false,
+ layoutEditMode: false,
+ }),
+ addArtifact: (artifact) => set((state) => ({
+ artifacts: [...state.artifacts.filter((item) => item.id !== artifact.id), artifact],
+ activeArtifactId: artifact.id,
+ workspaceView: "canvas",
+ })),
+ updateArtifact: (id, patch) => set((state) => ({ artifacts: state.artifacts.map((artifact) => (artifact.id === id ? { ...artifact, ...patch, updatedAt: Date.now() } : artifact)) })),
setActiveArtifact: (activeArtifactId) => set({ activeArtifactId, workspaceView: activeArtifactId ? "canvas" : "dashboard" }),
}));
diff --git a/frontend/src/styles/product-surfaces.css b/frontend/src/styles/product-surfaces.css
new file mode 100644
index 0000000..147ad34
--- /dev/null
+++ b/frontend/src/styles/product-surfaces.css
@@ -0,0 +1 @@
+.product-surface-drawer{position:absolute;z-index:74;top:72px;right:24px;bottom:116px;width:min(520px,calc(100vw - 310px));border-radius:30px;overflow:hidden;pointer-events:auto}.product-surface-modal{position:absolute;z-index:86;left:50%;top:50%;width:min(760px,calc(100vw - 140px));max-height:min(680px,calc(100vh - 140px));transform:translate(-50%,-50%);border-radius:30px;overflow:hidden;pointer-events:auto}.product-surface__header{min-height:72px;display:grid;grid-template-columns:42px 1fr 36px;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid rgba(142,227,255,.12)}.product-surface__icon{width:40px;height:40px;display:grid;place-items:center;border-radius:16px;color:var(--cyan);background:rgba(47,252,255,.08);border:1px solid rgba(47,252,255,.12)}.product-surface__header strong,.product-surface__header em{display:block}.product-surface__header strong{color:white;font-size:16px}.product-surface__header em{margin-top:4px;color:var(--text-muted);font-size:12px;font-style:normal}.product-surface__header button{width:34px;height:34px;display:grid;place-items:center;border:1px solid rgba(142,227,255,.14);border-radius:999px;color:var(--text-secondary);background:rgba(255,255,255,.035);cursor:pointer}.product-surface__body{max-height:calc(100% - 72px);overflow:auto;padding:14px}.surface-stat-grid,.surface-card-list--grid,.surface-compare-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.surface-card-list,.surface-action-list{display:grid;gap:10px}.surface-action-list{margin-top:14px}.surface-stat-grid article,.surface-hero-card,.surface-card,.surface-template-card,.surface-compare-grid article{border:1px solid rgba(142,227,255,.1);border-radius:20px;background:rgba(255,255,255,.025);padding:12px}.surface-stat-grid em,.surface-hero-card em,.surface-card i,.surface-compare-grid em,.surface-section-title{display:block;color:var(--text-muted);font-size:10px;font-style:normal;text-transform:uppercase;letter-spacing:.06em}.surface-stat-grid strong,.surface-hero-card strong,.surface-card strong,.surface-template-card strong,.surface-compare-grid strong{display:block;margin-top:4px;color:white;font-size:13px}.surface-hero-card span,.surface-card span,.surface-template-card span,.surface-compare-grid span{display:block;margin-top:7px;color:var(--text-secondary);font-size:12px;line-height:1.45}.surface-action-list button,.surface-chip-row button,.surface-pill-grid button{min-height:34px;display:inline-flex;align-items:center;gap:8px;border:1px solid rgba(142,227,255,.12);border-radius:999px;color:var(--text-secondary);background:rgba(255,255,255,.035);padding:0 12px;cursor:pointer;font-size:12px}.surface-action-list button:hover,.surface-chip-row button:hover,.surface-pill-grid button:hover,.surface-pill-grid button.is-active,.surface-template-card.is-active{color:white;border-color:rgba(47,252,255,.32);background:rgba(47,252,255,.08)}.surface-template-card{min-height:110px;display:grid;gap:5px;color:var(--text-secondary);cursor:pointer;text-align:left}.surface-template-card svg{color:var(--cyan)}.surface-card--warning{border-color:rgba(255,191,72,.24)}.surface-card--critical{border-color:rgba(255,59,95,.28)}.surface-card--success{border-color:rgba(56,255,179,.24)}.surface-chip-row,.surface-pill-grid{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.surface-section-title{margin:12px 0 8px}.surface-empty{border:1px solid rgba(142,227,255,.08);border-radius:20px;color:var(--text-muted);background:rgba(255,255,255,.025);padding:18px;text-align:center;font-size:12px}@media(max-width:1040px){.product-surface-drawer{left:90px;right:12px;width:auto}.product-surface-modal{width:calc(100vw - 120px)}.surface-card-list--grid,.surface-stat-grid,.surface-compare-grid{grid-template-columns:1fr}}
\ No newline at end of file
diff --git a/frontend/src/styles/temporal.css b/frontend/src/styles/temporal.css
new file mode 100644
index 0000000..4dbb825
--- /dev/null
+++ b/frontend/src/styles/temporal.css
@@ -0,0 +1,182 @@
+.temporal-expanded {
+ position: absolute;
+ z-index: 56;
+ left: 50%;
+ bottom: 180px;
+ width: min(980px, calc(100vw - 420px));
+ max-height: min(520px, calc(100vh - 270px));
+ transform: translateX(-50%);
+ border-radius: 30px;
+ padding: 16px;
+ overflow: hidden;
+ pointer-events: auto;
+}
+
+.temporal-expanded__header {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 18px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid rgba(142, 227, 255, 0.12);
+}
+
+.temporal-expanded__header strong,
+.temporal-expanded__header span {
+ display: block;
+}
+
+.temporal-expanded__header strong {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: white;
+ font-size: 18px;
+ letter-spacing: -0.03em;
+}
+
+.temporal-expanded__header span {
+ margin-top: 5px;
+ color: var(--text-muted);
+ font-size: 12px;
+}
+
+.temporal-expanded__header button {
+ width: 34px;
+ height: 34px;
+ display: grid;
+ place-items: center;
+ border: 1px solid rgba(142, 227, 255, 0.14);
+ border-radius: 999px;
+ color: var(--text-secondary);
+ background: rgba(255, 255, 255, 0.035);
+ cursor: pointer;
+}
+
+.temporal-expanded__search {
+ height: 42px;
+ display: grid;
+ grid-template-columns: 26px 1fr;
+ align-items: center;
+ gap: 8px;
+ margin: 14px 0;
+ border: 1px solid rgba(142, 227, 255, 0.12);
+ border-radius: 999px;
+ color: var(--cyan);
+ background: rgba(255, 255, 255, 0.035);
+ padding: 0 12px;
+}
+
+.temporal-expanded__search span {
+ color: rgba(214, 231, 248, 0.5);
+ font-size: 12px;
+}
+
+.temporal-expanded__scrub {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 14px;
+}
+
+.temporal-expanded__scrub button {
+ height: 32px;
+ display: inline-flex;
+ align-items: center;
+ gap: 7px;
+ border: 1px solid rgba(142, 227, 255, 0.12);
+ border-radius: 999px;
+ color: var(--text-secondary);
+ background: rgba(255, 255, 255, 0.035);
+ padding: 0 11px;
+ cursor: pointer;
+ font-size: 12px;
+}
+
+.temporal-expanded__track {
+ max-height: 330px;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+ overflow: auto;
+ padding-right: 4px;
+}
+
+.temporal-expanded__event {
+ min-height: 88px;
+ display: grid;
+ gap: 4px;
+ border: 1px solid rgba(142, 227, 255, 0.1);
+ border-radius: 20px;
+ color: var(--text-secondary);
+ background:
+ radial-gradient(circle at 0% 0%, rgba(47, 252, 255, 0.08), transparent 34%),
+ rgba(255, 255, 255, 0.025);
+ padding: 12px;
+ cursor: pointer;
+ text-align: left;
+}
+
+.temporal-expanded__event:hover {
+ border-color: rgba(47, 252, 255, 0.28);
+ background:
+ radial-gradient(circle at 0% 0%, rgba(47, 252, 255, 0.14), transparent 34%),
+ rgba(47, 252, 255, 0.045);
+}
+
+.temporal-expanded__event i,
+.temporal-expanded__event em {
+ color: var(--text-muted);
+ font-size: 10px;
+ font-style: normal;
+}
+
+.temporal-expanded__event strong {
+ color: white;
+ font-size: 12px;
+}
+
+.temporal-expanded__event span {
+ color: var(--text-secondary);
+ font-size: 11px;
+ line-height: 1.4;
+}
+
+.temporal-expanded__event--warning {
+ border-color: rgba(255, 191, 72, 0.22);
+ background:
+ radial-gradient(circle at 0% 0%, rgba(255, 191, 72, 0.12), transparent 34%),
+ rgba(255, 255, 255, 0.025);
+}
+
+.temporal-expanded__event--critical {
+ border-color: rgba(255, 59, 95, 0.28);
+ background:
+ radial-gradient(circle at 0% 0%, rgba(255, 59, 95, 0.13), transparent 34%),
+ rgba(255, 255, 255, 0.025);
+}
+
+.temporal-expanded__event--success {
+ border-color: rgba(56, 255, 179, 0.24);
+ background:
+ radial-gradient(circle at 0% 0%, rgba(56, 255, 179, 0.11), transparent 34%),
+ rgba(255, 255, 255, 0.025);
+}
+
+.temporal-expanded--state-22 {
+ border-color: rgba(255, 191, 72, 0.36);
+ background:
+ radial-gradient(circle at 50% 0%, rgba(255, 191, 72, 0.12), transparent 38%),
+ radial-gradient(circle at 12% 80%, rgba(47, 252, 255, 0.08), transparent 32%),
+ rgba(7, 13, 31, 0.72);
+}
+
+@media (max-width: 1180px) {
+ .temporal-expanded {
+ left: calc(50% + 36px);
+ width: calc(100vw - 170px);
+ }
+
+ .temporal-expanded__track {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/package.json b/package.json
index facfb8a..42521b8 100644
--- a/package.json
+++ b/package.json
@@ -10,21 +10,21 @@
"scripts": {
"start": "node ./scripts/orangebox-command-server.mjs",
"check": "node --check ./scripts/orangebox-command-server.mjs && node --check ./scripts/orangebox-mcp-server.mjs && node --check ./src/app.js",
- "check:all": "npm.cmd run check && npm.cmd run build:web && npm.cmd run build:api",
- "dev:web": "npm.cmd run dev -w @ae-see-suite/web",
- "dev:api": "npm.cmd run dev -w @ae-see-suite/api",
- "build:web": "npm.cmd run build -w @ae-see-suite/web",
- "build:api": "npm.cmd run build -w @ae-see-suite/api",
- "build": "npm.cmd run build:web && npm.cmd run build:api",
- "test:api": "npm.cmd run test -w @ae-see-suite/api",
- "frontend:proof:visual": "npm.cmd run proof:visual -w @ae-see-suite/web",
- "frontend:proof:visual:72": "npm.cmd run proof:visual:72 -w @ae-see-suite/web",
- "frontend:proof:pixel": "npm.cmd run proof:pixel -w @ae-see-suite/web",
- "frontend:proof:summary": "npm.cmd run proof:summary -w @ae-see-suite/web",
- "frontend:proof": "npm.cmd run build:web && npm.cmd run frontend:proof:visual && npm.cmd run frontend:proof:pixel && npm.cmd run frontend:proof:summary",
- "proof:see-suite-react": "npm.cmd run build:web && node ./scripts/v4/react-see-suite-proof.mjs --receipt",
+ "check:all": "npm run check && npm run build:web && npm run build:api",
+ "dev:web": "npm run dev -w @ae-see-suite/web",
+ "dev:api": "npm run dev -w @ae-see-suite/api",
+ "build:web": "npm run build -w @ae-see-suite/web",
+ "build:api": "npm run build -w @ae-see-suite/api",
+ "build": "npm run build:web && npm run build:api",
+ "test:api": "npm run test -w @ae-see-suite/api",
+ "frontend:proof:visual": "npm run proof:visual -w @ae-see-suite/web",
+ "frontend:proof:visual:72": "npm run proof:visual:72 -w @ae-see-suite/web",
+ "frontend:proof:pixel": "npm run proof:pixel -w @ae-see-suite/web",
+ "frontend:proof:summary": "npm run proof:summary -w @ae-see-suite/web",
+ "frontend:proof": "npm run build:web && npm run frontend:proof:visual && npm run frontend:proof:pixel && npm run frontend:proof:summary",
+ "proof:see-suite-react": "npm run build:web && node ./scripts/v4/react-see-suite-proof.mjs --receipt",
"proof:see-suite-visual-compare": "node ./scripts/v4/react-see-suite-visual-contact-sheet.mjs",
- "proof:see-suite-72-state": "npm.cmd run build:web && node ./scripts/v4/react-see-suite-72-state-proof.mjs",
+ "proof:see-suite-72-state": "npm run build:web && node ./scripts/v4/react-see-suite-72-state-proof.mjs",
"proof:see-suite-pixel-compare": "node ./scripts/v4/react-see-suite-pixel-compare.mjs",
"mcp": "node ./scripts/orangebox-mcp-server.mjs",
"knowledge": "node ./scripts/orangebox-knowledge-v2.mjs",
@@ -60,7 +60,7 @@
"aecode:operator": "node ./scripts/v4/gauntlet-engine.mjs operator status --json",
"system:proof": "node ./scripts/v4/gauntlet-engine.mjs system proof orangebox-main-system-v0 --json",
"system:full-green": "node ./scripts/v4/gauntlet-engine.mjs system full-green orangebox-main-system-v0 --execute --create --operator-approved --json",
- "machine:test-drive": "npm.cmd run innovation:activate && npm.cmd run ten:finish && npm.cmd run control:big && npm.cmd run inference:doctor && npm.cmd run four:doctor && npm.cmd run system:doctor && npm.cmd run creations:doctor && npm.cmd run aecode:format && npm.cmd run aecode:schemas && npm.cmd run aecode:compile && npm.cmd run aecode:mission-run && npm.cmd run aecode:artifact-generate && npm.cmd run aecode:operator && npm.cmd run system:proof",
+ "machine:test-drive": "npm run innovation:activate && npm run ten:finish && npm run control:big && npm run inference:doctor && npm run four:doctor && npm run system:doctor && npm run creations:doctor && npm run aecode:format && npm run aecode:schemas && npm run aecode:compile && npm run aecode:mission-run && npm run aecode:artifact-generate && npm run aecode:operator && npm run system:proof",
"inference:doctor": "node ./scripts/v4/inference-acceleration-doctor.mjs --json --receipt",
"creations:doctor": "node ./scripts/v4/orangebox-creations-doctor.mjs --json --receipt",
"aecode:format": "node ./scripts/v4/aecode-format-doctor.mjs --json --receipt",
@@ -103,7 +103,7 @@
"control:adapters": "node ./control-plane/run-bun.mjs ./control-plane/adapter-doctor.ts --receipt",
"control:topology": "node ./control-plane/run-bun.mjs ./control-plane/topology-doctor.ts --receipt",
"control:doctor": "node ./control-plane/run-bun.mjs ./control-plane/doctor.ts --receipt",
- "control:big": "npm.cmd run control:topology && npm.cmd run control:adapters && npm.cmd run control:real-smoke && npm.cmd run control:llama-gen && npm.cmd run control:doctor && npm.cmd run control:smoke",
+ "control:big": "npm run control:topology && npm run control:adapters && npm run control:real-smoke && npm run control:llama-gen && npm run control:doctor && npm run control:smoke",
"desktop": "tauri dev",
"desktop:build": "tauri build",
"tauri": "tauri"
diff --git a/scripts/ae-see-suite-mcp-server.mjs b/scripts/ae-see-suite-mcp-server.mjs
new file mode 100644
index 0000000..dc9eab9
--- /dev/null
+++ b/scripts/ae-see-suite-mcp-server.mjs
@@ -0,0 +1,83 @@
+import { McpServer } from "file:///C:/AtomEons/agent-stack/npm-tools/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
+import { StdioServerTransport } from "file:///C:/AtomEons/agent-stack/npm-tools/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js";
+import { z } from "file:///C:/AtomEons/agent-stack/npm-tools/node_modules/zod/index.js";
+import { registerAeSeeSuiteTools } from "./ae-see-suite-mcp-tools.mjs";
+
+const orangeboxUrl = process.env.ORANGEBOX_URL || "http://127.0.0.1:8787";
+
+function textContent(value) {
+ const text = typeof value === "string" ? value : JSON.stringify(value, null, 2);
+ return { content: [{ type: "text", text }] };
+}
+
+async function orangebox(path, { method = "GET", body = null, timeoutMs = 120000 } = {}) {
+ const ac = new AbortController();
+ const timer = setTimeout(() => ac.abort(), timeoutMs);
+ try {
+ const res = await fetch(`${orangeboxUrl}${path}`, {
+ method,
+ headers: { "content-type": "application/json" },
+ body: body ? JSON.stringify(body) : undefined,
+ signal: ac.signal
+ });
+ const text = await res.text();
+ let json = null;
+ try { json = JSON.parse(text); } catch {}
+ if (!res.ok) {
+ return { status: "FAILED", code: res.status, error: json?.error || text || res.statusText };
+ }
+ return json ?? text;
+ } catch (error) {
+ return { status: error.name === "AbortError" ? "TIMEOUT" : "FAILED", error: error.message, orangeboxUrl, path };
+ } finally {
+ clearTimeout(timer);
+ }
+}
+
+function summarize(value, limit = 900) {
+ const text = typeof value === "string" ? value : JSON.stringify(value ?? {}, null, 2);
+ return text.length > limit ? `${text.slice(0, limit)}\n[truncated ${text.length - limit} chars]` : text;
+}
+
+async function postWorkEvent(event) {
+ try {
+ await orangebox("/api/mcp/event", {
+ method: "POST",
+ body: { source: "ae-see-suite-mcp", ...event },
+ timeoutMs: 3000
+ });
+ } catch {}
+}
+
+function resultStatus(result) {
+ try {
+ const text = result?.content?.[0]?.text || "";
+ const parsed = JSON.parse(text);
+ return parsed.status || parsed.recommendation?.status || parsed.event?.status || "VERIFIED";
+ } catch {
+ return "VERIFIED";
+ }
+}
+
+function trackedTool(tool, handler) {
+ return async (args = {}) => {
+ const id = `${Date.now()}-${tool}-${Math.random().toString(16).slice(2)}`;
+ const started = Date.now();
+ await postWorkEvent({ id, tool, phase: "start", status: "Running", summary: summarize(args) });
+ try {
+ const result = await handler(args);
+ await postWorkEvent({ id, tool, phase: "end", status: "VERIFIED", resultStatus: resultStatus(result), durationMs: Date.now() - started, summary: summarize(args, 500) });
+ return result;
+ } catch (error) {
+ await postWorkEvent({ id, tool, phase: "error", status: "FAILED", durationMs: Date.now() - started, summary: summarize(args, 500), error: error.message });
+ throw error;
+ }
+ };
+}
+
+const server = new McpServer({ name: "ae-see-suite", version: "0.1.0" });
+
+registerAeSeeSuiteTools({ server, z, textContent, orangebox, trackedTool });
+
+const transport = new StdioServerTransport();
+await server.connect(transport);
diff --git a/scripts/ae-see-suite-mcp-tools.mjs b/scripts/ae-see-suite-mcp-tools.mjs
new file mode 100644
index 0000000..bd92a96
--- /dev/null
+++ b/scripts/ae-see-suite-mcp-tools.mjs
@@ -0,0 +1,103 @@
+export function registerAeSeeSuiteTools({ server, z, textContent, orangebox, trackedTool }) {
+ const frontendBuild = "npm run build:web";
+
+ async function runCommand(command, timeoutMs = 240000) {
+ return orangebox("/api/v4/mcp/code-execute", {
+ method: "POST",
+ body: { command, timeoutMs, receipt: true },
+ timeoutMs
+ });
+ }
+
+ server.registerTool(
+ "ae_see_suite_help",
+ {
+ title: "AE See-Suite Help",
+ description: "Show the AE See-Suite living dashboard build contract, state atlas workflow, and proof commands.",
+ inputSchema: {}
+ },
+ trackedTool("ae_see_suite_help", async () => textContent({
+ status: "VERIFIED",
+ product: "AE See-Suite living AI operating environment",
+ law: "One AppShell, many semantic states. Never build 72 pages or use mockup images as UI.",
+ anchors: ["01 Calm", "06 Alert", "22 Temporal Memory", "26 Command Palette", "37 Agent Queue", "61 Living Canvas"],
+ commands: {
+ build: frontendBuild,
+ proofAnchors: "npm run build:web && npm run frontend:proof:visual -- --states=01,06,22,26,37,61 --label=mcp-anchors",
+ proof72: "npm run build:web && npm run frontend:proof:visual:72"
+ },
+ nextGoal: "Convert state atlas surfaces into real product behavior driven by Zustand state, user actions, and backend stream events."
+ }))
+ );
+
+ server.registerTool(
+ "ae_see_suite_build_frontend",
+ {
+ title: "Build AE See-Suite Frontend",
+ description: "Run the frontend TypeScript/Vite build through the receipted OrangeBOX executor.",
+ inputSchema: {}
+ },
+ trackedTool("ae_see_suite_build_frontend", async () => textContent(await runCommand(frontendBuild, 240000)))
+ );
+
+ server.registerTool(
+ "ae_see_suite_proof_anchors",
+ {
+ title: "Proof AE See-Suite Anchor States",
+ description: "Build and capture the highest-value AE See-Suite anchor states: 01, 06, 22, 26, 37, 61.",
+ inputSchema: {
+ states: z.string().optional().describe("Comma-separated state ids. Default: 01,06,22,26,37,61"),
+ label: z.string().optional().describe("Visual proof label. Default: mcp-anchors")
+ }
+ },
+ trackedTool("ae_see_suite_proof_anchors", async ({ states = "01,06,22,26,37,61", label = "mcp-anchors" }) => {
+ const command = `npm run build:web && npm run frontend:proof:visual -- --states=${states} --label=${label}`;
+ return textContent(await runCommand(command, 420000));
+ })
+ );
+
+ server.registerTool(
+ "ae_see_suite_proof_72",
+ {
+ title: "Proof AE See-Suite 72-State Atlas",
+ description: "Build and capture all 72 AE See-Suite state atlas entries.",
+ inputSchema: {
+ label: z.string().optional().describe("Visual proof label. Default: mcp-72-state")
+ }
+ },
+ trackedTool("ae_see_suite_proof_72", async ({ label = "mcp-72-state" }) => {
+ const command = `npm run build:web && npm run frontend:proof:visual:72 -- --label=${label}`;
+ return textContent(await runCommand(command, 900000));
+ })
+ );
+
+ server.registerTool(
+ "ae_see_suite_state_open_command",
+ {
+ title: "AE See-Suite State URL Helper",
+ description: "Return direct local URLs and acceptance checks for a state atlas id.",
+ inputSchema: {
+ state: z.string().describe("State id such as 01, 06, 22, 26, 37, or 61."),
+ baseUrl: z.string().optional().describe("Frontend base URL. Default http://localhost:5173")
+ }
+ },
+ trackedTool("ae_see_suite_state_open_command", async ({ state, baseUrl = "http://localhost:5173" }) => {
+ const normalized = String(state).padStart(2, "0");
+ const acceptance = {
+ "01": ["calm shell", "no forced incident", "panels readable", "chat dock available"],
+ "06": ["alert mode", "causal path visible", "watcher/analyst active", "remediation suggestions"],
+ "22": ["temporal expanded overlay", "timeline events visible", "scrub controls visible", "composer can receive timeline prompt"],
+ "26": ["command palette open", "dashboard recessed", "actions searchable"],
+ "37": ["agent queue drawer open", "tasks/agents visible", "dashboard remains behind drawer"],
+ "61": ["living canvas primary", "artifact branches visible", "chat dock remains command surface"]
+ };
+ return textContent({
+ status: "VERIFIED",
+ state: normalized,
+ url: `${baseUrl}/?state=${normalized}`,
+ acceptance: acceptance[normalized] ?? ["same AppShell", "state reachable", "no mockup image as UI"],
+ note: "Use this as a local browser target or proof-run target."
+ });
+ })
+ );
+}