// umbrella_inline.js — mounts the Cortex-OS graph inside Hermes WebUI's // Workspace right panel. Plugin-only shim; the standalone page remains a // fallback at /plugins/svrnty/umbrella.html. (function () { "use strict"; if (window.__svrntyUmbrellaInlineLoaded) return; window.__svrntyUmbrellaInlineLoaded = true; const LOG = (...a) => console.log("[svrnty-umbrella-inline]", ...a); const ICON = ''; let surface = null; let graphOpen = false; let previousHeading = "Workspace"; let previousPanelWidth = ""; let openedPanelForGraph = false; function $(id) { return document.getElementById(id); } function isWorkspacePanelOpen() { const htmlState = document.documentElement.dataset.workspacePanel; const panel = document.querySelector(".rightpanel"); return htmlState === "open" && !!panel && getComputedStyle(panel).pointerEvents !== "none"; } function ensureSurface() { if (surface && document.body.contains(surface)) return surface; const panel = document.querySelector(".rightpanel"); const preview = $("previewArea"); if (!panel || !preview) return null; surface = document.createElement("div"); surface.id = "svrntyUmbrellaInlineSurface"; surface.className = "svrnty-umbrella-inline-surface"; surface.dataset.open = "false"; surface.innerHTML = ''; preview.insertAdjacentElement("afterend", surface); return surface; } function setWorkspaceSurfaces(mode) { const fileTree = $("fileTree"); const empty = $("wsEmptyState"); const preview = $("previewArea"); const breadcrumb = $("breadcrumbBar"); const graph = ensureSurface(); if (!graph) return; const showGraph = mode === "graph"; if (fileTree) fileTree.style.display = showGraph ? "none" : ""; if (empty) empty.style.display = showGraph ? "none" : empty.style.display; if (preview) preview.style.display = showGraph ? "none" : ""; if (breadcrumb) breadcrumb.style.display = showGraph ? "none" : breadcrumb.style.display; graph.dataset.open = showGraph ? "true" : "false"; } function syncHeader(open) { const heading = $("workspacePanelHeading"); const button = $("btnSvrntyWorkspaceGraph"); if (heading) { if (open) { previousHeading = heading.textContent || "Workspace"; heading.textContent = "Project Graph"; heading.title = "Project Graph"; } else { heading.textContent = previousHeading || "Workspace"; heading.title = "Workspace root"; } } if (button) { button.classList.toggle("active", open); button.setAttribute("aria-pressed", open ? "true" : "false"); } } function resizeGraphSoon() { const frame = surface && surface.querySelector("iframe"); if (!frame) return; setTimeout(() => { try { const cy = frame.contentWindow && frame.contentWindow.cy; if (cy) { cy.resize(); cy.fit(null, 24); } } catch (_) {} }, 250); } function expandPanelForGraph() { const panel = document.querySelector(".rightpanel"); if (!panel) return; previousPanelWidth = panel.style.width || ""; const current = panel.getBoundingClientRect().width || 0; if (current < 480) { panel.style.width = "500px"; } } function restorePanelWidth() { const panel = document.querySelector(".rightpanel"); if (!panel) return; panel.style.width = previousPanelWidth; previousPanelWidth = ""; } function openWorkspaceGraph() { if (graphOpen) { resizeGraphSoon(); return; } openedPanelForGraph = !isWorkspacePanelOpen(); if (typeof window.openWorkspacePanel === "function") { window.openWorkspacePanel("browse"); } else if (typeof window.toggleWorkspacePanel === "function") { window.toggleWorkspacePanel(true); } expandPanelForGraph(); graphOpen = true; setWorkspaceSurfaces("graph"); syncHeader(true); resizeGraphSoon(); LOG("opened inline graph"); } function closeWorkspaceGraph() { if (!graphOpen) return false; graphOpen = false; setWorkspaceSurfaces("workspace"); syncHeader(false); restorePanelWidth(); if (openedPanelForGraph && typeof window.closeWorkspacePanel === "function") { window.closeWorkspacePanel(); } else if (typeof window.renderBreadcrumb === "function") { window.renderBreadcrumb(); } openedPanelForGraph = false; LOG("closed inline graph"); return true; } function injectButton() { const actions = document.querySelector(".rightpanel .panel-actions"); if (!actions || $("btnSvrntyWorkspaceGraph")) return !!actions; const refresh = $("btnRefreshPanel"); const btn = document.createElement("button"); btn.className = "panel-icon-btn has-tooltip has-tooltip--bottom svrnty-graph-btn"; btn.id = "btnSvrntyWorkspaceGraph"; btn.type = "button"; btn.dataset.tooltip = "Project graph"; btn.setAttribute("aria-label", "Open project graph"); btn.setAttribute("aria-pressed", "false"); btn.innerHTML = ICON; btn.addEventListener("click", (event) => { event.preventDefault(); event.stopPropagation(); openWorkspaceGraph(); }); if (refresh && refresh.parentElement === actions) { refresh.insertAdjacentElement("afterend", btn); } else { actions.appendChild(btn); } ensureSurface(); return true; } function interceptCloseButton() { const close = $("btnClearPreview"); if (!close || close.dataset.svrntyGraphCloseBound === "1") return !!close; close.dataset.svrntyGraphCloseBound = "1"; close.addEventListener("click", (event) => { if (!graphOpen) return; event.preventDefault(); event.stopImmediatePropagation(); closeWorkspaceGraph(); }, true); return true; } function init() { const ok = injectButton() && interceptCloseButton(); if (!ok) { requestAnimationFrame(init); return; } window.SvrntyUmbrellaInline = { open: openWorkspaceGraph, close: closeWorkspaceGraph, isOpen: () => graphOpen, }; LOG("ready"); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();