(function () {
"use strict";
const pageDefinitions = [
{ index: 0, label: "整车联合数字孪生", shortLabel: "数字孪生", target: ".joint-twin-shell" },
{ index: 1, label: "决策轨迹与校验", shortLabel: "决策校验", target: "#panel-trace" },
{ index: 2, label: "指令配置与硬件映射", shortLabel: "配置映射", target: "#panel-config" },
{ index: 3, label: "CAN 编译计划", shortLabel: "CAN 计划", target: "#panel-plan" },
{ index: 4, label: "执行结果与硬件回读", shortLabel: "执行回读", target: "#panel-result" },
];
const $ = (selector, root = document) => root.querySelector(selector);
const $$ = (selector, root = document) => [...root.querySelectorAll(selector)];
const initialRole = sessionStorage.getItem("cognitive-agent.demo-role") === "admin"
? "admin"
: "user";
const storedModule = sessionStorage.getItem("cognitive-agent.active-module");
const ui = {
role: initialRole,
controlMode: sessionStorage.getItem("cognitive-agent.control-mode") === "gesture"
? "gesture"
: "natural",
activeModule: storedModule === "self-extension"
? "self-extension"
: storedModule === "self-calibration"
? "self-calibration"
: storedModule === "self-repair"
? "self-repair"
: "self-orchestration",
activePage: 0,
sidebarCollapsed: sessionStorage.getItem("cognitive-agent.sidebar-collapsed") === "true",
};
const dropdownControls = new Map();
function make(tag, className, html) {
const node = document.createElement(tag);
if (className) node.className = className;
if (html != null) node.innerHTML = html;
return node;
}
function closeCustomDropdowns(except = null) {
dropdownControls.forEach((control) => {
if (control !== except) control.close();
});
}
function enhanceSelect(select) {
if (!select || dropdownControls.has(select)) return;
const shell = select.parentElement;
if (!shell) return;
shell.classList.add("v2-custom-select");
select.classList.add("v2-native-select");
const trigger = make("button", "v2-dropdown-trigger", `
`);
trigger.type = "button";
trigger.setAttribute("aria-haspopup", "listbox");
trigger.setAttribute("aria-expanded", "false");
trigger.setAttribute("aria-label", select.getAttribute("aria-label") || "打开下拉菜单");
const menu = make("div", "v2-dropdown-menu", "");
menu.id = `${select.id}Menu`;
menu.hidden = true;
menu.setAttribute("role", "listbox");
menu.setAttribute("aria-label", select.getAttribute("aria-label") || "选项");
trigger.setAttribute("aria-controls", menu.id);
shell.append(trigger, menu);
const valueNode = $(".v2-dropdown-value", trigger);
const render = () => {
const selected = select.selectedOptions[0] || select.options[0];
valueNode.textContent = selected?.textContent?.trim() || "请选择";
trigger.disabled = select.disabled;
menu.innerHTML = "";
[...select.options].forEach((option) => {
const item = make("button", "v2-dropdown-option", "");
item.type = "button";
item.dataset.value = option.value;
item.textContent = option.textContent.trim();
item.disabled = option.disabled;
item.setAttribute("role", "option");
item.setAttribute("aria-selected", String(option.value === select.value));
menu.append(item);
});
};
const close = () => {
menu.hidden = true;
shell.classList.remove("v2-dropdown-open");
trigger.setAttribute("aria-expanded", "false");
};
const open = () => {
if (trigger.disabled) return;
closeCustomDropdowns();
render();
menu.hidden = false;
shell.classList.add("v2-dropdown-open");
trigger.setAttribute("aria-expanded", "true");
};
const control = { close, menu, open, select, shell, sync: render, trigger };
dropdownControls.set(select, control);
trigger.addEventListener("click", (event) => {
event.stopPropagation();
if (menu.hidden) open();
else close();
});
trigger.addEventListener("keydown", (event) => {
if (event.key === "ArrowDown") {
event.preventDefault();
open();
requestAnimationFrame(() => {
$(".v2-dropdown-option[aria-selected=\"true\"]:not(:disabled)", menu)?.focus();
});
} else if (event.key === "Escape") {
close();
}
});
menu.addEventListener("click", (event) => {
event.stopPropagation();
const item = event.target.closest(".v2-dropdown-option");
if (!item || item.disabled) return;
select.value = item.dataset.value;
select.dispatchEvent(new Event("change", { bubbles: true }));
render();
close();
trigger.focus();
});
menu.addEventListener("keydown", (event) => {
if (event.key !== "Escape") return;
event.preventDefault();
close();
trigger.focus();
});
select.addEventListener("change", render);
new MutationObserver(render).observe(select, {
attributes: true,
characterData: true,
childList: true,
subtree: true,
});
render();
}
function enhanceConfiguredDropdowns() {
[$("#v2RoleSelect"), $("#vehicleSelect"), $("#v2ExecutionSelect")]
.filter(Boolean)
.forEach(enhanceSelect);
}
function buildSidebar(commandPanel) {
commandPanel.classList.add("v2-sidebar");
commandPanel.innerHTML = "";
const profile = make("section", "v2-profile", `
WELCOME TO THE CABIN
Hi,
Hi,user
`);
const control = make("section", "v2-sidebar-section v2-control-section", `
CONTROL DESK
控制台
控制方式
`);
const config = make("section", "v2-sidebar-section v2-config-section", `
配置信息
`);
const footer = make("footer", "v2-sidebar-footer", `
智舱控制链路正在连接服务
`);
commandPanel.append(profile, control, config, footer);
$("#v2RoleSelect").value = ui.role;
return $("#v2ConfigStack");
}
function buildConfigFields(configStack, originalForm) {
const vehicleField = $(".vehicle-field", originalForm);
const providerField = $(".field-group:has(.segmented [data-provider])", originalForm);
const executionField = $(".field-group:has(.execution-mode-options)", originalForm);
const simulationFaultField = $("#simulationFaultField", originalForm);
const approvalField = $("#approvalField", originalForm);
if (vehicleField) {
vehicleField.classList.add("v2-config-field", "v2-vehicle-field");
const vehicleControl = $(".vehicle-select-control", vehicleField);
const vehicleSelect = $("#vehicleSelect", vehicleField);
const vehicleIcon = $("svg, [data-lucide]", vehicleControl);
if (vehicleControl && vehicleSelect && vehicleIcon) {
const copy = make("div", "v2-config-card-copy", "车型配置");
const selectSlot = make("div", "v2-config-card-select", "");
const state = make("span", "v2-field-state", "CHECK");
state.id = "v2VehicleState";
selectSlot.append(vehicleSelect);
copy.append(selectSlot);
vehicleControl.classList.add("v2-config-card", "v2-config-select-card");
vehicleControl.id = "v2VehicleCard";
vehicleControl.dataset.state = "checking";
vehicleControl.replaceChildren(vehicleIcon, copy, state);
$(".field-label", vehicleField)?.remove();
}
configStack.append(vehicleField);
}
const modelField = make("div", "v2-config-field v2-config-card v2-model-field", `
推理模型模型检测中
AUTO
模型由服务端安全配置
`);
modelField.id = "v2ModelField";
configStack.append(modelField);
const gestureModelField = make("div", "v2-config-field v2-config-card v2-gesture-model-field", `
手势模型MediaPipe GR
VISION
Tasks Vision · 0.10.14`);
gestureModelField.id = "v2GestureModelField";
configStack.append(gestureModelField);
const userHardwareState = make("div", "v2-user-target-status", `
正在检查真实台架`);
configStack.append(userHardwareState);
if (providerField) {
providerField.classList.add("v2-provider-field");
providerField.hidden = true;
configStack.append(providerField);
}
const executionSelect = make("div", "v2-config-field v2-execution-field", `
管理员可切换执行环境
`);
configStack.append(executionSelect);
if (executionField) {
executionField.classList.add("v2-native-execution-field");
executionField.hidden = true;
configStack.append(executionField);
}
const advanced = make("div", "v2-advanced-stack", "");
[simulationFaultField, approvalField].forEach((field) => {
if (!field) return;
field.classList.add("v2-config-field", "v2-advanced-field");
advanced.append(field);
});
configStack.append(advanced);
}
function buildOperation(mainPanel, originalForm, panelHeading, modeRail, requestHeader, gestureDrawer) {
const operation = make("section", "v2-operation-shell", `
`);
mainPanel.prepend(operation);
const naturalPanel = $("#v2NaturalPanel");
if (panelHeading) {
panelHeading.classList.add("v2-operation-heading");
const kicker = $(".section-kicker", panelHeading);
const title = $("h2", panelHeading);
const intro = $(".panel-intro", panelHeading);
if (kicker) kicker.textContent = "自然语言控制";
if (title) title.textContent = "一句话,调好整车";
if (intro) intro.textContent = "座椅、空调、天幕与氛围灯,一句话联动完成";
naturalPanel.append(panelHeading);
}
const naturalGrid = make("div", "v2-natural-grid", "");
naturalGrid.id = "v2NaturalGrid";
originalForm.classList.add("v2-request-form");
naturalGrid.append(originalForm);
if (requestHeader) {
requestHeader.classList.add("v2-request-status");
naturalGrid.append(requestHeader);
}
naturalPanel.append(naturalGrid);
if (modeRail) {
modeRail.classList.add("v2-mode-rail");
naturalPanel.append(modeRail);
}
const gesturePanel = $("#v2GesturePanel");
const gestureHeading = make("header", "v2-operation-heading v2-gesture-operation-heading", `
手势控制
抬抬手,控制整车
通过摄像头识别手势,直观控制车舱功能
`);
gesturePanel.append(gestureHeading);
if (gestureDrawer) {
gestureDrawer.classList.add("v2-inline-gesture");
const cameraStage = $(".gesture-camera-stage", gestureDrawer);
const cameraToggle = $("#gestureStartButton", gestureDrawer);
const debugToggle = $("#gestureArmButton", gestureDrawer);
const actionRail = $(".gesture-actions", gestureDrawer);
const statusStrip = $(".gesture-status-strip", gestureDrawer);
const gestureNow = $(".gesture-now", gestureDrawer);
const guideCard = $(".gesture-guide-card", gestureDrawer);
if (cameraToggle) {
cameraToggle.classList.add("v2-camera-toggle");
cameraToggle.setAttribute("aria-label", "开启摄像头");
cameraToggle.setAttribute("title", "开启摄像头");
}
if (actionRail && cameraToggle && debugToggle) {
actionRail.classList.add("v2-gesture-action-rail");
actionRail.insertBefore(debugToggle, cameraToggle);
actionRail.append(cameraToggle);
}
const resultStack = make("div", "v2-gesture-result-stack", "");
resultStack.id = "v2GestureResultStack";
const recognitionCard = make("section", "v2-gesture-recognition-card", `
手势识别结果`);
const executionSlot = make("section", "v2-gesture-execution-slot", `
执行结果`);
executionSlot.id = "v2GestureExecutionSlot";
if (statusStrip) recognitionCard.append(statusStrip);
if (gestureNow) recognitionCard.append(gestureNow);
resultStack.append(recognitionCard, executionSlot);
if (cameraStage) gestureDrawer.append(cameraStage);
if (actionRail) gestureDrawer.append(actionRail);
gestureDrawer.append(resultStack);
if (guideCard) gestureDrawer.append(guideCard);
gesturePanel.append(gestureDrawer);
}
return operation;
}
function buildModuleSwitcher(mainPanel) {
const modules = [
{ id: "self-orchestration", label: "自编排", available: true },
{
id: "self-calibration",
label: "自标定",
available: true,
adminOnly: true,
},
{ id: "self-extension", label: "自扩展", available: true },
{
id: "self-repair",
label: "自修复",
available: true,
adminOnly: true,
},
];
const switcher = make("nav", "v2-module-switcher", "");
switcher.id = "v2ModuleSwitcher";
switcher.setAttribute("role", "tablist");
switcher.setAttribute("aria-label", "能力模块切换");
modules.forEach((module, index) => {
const button = make("button", "v2-module-tab", `${module.label}`);
button.type = "button";
button.id = `v2ModuleTab${index}`;
button.dataset.module = module.id;
button.setAttribute("role", "tab");
button.setAttribute("aria-selected", "false");
if (module.adminOnly) button.dataset.adminOnly = "true";
if (!module.available) {
button.disabled = true;
button.setAttribute("aria-disabled", "true");
button.title = module.adminOnly ? `${module.label}仅对 admin 开放` : `${module.label}模块待接入`;
}
switcher.append(button);
});
mainPanel.prepend(switcher);
}
function buildOutput(mainPanel) {
const output = make("section", "v2-output-shell", `
`);
mainPanel.append(output);
const content = $("#v2OutputContent");
const twin = $(".joint-twin-shell", mainPanel);
const resultWorkspace = $(".result-workspace", mainPanel);
if (twin) content.append(twin);
if (resultWorkspace) content.append(resultWorkspace);
pageDefinitions.forEach((page) => {
const target = $(page.target, content);
if (!target) return;
target.dataset.v2Page = String(page.index);
target.classList.add("v2-output-page");
});
pageDefinitions.forEach((page) => {
const button = make("button", "v2-page-button", `
${String(page.index).padStart(2, "0")}
${page.shortLabel}`);
button.type = "button";
button.dataset.v2PageTarget = String(page.index);
button.setAttribute("aria-label", `${String(page.index).padStart(2, "0")} ${page.label}`);
$("#v2PageRail").append(button);
});
}
function setPage(pageIndex) {
const maxPage = ui.role === "admin" ? pageDefinitions.length - 1 : 0;
ui.activePage = Math.max(0, Math.min(Number(pageIndex) || 0, maxPage));
const definition = pageDefinitions[ui.activePage];
$(".v2-output-shell")?.classList.toggle("v2-twin-active", definition.index === 0);
$$(".v2-output-page").forEach((page) => {
const active = Number(page.dataset.v2Page) === ui.activePage;
page.classList.toggle("v2-active-output", active);
page.setAttribute("aria-hidden", active ? "false" : "true");
});
$$(".v2-page-button").forEach((button) => {
const active = Number(button.dataset.v2PageTarget) === ui.activePage;
button.classList.toggle("active", active);
button.setAttribute("aria-current", active ? "page" : "false");
});
$("#v2PageIndex").textContent = String(definition.index).padStart(2, "0");
$("#v2PageTitle").textContent = definition.label;
$("#v2OutputState").textContent = definition.index === 0 ? "LIVE STATE" : "AUDIT VIEW";
requestAnimationFrame(updateScrollCues);
}
function updateScrollCues() {
$$(".result-workspace .tab-panel").forEach((panel) => {
const active = panel.classList.contains("v2-active-output");
panel.classList.toggle(
"v2-scrollable",
active && panel.scrollHeight > panel.clientHeight + 6,
);
});
}
function updateModeEdgeHints() {
const chips = $(".v2-mode-rail .mode-chips");
if (!chips) return;
const buttons = $$('button', chips);
buttons.forEach((button) => {
button.classList.remove("v2-edge-fade-left", "v2-edge-fade-right");
button.style.removeProperty("--v2-edge-fade-start");
button.style.removeProperty("--v2-edge-fade-end");
});
if (buttons.length < 2 || chips.clientWidth <= 0) return;
const viewport = chips.getBoundingClientRect();
const visible = buttons.map((button) => ({
button,
rect: button.getBoundingClientRect(),
})).filter(({ rect }) => {
return rect.right > viewport.left + 1 && rect.left < viewport.right - 1;
});
if (!visible.length) return;
const fadeSpan = 30;
const firstVisible = visible[0];
const lastVisible = visible[visible.length - 1];
if (firstVisible.rect.left < viewport.left - 1) {
const clippedAt = Math.min(100, Math.max(
0,
((viewport.left - firstVisible.rect.left) / firstVisible.rect.width) * 100,
));
firstVisible.button.style.setProperty("--v2-edge-fade-start", `${clippedAt}%`);
firstVisible.button.style.setProperty(
"--v2-edge-fade-end",
`${Math.min(100, clippedAt + fadeSpan)}%`,
);
firstVisible.button.classList.add("v2-edge-fade-left");
}
if (lastVisible.rect.right > viewport.right + 1) {
const clippedAt = Math.min(100, Math.max(
0,
((viewport.right - lastVisible.rect.left) / lastVisible.rect.width) * 100,
));
lastVisible.button.style.setProperty(
"--v2-edge-fade-start",
`${Math.max(0, clippedAt - fadeSpan)}%`,
);
lastVisible.button.style.setProperty("--v2-edge-fade-end", `${clippedAt}%`);
lastVisible.button.classList.add("v2-edge-fade-right");
}
}
function setControlMode(mode, { triggerGesture = true } = {}) {
ui.controlMode = mode === "gesture" ? "gesture" : "natural";
sessionStorage.setItem("cognitive-agent.control-mode", ui.controlMode);
document.body.dataset.controlMode = ui.controlMode;
const requestStatus = $(".v2-request-status");
const statusTarget = ui.controlMode === "gesture"
? $("#v2GestureExecutionSlot")
: $("#v2NaturalGrid");
if (requestStatus && statusTarget && requestStatus.parentElement !== statusTarget) {
statusTarget.append(requestStatus);
}
$$('[data-v2-control]').forEach((button) => {
const active = button.dataset.v2Control === ui.controlMode;
button.classList.toggle("active", active);
button.setAttribute("aria-pressed", String(active));
});
requestAnimationFrame(updateModeEdgeHints);
const drawer = $("#gestureDrawer");
if (!triggerGesture) {
const gestureVisible = ui.controlMode === "gesture";
drawer?.setAttribute("aria-hidden", String(!gestureVisible));
$("#gestureToggleButton")?.setAttribute("aria-expanded", String(gestureVisible));
return;
}
if (ui.controlMode === "gesture") {
if (!drawer?.classList.contains("open")) $("#gestureToggleButton")?.click();
} else if (drawer?.classList.contains("open")) {
$("#gestureCloseButton")?.click();
}
}
function setModule(module, { persist = true } = {}) {
if (["self-calibration", "self-repair"].includes(module) && ui.role !== "admin") {
setRole("admin");
}
const allowed = new Set(["self-orchestration", "self-extension"]);
if (ui.role === "admin") {
allowed.add("self-calibration");
allowed.add("self-repair");
}
ui.activeModule = allowed.has(module) ? module : "self-orchestration";
if (persist) {
sessionStorage.setItem("cognitive-agent.active-module", ui.activeModule);
}
document.body.dataset.module = ui.activeModule;
const roleSelect = $("#v2RoleSelect");
if (roleSelect) {
roleSelect.disabled = ui.activeModule === "self-repair";
dropdownControls.get(roleSelect)?.sync();
}
$$('.v2-module-tab').forEach((button) => {
const active = button.dataset.module === ui.activeModule;
button.classList.toggle("active", active);
button.setAttribute("aria-selected", String(active));
button.tabIndex = active ? 0 : -1;
});
if (["self-extension", "self-calibration", "self-repair"].includes(ui.activeModule)) {
const drawer = $("#gestureDrawer");
if (drawer?.classList.contains("open")) $("#gestureCloseButton")?.click();
} else {
setControlMode(ui.controlMode, { triggerGesture: false });
}
window.dispatchEvent(new CustomEvent("cognitive-agent:module-change", {
detail: { module: ui.activeModule },
}));
window.setTimeout(() => window.dispatchEvent(new Event("resize")), 120);
}
function setRole(role) {
if (ui.activeModule === "self-repair" && role !== "admin") {
const roleSelect = $("#v2RoleSelect");
if (roleSelect) {
roleSelect.value = "admin";
dropdownControls.get(roleSelect)?.sync();
}
return;
}
ui.role = role === "admin" ? "admin" : "user";
sessionStorage.setItem("cognitive-agent.demo-role", ui.role);
document.body.dataset.demoRole = ui.role;
window.dispatchEvent(new CustomEvent("cognitive-agent:demo-role-change", {
detail: { role: ui.role },
}));
$("#v2RoleSelect").value = ui.role;
dropdownControls.get($("#v2RoleSelect"))?.sync();
$("#v2PageRail").hidden = ui.role !== "admin";
const calibrationTab = $('.v2-module-tab[data-module="self-calibration"]');
if (calibrationTab) {
calibrationTab.disabled = false;
calibrationTab.setAttribute("aria-disabled", "false");
calibrationTab.title = ui.role === "admin"
? ""
: "进入自标定时将自动切换为 admin";
}
const repairTab = $('.v2-module-tab[data-module="self-repair"]');
if (repairTab) {
repairTab.hidden = false;
repairTab.disabled = false;
repairTab.setAttribute("aria-disabled", "false");
repairTab.title = ui.role === "admin"
? ""
: "进入自修复时将自动切换为 admin";
}
if (ui.role !== "admin") {
if (["self-calibration", "self-repair"].includes(ui.activeModule)) {
setModule("self-orchestration");
}
setPage(0);
requestUserHardwareMode();
} else {
const note = $("#v2ExecutionNote");
if (note) note.textContent = "管理员可切换虚拟 CAN、模拟台架与真实台架";
const runButton = $("#runButton");
if (runButton && !runButton.classList.contains("loading")) runButton.disabled = false;
syncExecutionSelector();
}
}
function setSidebarCollapsed(collapsed) {
ui.sidebarCollapsed = Boolean(collapsed);
sessionStorage.setItem(
"cognitive-agent.sidebar-collapsed",
String(ui.sidebarCollapsed),
);
document.body.classList.toggle("v2-sidebar-collapsed", ui.sidebarCollapsed);
const button = $("#v2SidebarToggle");
if (button) {
button.setAttribute("aria-expanded", String(!ui.sidebarCollapsed));
button.setAttribute(
"aria-label",
ui.sidebarCollapsed ? "展开左侧控制台" : "折叠左侧控制台",
);
button.innerHTML = ``;
}
window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } });
window.setTimeout(() => window.dispatchEvent(new Event("resize")), 180);
}
function requestUserHardwareMode() {
const hardwareButton = $("#hardwareMode");
const note = $("#v2ExecutionNote");
const userTarget = $(".v2-user-target-status");
const userTargetText = $("#v2UserTargetText");
const runButton = $("#runButton");
if (!hardwareButton) return;
if (!hardwareButton.disabled) {
if (!hardwareButton.classList.contains("active")) hardwareButton.click();
if (note) note.textContent = "user 演示固定使用真实台架";
if (userTarget) userTarget.dataset.state = "ready";
if (userTargetText) userTargetText.textContent = "执行目标:真实台架";
if (runButton && !runButton.classList.contains("loading")) runButton.disabled = false;
} else if (note) {
note.textContent = "真实台架尚未就绪,服务端安全门禁保持锁定";
if (userTarget) userTarget.dataset.state = "locked";
if (userTargetText) userTargetText.textContent = "真实台架尚未就绪";
if (runButton) runButton.disabled = true;
}
}
function syncExecutionSelector() {
const select = $("#v2ExecutionSelect");
if (!select) return;
const active = $('[data-execution-mode].active');
if (active) select.value = active.dataset.executionMode;
["dry_run", "simulated_hardware", "hardware"].forEach((value) => {
const option = $(`option[value="${value}"]`, select);
const button = $(`[data-execution-mode="${value}"]`);
if (option && button) option.disabled = button.disabled;
});
dropdownControls.get(select)?.sync();
}
function syncRuntimePresentation() {
const modelBadge = $("#modelBadge");
const connectionBadge = $("#connectionBadge");
const modelValue = $("#v2ModelValue");
const modelNote = $("#v2ModelNote");
const connectionText = $("#v2ConnectionText");
if (modelBadge && modelValue) {
const text = modelBadge.textContent.trim() || "模型检测中";
modelValue.textContent = text;
const unavailable = modelBadge.classList.contains("danger");
$("#v2ModelField")?.classList.toggle("unavailable", unavailable);
$("#v2ModelState").textContent = unavailable ? "LOCAL" : "READY";
if (modelNote) modelNote.textContent = unavailable
? "GPT 不可用,自动使用本地规则"
: "服务端安全托管 · 失败自动降级";
}
if (connectionBadge && connectionText) {
connectionText.textContent = connectionBadge.textContent.trim() || "正在连接服务";
const online = !connectionBadge.classList.contains("danger")
&& !connectionBadge.classList.contains("warning");
$(".v2-sidebar-footer")?.classList.toggle("offline", !online);
}
syncExecutionSelector();
if (ui.role === "user") requestUserHardwareMode();
}
function setVehicleLinkState(connected) {
const card = $("#v2VehicleCard");
const state = $("#v2VehicleState");
if (!card || !state) return;
card.dataset.state = connected ? "online" : "offline";
state.textContent = connected ? "READY" : "OFFLINE";
}
async function refreshVehicleLinkState() {
const card = $("#v2VehicleCard");
const state = $("#v2VehicleState");
if (card) card.dataset.state = "checking";
if (state) state.textContent = "CHECK";
try {
const response = await fetch("/api/extension/health", {
credentials: "same-origin",
headers: { Accept: "application/json" },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const health = await response.json();
setVehicleLinkState(Boolean(health.vehicle?.connected));
} catch (_error) {
setVehicleLinkState(false);
}
}
function bindEvents() {
$("#v2RoleSelect")?.addEventListener("change", (event) => setRole(event.target.value));
$$('[data-v2-control]').forEach((button) => {
button.addEventListener("click", () => setControlMode(button.dataset.v2Control));
});
$$('.v2-module-tab').forEach((button) => {
button.addEventListener("click", () => {
if (!button.disabled) setModule(button.dataset.module);
});
});
$("#v2ExecutionSelect")?.addEventListener("change", (event) => {
$(`[data-execution-mode="${event.target.value}"]`)?.click();
syncExecutionSelector();
});
$$(".v2-page-button").forEach((button) => {
button.addEventListener("click", () => setPage(button.dataset.v2PageTarget));
});
$("#v2LogoutButton")?.addEventListener("click", () => $("#logoutButton")?.click());
window.addEventListener("cognitive-agent:connection", (event) => {
if (event.detail?.status === "online") refreshVehicleLinkState();
else if (["offline", "degraded"].includes(event.detail?.status)) setVehicleLinkState(false);
});
$("#v2SidebarToggle")?.addEventListener(
"click",
() => setSidebarCollapsed(!ui.sidebarCollapsed),
);
document.addEventListener("click", () => closeCustomDropdowns());
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") closeCustomDropdowns();
});
window.addEventListener("resize", updateScrollCues);
window.addEventListener("resize", updateModeEdgeHints);
window.addEventListener("cognitive-agent:result", () => requestAnimationFrame(updateScrollCues));
const modeChips = $(".v2-mode-rail .mode-chips");
modeChips?.addEventListener(
"scroll",
() => requestAnimationFrame(updateModeEdgeHints),
{ passive: true },
);
if (modeChips) {
new MutationObserver(() => requestAnimationFrame(updateModeEdgeHints))
.observe(modeChips, { childList: true });
}
const observer = new MutationObserver(syncRuntimePresentation);
[$("#modelBadge"), $("#connectionBadge"), $("#hardwareMode"), $("#simulationMode")]
.filter(Boolean)
.forEach((node) => observer.observe(node, {
attributes: true,
childList: true,
subtree: true,
characterData: true,
}));
}
function init() {
const workspace = $(".workspace");
const commandPanel = $(".command-panel");
const mainPanel = $(".main-panel");
const originalForm = $("#requestForm");
if (!workspace || !commandPanel || !mainPanel || !originalForm) return;
document.body.classList.add("console-v2");
const panelHeading = $(".panel-heading", commandPanel);
const modeRail = $(".mode-rail", commandPanel);
const exampleGroup = $(".example-group", commandPanel);
const safetyStrip = $("#safetyStrip", commandPanel);
const requestHeader = $(".request-header", mainPanel);
const gestureDrawer = $("#gestureDrawer");
const detached = {
panelHeading,
modeRail,
requestHeader,
gestureDrawer,
originalForm,
exampleGroup,
safetyStrip,
};
Object.values(detached).filter(Boolean).forEach((node) => node.remove());
const legacyParking = make("div", "v2-legacy-parking v2-legacy-hidden", "");
[exampleGroup, safetyStrip].filter(Boolean).forEach((node) => legacyParking.append(node));
document.body.append(legacyParking);
const configStack = buildSidebar(commandPanel);
buildConfigFields(configStack, originalForm);
enhanceConfiguredDropdowns();
buildOperation(
mainPanel,
originalForm,
panelHeading,
modeRail,
requestHeader,
gestureDrawer,
);
buildModuleSwitcher(mainPanel);
$(".pipeline", mainPanel)?.classList.add("v2-legacy-hidden");
$(".topbar")?.classList.add("v2-legacy-hidden");
$(".gesture-backdrop")?.classList.add("v2-legacy-hidden");
buildOutput(mainPanel);
bindEvents();
setControlMode(ui.controlMode, { triggerGesture: false });
setModule(ui.activeModule, { persist: false });
setRole(ui.role);
setSidebarCollapsed(ui.sidebarCollapsed);
setPage(0);
syncRuntimePresentation();
refreshVehicleLinkState();
window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } });
requestAnimationFrame(() => {
updateModeEdgeHints();
document.body.classList.add("v2-ready");
});
}
window.CognitiveAgentConsoleV2 = {
enhanceSelect,
getModule: () => ui.activeModule,
getRole: () => ui.role,
setModule,
};
document.addEventListener("DOMContentLoaded", init);
}());