- CompanyView.vue: hero, plattform, produkte, nyx CTA, footer - ImpressumView.vue + DatenschutzView.vue: legal pages - Router: HTML5 history mode (no # URLs), company routes - Reverted vite-ssg (SSR compat needs proper refactor, planned) - Removed ssr-shim.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
739 lines
42 KiB
JavaScript
739 lines
42 KiB
JavaScript
import { defineComponent, ref, computed, onMounted, nextTick, watch, onUnmounted, resolveComponent, unref, mergeProps, withCtx, createVNode, createTextVNode, resolveDynamicComponent, openBlock, createBlock, withDirectives, vModelCheckbox, toDisplayString, createCommentVNode, Fragment, renderList, Teleport, withModifiers, useSSRContext } from "vue";
|
||
import { ssrRenderComponent, ssrIncludeBooleanAttr, ssrRenderClass, ssrRenderVNode, ssrLooseContain, ssrRenderStyle, ssrInterpolate, ssrRenderList, ssrRenderTeleport, ssrRenderAttrs } from "vue/server-renderer";
|
||
import { useRoute } from "vue-router";
|
||
import { t as takeover, g as getApiBase, w as ws, b as auth, s as scrollbarOptions, T as THEME_ICONS, f as useTheme, h as useDevFlags, _ as _export_sfc } from "../main.mjs";
|
||
import { OverlayScrollbarsComponent } from "overlayscrollbars-vue";
|
||
import { HomeIcon, BoltIcon, SignalSlashIcon, LinkIcon, XMarkIcon, CameraIcon, LockClosedIcon } from "@heroicons/vue/20/solid";
|
||
import "@unhead/vue/server";
|
||
import "pinia";
|
||
import "@heroicons/vue/24/outline";
|
||
import "overlayscrollbars";
|
||
const SESSION_KEY = "nyx_session";
|
||
const _sfc_main = /* @__PURE__ */ defineComponent({
|
||
...{ name: "DevView" },
|
||
__name: "DevView",
|
||
__ssrInlineRender: true,
|
||
setup(__props) {
|
||
const route = useRoute();
|
||
const { isLoggedIn } = auth;
|
||
const { connected, send: wsSend, onMessage } = ws;
|
||
const { theme, setTheme } = useTheme();
|
||
const devFlags = useDevFlags();
|
||
const takeoverToken = takeover.token;
|
||
const captureActive = takeover.capture.isActive;
|
||
const breakoutReq = takeover.breakout.pendingRequest;
|
||
function handleInitTakeover() {
|
||
takeover.init();
|
||
}
|
||
function handleRevoke() {
|
||
takeover.revoke();
|
||
}
|
||
function confirmBreakout() {
|
||
breakoutReq.value?.resolve(true);
|
||
}
|
||
function denyBreakout() {
|
||
breakoutReq.value?.resolve(false);
|
||
}
|
||
async function handleToggleCapture() {
|
||
if (captureActive.value) {
|
||
takeover.capture.disable();
|
||
} else {
|
||
await takeover.capture.enable();
|
||
}
|
||
}
|
||
const SESSION_TOKEN = () => localStorage.getItem(SESSION_KEY) ?? "";
|
||
const systemRequests = ref([]);
|
||
const systemGranted = ref(null);
|
||
async function fetchPendingSystemRequests() {
|
||
try {
|
||
const res = await fetch(`${getApiBase()}/api/system/pending`, {
|
||
headers: { Authorization: `Bearer ${SESSION_TOKEN()}` }
|
||
});
|
||
if (res.ok) {
|
||
const { pending } = await res.json();
|
||
systemRequests.value = pending ?? [];
|
||
}
|
||
} catch {
|
||
}
|
||
}
|
||
async function approveSystemRequest(requestId) {
|
||
const res = await fetch(`${getApiBase()}/api/system/approve`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ sessionToken: SESSION_TOKEN(), requestId })
|
||
});
|
||
if (res.ok) systemRequests.value = systemRequests.value.filter((r) => r.requestId !== requestId);
|
||
}
|
||
async function denySystemRequest(requestId) {
|
||
await fetch(`${getApiBase()}/api/system/deny`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ sessionToken: SESSION_TOKEN(), requestId })
|
||
});
|
||
systemRequests.value = systemRequests.value.filter((r) => r.requestId !== requestId);
|
||
}
|
||
const counterValue = ref(Math.floor(Math.random() * 11));
|
||
const counterBusy = ref(false);
|
||
const counterMuted = ref(true);
|
||
const challengeMessage = ref("");
|
||
const challengeTimer = ref(0);
|
||
let challengeInterval = null;
|
||
let challengeGen = 0;
|
||
const actionPicker = ref({ title: "", options: [] });
|
||
const actionPickerBusy = ref(false);
|
||
async function pickAction(id) {
|
||
actionPickerBusy.value = true;
|
||
actionPicker.value = { title: "", options: [] };
|
||
try {
|
||
await fetch(`${getApiBase()}/api/dev/counter`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${SESSION_TOKEN()}` },
|
||
body: JSON.stringify({ action: "pick", pick: id })
|
||
});
|
||
} catch {
|
||
}
|
||
actionPickerBusy.value = false;
|
||
}
|
||
async function counterAction(action) {
|
||
counterMuted.value = true;
|
||
challengeGen++;
|
||
if (challengeInterval) {
|
||
clearInterval(challengeInterval);
|
||
challengeInterval = null;
|
||
}
|
||
challengeMessage.value = "";
|
||
challengeTimer.value = 0;
|
||
counterBusy.value = true;
|
||
try {
|
||
await fetch(`${getApiBase()}/api/dev/counter`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${SESSION_TOKEN()}` },
|
||
body: JSON.stringify({ action })
|
||
});
|
||
} catch {
|
||
}
|
||
counterBusy.value = false;
|
||
}
|
||
const loading = ref(false);
|
||
const statsError = ref("");
|
||
const stats = ref(null);
|
||
function fmt(v) {
|
||
if (v === null || v === void 0) return "—";
|
||
return v.toFixed(2);
|
||
}
|
||
const usedPct = computed(() => {
|
||
const t = stats.value?.credits?.total;
|
||
const u = stats.value?.credits?.used;
|
||
if (!t) return 0;
|
||
return Math.min(100, u / t * 100);
|
||
});
|
||
function load() {
|
||
if (!connected.value) return;
|
||
loading.value = true;
|
||
statsError.value = "";
|
||
wsSend({ type: "stats_request" });
|
||
}
|
||
const discoing = ref(false);
|
||
const discoChatting = ref(false);
|
||
function disco() {
|
||
if (!connected.value) return;
|
||
discoing.value = true;
|
||
wsSend({ type: "disco_request" });
|
||
setTimeout(() => {
|
||
discoing.value = false;
|
||
}, 2e3);
|
||
}
|
||
function discoChat() {
|
||
if (!connected.value) return;
|
||
discoChatting.value = true;
|
||
wsSend({ type: "disco_chat_request" });
|
||
setTimeout(() => {
|
||
discoChatting.value = false;
|
||
}, 3e3);
|
||
}
|
||
let unsubscribeWs = null;
|
||
let refreshInterval;
|
||
onMounted(() => {
|
||
fetchPendingSystemRequests();
|
||
unsubscribeWs = onMessage((data) => {
|
||
if (data.type === "system_access_request") {
|
||
if (!systemRequests.value.find((r) => r.requestId === data.requestId))
|
||
systemRequests.value.push(data);
|
||
return;
|
||
}
|
||
if (data.type === "counter_update") {
|
||
counterValue.value = data.value ?? counterValue.value;
|
||
return;
|
||
}
|
||
if (data.type === "counter_challenge") {
|
||
challengeMessage.value = data.message || "DECIDE NOW!";
|
||
challengeTimer.value = data.timeout || 30;
|
||
counterMuted.value = false;
|
||
nextTick(() => {
|
||
const el = document.querySelector(".counter-widget");
|
||
if (el) {
|
||
el.classList.remove("flash");
|
||
void el.offsetWidth;
|
||
el.classList.add("flash");
|
||
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
||
}
|
||
});
|
||
if (challengeInterval) clearInterval(challengeInterval);
|
||
const cid = ++challengeGen;
|
||
challengeInterval = setInterval(() => {
|
||
if (cid !== challengeGen) {
|
||
clearInterval(challengeInterval);
|
||
return;
|
||
}
|
||
challengeTimer.value--;
|
||
if (challengeTimer.value <= 0) {
|
||
if (challengeInterval) {
|
||
clearInterval(challengeInterval);
|
||
challengeInterval = null;
|
||
}
|
||
counterMuted.value = true;
|
||
challengeMessage.value = "";
|
||
fetch(`${getApiBase()}/api/dev/counter`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${SESSION_TOKEN()}` },
|
||
body: JSON.stringify({ action: "timeout" })
|
||
});
|
||
}
|
||
}, 1e3);
|
||
return;
|
||
}
|
||
if (data.type === "confetti") {
|
||
const container = document.createElement("div");
|
||
container.className = "confetti-container";
|
||
const colors = ["#ff6b6b", "#ffd93d", "#6bcb77", "#4d96ff", "#ff922b", "#cc5de8"];
|
||
for (let i = 0; i < 60; i++) {
|
||
const piece = document.createElement("div");
|
||
piece.className = "confetti-piece";
|
||
piece.style.left = Math.random() * 100 + "%";
|
||
piece.style.background = colors[Math.floor(Math.random() * colors.length)];
|
||
piece.style.animationDelay = Math.random() * 2 + "s";
|
||
piece.style.borderRadius = Math.random() > 0.5 ? "50%" : "0";
|
||
container.appendChild(piece);
|
||
}
|
||
document.body.appendChild(container);
|
||
setTimeout(() => container.remove(), 5e3);
|
||
return;
|
||
}
|
||
if (data.type === "action_picker") {
|
||
actionPicker.value = { title: data.title || "Next?", options: data.options || [] };
|
||
actionPickerBusy.value = false;
|
||
return;
|
||
}
|
||
if (data.type === "counter_mute") {
|
||
counterMuted.value = true;
|
||
challengeMessage.value = data.message || "";
|
||
if (challengeInterval) {
|
||
clearInterval(challengeInterval);
|
||
challengeInterval = null;
|
||
}
|
||
challengeTimer.value = 0;
|
||
return;
|
||
}
|
||
if (data.type === "stats") {
|
||
loading.value = false;
|
||
if (data.error) {
|
||
statsError.value = data.error;
|
||
} else {
|
||
stats.value = data;
|
||
}
|
||
}
|
||
});
|
||
const startRefresh = () => {
|
||
load();
|
||
refreshInterval = setInterval(load, 15e3);
|
||
};
|
||
if (connected.value) {
|
||
startRefresh();
|
||
} else {
|
||
const stop = watch(connected, (val) => {
|
||
if (val) {
|
||
stop();
|
||
startRefresh();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
watch(() => route.name, (name, prev) => {
|
||
if (name === "dev" && !refreshInterval && connected.value) {
|
||
load();
|
||
refreshInterval = setInterval(load, 15e3);
|
||
} else if (prev === "dev" && name !== "dev" && refreshInterval) {
|
||
clearInterval(refreshInterval);
|
||
refreshInterval = void 0;
|
||
}
|
||
});
|
||
onUnmounted(() => {
|
||
if (unsubscribeWs) unsubscribeWs();
|
||
if (refreshInterval) clearInterval(refreshInterval);
|
||
});
|
||
return (_ctx, _push, _parent, _attrs) => {
|
||
const _component_RouterLink = resolveComponent("RouterLink");
|
||
if (unref(isLoggedIn)) {
|
||
_push(ssrRenderComponent(unref(OverlayScrollbarsComponent), mergeProps({
|
||
class: "dev-view",
|
||
options: unref(scrollbarOptions),
|
||
element: "div"
|
||
}, _attrs), {
|
||
default: withCtx((_, _push2, _parent2, _scopeId) => {
|
||
if (_push2) {
|
||
_push2(`<div class="page" data-v-6fcff79f${_scopeId}><div class="dev-header" data-v-6fcff79f${_scopeId}><h2 data-v-6fcff79f${_scopeId}>/dev</h2><div class="dev-actions" data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(_component_RouterLink, {
|
||
to: "/agents",
|
||
class: "dev-disco-btn"
|
||
}, {
|
||
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
|
||
if (_push3) {
|
||
_push3(ssrRenderComponent(unref(HomeIcon), { class: "w-4 h-4 inline" }, null, _parent3, _scopeId2));
|
||
_push3(` Home`);
|
||
} else {
|
||
return [
|
||
createVNode(unref(HomeIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Home")
|
||
];
|
||
}
|
||
}),
|
||
_: 1
|
||
}, _parent2, _scopeId));
|
||
_push2(`<button class="dev-disco-btn"${ssrIncludeBooleanAttr(discoing.value) ? " disabled" : ""} data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(unref(BoltIcon), { class: "w-4 h-4 inline" }, null, _parent2, _scopeId));
|
||
_push2(` Disconnect Gateway</button><button class="dev-disco-btn"${ssrIncludeBooleanAttr(discoChatting.value) ? " disabled" : ""} data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(unref(SignalSlashIcon), { class: "w-4 h-4 inline" }, null, _parent2, _scopeId));
|
||
_push2(` Disconnect Chat</button></div></div><div class="content" data-v-6fcff79f${_scopeId}><div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>Theme</h3><div class="dev-actions" data-v-6fcff79f${_scopeId}><button class="${ssrRenderClass([{ active: unref(theme) === "loop42" }, "dev-theme-btn"])}" data-v-6fcff79f${_scopeId}>`);
|
||
ssrRenderVNode(_push2, createVNode(resolveDynamicComponent(unref(THEME_ICONS).loop42), { class: "w-4 h-4 inline" }, null), _parent2, _scopeId);
|
||
_push2(` loop42</button><button class="${ssrRenderClass([{ active: unref(theme) === "titan" }, "dev-theme-btn"])}" data-v-6fcff79f${_scopeId}>`);
|
||
ssrRenderVNode(_push2, createVNode(resolveDynamicComponent(unref(THEME_ICONS).titan), { class: "w-4 h-4 inline" }, null), _parent2, _scopeId);
|
||
_push2(` Titan</button><button class="${ssrRenderClass([{ active: unref(theme) === "eras" }, "dev-theme-btn"])}" data-v-6fcff79f${_scopeId}>`);
|
||
ssrRenderVNode(_push2, createVNode(resolveDynamicComponent(unref(THEME_ICONS).eras), { class: "w-4 h-4 inline" }, null), _parent2, _scopeId);
|
||
_push2(` ERAS</button></div></div><div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>Dev Flags</h3><div class="dev-flags" data-v-6fcff79f${_scopeId}><label class="dev-flag" data-v-6fcff79f${_scopeId}><input type="checkbox"${ssrIncludeBooleanAttr(Array.isArray(unref(devFlags).showGrid) ? ssrLooseContain(unref(devFlags).showGrid, null) : unref(devFlags).showGrid) ? " checked" : ""} data-v-6fcff79f${_scopeId}><span data-v-6fcff79f${_scopeId}>showGrid</span></label><label class="dev-flag" data-v-6fcff79f${_scopeId}><input type="checkbox"${ssrIncludeBooleanAttr(Array.isArray(unref(devFlags).showDebugInfo) ? ssrLooseContain(unref(devFlags).showDebugInfo, null) : unref(devFlags).showDebugInfo) ? " checked" : ""} data-v-6fcff79f${_scopeId}><span data-v-6fcff79f${_scopeId}>showDebugInfo</span></label><label class="dev-flag" data-v-6fcff79f${_scopeId}><input type="checkbox"${ssrIncludeBooleanAttr(Array.isArray(unref(devFlags).showHud) ? ssrLooseContain(unref(devFlags).showHud, null) : unref(devFlags).showHud) ? " checked" : ""} data-v-6fcff79f${_scopeId}><span data-v-6fcff79f${_scopeId}>showHud</span></label></div></div><div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>Takeover</h3>`);
|
||
if (!unref(takeoverToken)) {
|
||
_push2(`<div class="dev-actions" data-v-6fcff79f${_scopeId}><button class="dev-theme-btn" data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(unref(LinkIcon), { class: "w-4 h-4 inline" }, null, _parent2, _scopeId));
|
||
_push2(` Enable Takeover</button></div>`);
|
||
} else {
|
||
_push2(`<div class="dev-actions" style="${ssrRenderStyle({ "gap": "var(--space-page)", "align-items": "center", "flex-wrap": "wrap" })}" data-v-6fcff79f${_scopeId}><code class="takeover-token" data-v-6fcff79f${_scopeId}>${ssrInterpolate(unref(takeoverToken))}</code><button class="dev-theme-btn active" data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(unref(XMarkIcon), { class: "w-4 h-4 inline" }, null, _parent2, _scopeId));
|
||
_push2(` Revoke</button><button class="${ssrRenderClass([{ active: unref(captureActive) }, "dev-theme-btn"])}" data-v-6fcff79f${_scopeId}>`);
|
||
_push2(ssrRenderComponent(unref(CameraIcon), { class: "w-4 h-4 inline" }, null, _parent2, _scopeId));
|
||
_push2(` ${ssrInterpolate(unref(captureActive) ? "Capture ON" : "Enable Capture")}</button></div>`);
|
||
}
|
||
_push2(`</div>`);
|
||
if (systemRequests.value.length > 0 || systemGranted.value) {
|
||
_push2(`<div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>System Access</h3>`);
|
||
if (systemGranted.value) {
|
||
_push2(`<div class="dev-system-granted" data-v-6fcff79f${_scopeId}> Access granted to ${ssrInterpolate(systemGranted.value.user)} — active until session end. </div>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`<!--[-->`);
|
||
ssrRenderList(systemRequests.value, (req) => {
|
||
_push2(`<div class="dev-system-request" data-v-6fcff79f${_scopeId}><div class="dev-system-code" data-v-6fcff79f${_scopeId}>${ssrInterpolate(req.userCode)}</div><div class="dev-system-desc" data-v-6fcff79f${_scopeId}>${ssrInterpolate(req.description)}</div><div class="dev-system-expiry" data-v-6fcff79f${_scopeId}>expires in ${ssrInterpolate(Math.max(0, Math.ceil((req.expiresAt - Date.now()) / 1e3)))}s</div><div class="dev-actions" style="${ssrRenderStyle({ "margin-top": "8px" })}" data-v-6fcff79f${_scopeId}><button class="dev-theme-btn" data-v-6fcff79f${_scopeId}>Deny</button><button class="dev-theme-btn active" data-v-6fcff79f${_scopeId}>Approve</button></div></div>`);
|
||
});
|
||
_push2(`<!--]--></div>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`<div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>MCP Counter</h3><div class="${ssrRenderClass([{ muted: counterMuted.value }, "counter-widget"])}" data-v-6fcff79f${_scopeId}><div class="counter-controls" data-v-6fcff79f${_scopeId}><button class="counter-btn"${ssrIncludeBooleanAttr(counterMuted.value || counterBusy.value) ? " disabled" : ""} data-v-6fcff79f${_scopeId}>−</button><span class="counter-value" id="mcp-counter-value" data-v-6fcff79f${_scopeId}>${ssrInterpolate(counterValue.value)}</span><button class="counter-btn"${ssrIncludeBooleanAttr(counterMuted.value || counterBusy.value) ? " disabled" : ""} data-v-6fcff79f${_scopeId}>+</button></div>`);
|
||
if (challengeMessage.value) {
|
||
_push2(`<div class="counter-challenge" data-v-6fcff79f${_scopeId}><span class="counter-message" data-v-6fcff79f${_scopeId}>${ssrInterpolate(challengeMessage.value)}</span>`);
|
||
if (challengeTimer.value > 0) {
|
||
_push2(`<span class="counter-timer" data-v-6fcff79f${_scopeId}>${ssrInterpolate(challengeTimer.value)}s</span>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`</div>`);
|
||
} else {
|
||
_push2(`<div class="counter-hint" data-v-6fcff79f${_scopeId}>Waiting for Claude...</div>`);
|
||
}
|
||
_push2(`</div></div>`);
|
||
if (actionPicker.value.title) {
|
||
_push2(`<div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>${ssrInterpolate(actionPicker.value.title)}</h3><div class="action-picker" data-v-6fcff79f${_scopeId}><!--[-->`);
|
||
ssrRenderList(actionPicker.value.options, (opt, i) => {
|
||
_push2(`<button class="action-pick-btn"${ssrIncludeBooleanAttr(actionPickerBusy.value) ? " disabled" : ""} data-v-6fcff79f${_scopeId}>${ssrInterpolate(opt.label)}</button>`);
|
||
});
|
||
_push2(`<!--]--></div></div>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`<div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>OpenRouter Credits</h3>`);
|
||
if (loading.value && !stats.value) {
|
||
_push2(`<div class="dev-loading" data-v-6fcff79f${_scopeId}>Loading…</div>`);
|
||
} else if (statsError.value) {
|
||
_push2(`<div class="dev-error" data-v-6fcff79f${_scopeId}>${ssrInterpolate(statsError.value)}</div>`);
|
||
} else if (stats.value) {
|
||
_push2(`<div class="credits-widget" data-v-6fcff79f${_scopeId}><div class="credits-bar-track" data-v-6fcff79f${_scopeId}><div class="credits-bar-fill" style="${ssrRenderStyle({ width: usedPct.value + "%" })}" data-v-6fcff79f${_scopeId}></div></div><div class="credits-row" data-v-6fcff79f${_scopeId}><div class="credits-stat" data-v-6fcff79f${_scopeId}><span class="credits-label" data-v-6fcff79f${_scopeId}>Used</span><span class="credits-amount credits-used" data-v-6fcff79f${_scopeId}>$${ssrInterpolate(fmt(stats.value.credits.used))}</span></div><div class="credits-stat" data-v-6fcff79f${_scopeId}><span class="credits-label" data-v-6fcff79f${_scopeId}>Remaining</span><span class="credits-amount credits-remaining" data-v-6fcff79f${_scopeId}>$${ssrInterpolate(fmt(stats.value.credits.remaining))}</span></div><div class="credits-stat" data-v-6fcff79f${_scopeId}><span class="credits-label" data-v-6fcff79f${_scopeId}>Total</span><span class="credits-amount" data-v-6fcff79f${_scopeId}>$${ssrInterpolate(fmt(stats.value.credits.total))}</span></div></div></div>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`</div>`);
|
||
if (stats.value) {
|
||
_push2(`<div class="dev-section" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>Agents</h3><div class="dev-table-wrap" data-v-6fcff79f${_scopeId}><table class="dev-table" data-v-6fcff79f${_scopeId}><thead data-v-6fcff79f${_scopeId}><tr data-v-6fcff79f${_scopeId}><th data-v-6fcff79f${_scopeId}>Agent</th><th data-v-6fcff79f${_scopeId}>Model</th><th data-v-6fcff79f${_scopeId}>Context</th><th data-v-6fcff79f${_scopeId}>Prompt / 1M</th><th data-v-6fcff79f${_scopeId}>Completion / 1M</th></tr></thead><tbody data-v-6fcff79f${_scopeId}><!--[-->`);
|
||
ssrRenderList(stats.value.agents, (a) => {
|
||
_push2(`<tr data-v-6fcff79f${_scopeId}><td class="agent-id" data-v-6fcff79f${_scopeId}>${ssrInterpolate(a.id)}</td><td data-v-6fcff79f${_scopeId}><code data-v-6fcff79f${_scopeId}>${ssrInterpolate(a.modelId || a.model)}</code></td><td data-v-6fcff79f${_scopeId}>${ssrInterpolate(a.contextLength ? (a.contextLength / 1e3).toFixed(0) + "k" : "—")}</td><td data-v-6fcff79f${_scopeId}>${ssrInterpolate(a.promptPrice !== null ? "$" + a.promptPrice.toFixed(3) : "—")}</td><td data-v-6fcff79f${_scopeId}>${ssrInterpolate(a.completionPrice !== null ? "$" + a.completionPrice.toFixed(3) : "—")}</td></tr>`);
|
||
});
|
||
_push2(`<!--]--></tbody></table></div></div>`);
|
||
} else {
|
||
_push2(`<!---->`);
|
||
}
|
||
_push2(`</div></div>`);
|
||
ssrRenderTeleport(_push2, (_push3) => {
|
||
if (unref(breakoutReq)) {
|
||
_push3(`<div class="breakout-modal-overlay" data-v-6fcff79f${_scopeId}><div class="breakout-modal" data-v-6fcff79f${_scopeId}><h3 data-v-6fcff79f${_scopeId}>Open Breakout</h3><p data-v-6fcff79f${_scopeId}>Name: <strong data-v-6fcff79f${_scopeId}>${ssrInterpolate(unref(breakoutReq).name)}</strong></p><p data-v-6fcff79f${_scopeId}>Size: <strong data-v-6fcff79f${_scopeId}>${ssrInterpolate(unref(breakoutReq).preset)}</strong></p><p class="breakout-nonce" data-v-6fcff79f${_scopeId}>${ssrInterpolate(unref(breakoutReq).nonce)}</p><div class="breakout-modal-actions" data-v-6fcff79f${_scopeId}><button class="dev-theme-btn" data-v-6fcff79f${_scopeId}>Cancel</button><button class="dev-theme-btn active" data-v-6fcff79f${_scopeId}>Confirm</button></div></div></div>`);
|
||
} else {
|
||
_push3(`<!---->`);
|
||
}
|
||
}, "body", false, _parent2);
|
||
} else {
|
||
return [
|
||
createVNode("div", { class: "page" }, [
|
||
createVNode("div", { class: "dev-header" }, [
|
||
createVNode("h2", null, "/dev"),
|
||
createVNode("div", { class: "dev-actions" }, [
|
||
createVNode(_component_RouterLink, {
|
||
to: "/agents",
|
||
class: "dev-disco-btn"
|
||
}, {
|
||
default: withCtx(() => [
|
||
createVNode(unref(HomeIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Home")
|
||
]),
|
||
_: 1
|
||
}),
|
||
createVNode("button", {
|
||
class: "dev-disco-btn",
|
||
onClick: disco,
|
||
disabled: discoing.value
|
||
}, [
|
||
createVNode(unref(BoltIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Disconnect Gateway")
|
||
], 8, ["disabled"]),
|
||
createVNode("button", {
|
||
class: "dev-disco-btn",
|
||
onClick: discoChat,
|
||
disabled: discoChatting.value
|
||
}, [
|
||
createVNode(unref(SignalSlashIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Disconnect Chat")
|
||
], 8, ["disabled"])
|
||
])
|
||
]),
|
||
createVNode("div", { class: "content" }, [
|
||
createVNode("div", { class: "dev-section" }, [
|
||
createVNode("h3", null, "Theme"),
|
||
createVNode("div", { class: "dev-actions" }, [
|
||
createVNode("button", {
|
||
class: ["dev-theme-btn", { active: unref(theme) === "loop42" }],
|
||
onClick: ($event) => unref(setTheme)("loop42")
|
||
}, [
|
||
(openBlock(), createBlock(resolveDynamicComponent(unref(THEME_ICONS).loop42), { class: "w-4 h-4 inline" })),
|
||
createTextVNode(" loop42")
|
||
], 10, ["onClick"]),
|
||
createVNode("button", {
|
||
class: ["dev-theme-btn", { active: unref(theme) === "titan" }],
|
||
onClick: ($event) => unref(setTheme)("titan")
|
||
}, [
|
||
(openBlock(), createBlock(resolveDynamicComponent(unref(THEME_ICONS).titan), { class: "w-4 h-4 inline" })),
|
||
createTextVNode(" Titan")
|
||
], 10, ["onClick"]),
|
||
createVNode("button", {
|
||
class: ["dev-theme-btn", { active: unref(theme) === "eras" }],
|
||
onClick: ($event) => unref(setTheme)("eras")
|
||
}, [
|
||
(openBlock(), createBlock(resolveDynamicComponent(unref(THEME_ICONS).eras), { class: "w-4 h-4 inline" })),
|
||
createTextVNode(" ERAS")
|
||
], 10, ["onClick"])
|
||
])
|
||
]),
|
||
createVNode("div", { class: "dev-section" }, [
|
||
createVNode("h3", null, "Dev Flags"),
|
||
createVNode("div", { class: "dev-flags" }, [
|
||
createVNode("label", { class: "dev-flag" }, [
|
||
withDirectives(createVNode("input", {
|
||
type: "checkbox",
|
||
"onUpdate:modelValue": ($event) => unref(devFlags).showGrid = $event
|
||
}, null, 8, ["onUpdate:modelValue"]), [
|
||
[vModelCheckbox, unref(devFlags).showGrid]
|
||
]),
|
||
createVNode("span", null, "showGrid")
|
||
]),
|
||
createVNode("label", { class: "dev-flag" }, [
|
||
withDirectives(createVNode("input", {
|
||
type: "checkbox",
|
||
"onUpdate:modelValue": ($event) => unref(devFlags).showDebugInfo = $event
|
||
}, null, 8, ["onUpdate:modelValue"]), [
|
||
[vModelCheckbox, unref(devFlags).showDebugInfo]
|
||
]),
|
||
createVNode("span", null, "showDebugInfo")
|
||
]),
|
||
createVNode("label", { class: "dev-flag" }, [
|
||
withDirectives(createVNode("input", {
|
||
type: "checkbox",
|
||
"onUpdate:modelValue": ($event) => unref(devFlags).showHud = $event
|
||
}, null, 8, ["onUpdate:modelValue"]), [
|
||
[vModelCheckbox, unref(devFlags).showHud]
|
||
]),
|
||
createVNode("span", null, "showHud")
|
||
])
|
||
])
|
||
]),
|
||
createVNode("div", { class: "dev-section" }, [
|
||
createVNode("h3", null, "Takeover"),
|
||
!unref(takeoverToken) ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "dev-actions"
|
||
}, [
|
||
createVNode("button", {
|
||
class: "dev-theme-btn",
|
||
onClick: handleInitTakeover
|
||
}, [
|
||
createVNode(unref(LinkIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Enable Takeover")
|
||
])
|
||
])) : (openBlock(), createBlock("div", {
|
||
key: 1,
|
||
class: "dev-actions",
|
||
style: { "gap": "var(--space-page)", "align-items": "center", "flex-wrap": "wrap" }
|
||
}, [
|
||
createVNode("code", { class: "takeover-token" }, toDisplayString(unref(takeoverToken)), 1),
|
||
createVNode("button", {
|
||
class: "dev-theme-btn active",
|
||
onClick: handleRevoke
|
||
}, [
|
||
createVNode(unref(XMarkIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" Revoke")
|
||
]),
|
||
createVNode("button", {
|
||
class: ["dev-theme-btn", { active: unref(captureActive) }],
|
||
onClick: handleToggleCapture
|
||
}, [
|
||
createVNode(unref(CameraIcon), { class: "w-4 h-4 inline" }),
|
||
createTextVNode(" " + toDisplayString(unref(captureActive) ? "Capture ON" : "Enable Capture"), 1)
|
||
], 2)
|
||
]))
|
||
]),
|
||
systemRequests.value.length > 0 || systemGranted.value ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "dev-section"
|
||
}, [
|
||
createVNode("h3", null, "System Access"),
|
||
systemGranted.value ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "dev-system-granted"
|
||
}, " Access granted to " + toDisplayString(systemGranted.value.user) + " — active until session end. ", 1)) : createCommentVNode("", true),
|
||
(openBlock(true), createBlock(Fragment, null, renderList(systemRequests.value, (req) => {
|
||
return openBlock(), createBlock("div", {
|
||
key: req.requestId,
|
||
class: "dev-system-request"
|
||
}, [
|
||
createVNode("div", { class: "dev-system-code" }, toDisplayString(req.userCode), 1),
|
||
createVNode("div", { class: "dev-system-desc" }, toDisplayString(req.description), 1),
|
||
createVNode("div", { class: "dev-system-expiry" }, "expires in " + toDisplayString(Math.max(0, Math.ceil((req.expiresAt - Date.now()) / 1e3))) + "s", 1),
|
||
createVNode("div", {
|
||
class: "dev-actions",
|
||
style: { "margin-top": "8px" }
|
||
}, [
|
||
createVNode("button", {
|
||
class: "dev-theme-btn",
|
||
onClick: ($event) => denySystemRequest(req.requestId)
|
||
}, "Deny", 8, ["onClick"]),
|
||
createVNode("button", {
|
||
class: "dev-theme-btn active",
|
||
onClick: ($event) => approveSystemRequest(req.requestId)
|
||
}, "Approve", 8, ["onClick"])
|
||
])
|
||
]);
|
||
}), 128))
|
||
])) : createCommentVNode("", true),
|
||
createVNode("div", { class: "dev-section" }, [
|
||
createVNode("h3", null, "MCP Counter"),
|
||
createVNode("div", {
|
||
class: ["counter-widget", { muted: counterMuted.value }]
|
||
}, [
|
||
createVNode("div", { class: "counter-controls" }, [
|
||
createVNode("button", {
|
||
class: "counter-btn",
|
||
onClick: ($event) => counterAction("decrement"),
|
||
disabled: counterMuted.value || counterBusy.value
|
||
}, "−", 8, ["onClick", "disabled"]),
|
||
createVNode("span", {
|
||
class: "counter-value",
|
||
id: "mcp-counter-value"
|
||
}, toDisplayString(counterValue.value), 1),
|
||
createVNode("button", {
|
||
class: "counter-btn",
|
||
onClick: ($event) => counterAction("increment"),
|
||
disabled: counterMuted.value || counterBusy.value
|
||
}, "+", 8, ["onClick", "disabled"])
|
||
]),
|
||
challengeMessage.value ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "counter-challenge"
|
||
}, [
|
||
createVNode("span", { class: "counter-message" }, toDisplayString(challengeMessage.value), 1),
|
||
challengeTimer.value > 0 ? (openBlock(), createBlock("span", {
|
||
key: 0,
|
||
class: "counter-timer"
|
||
}, toDisplayString(challengeTimer.value) + "s", 1)) : createCommentVNode("", true)
|
||
])) : (openBlock(), createBlock("div", {
|
||
key: 1,
|
||
class: "counter-hint"
|
||
}, "Waiting for Claude..."))
|
||
], 2)
|
||
]),
|
||
actionPicker.value.title ? (openBlock(), createBlock("div", {
|
||
key: 1,
|
||
class: "dev-section"
|
||
}, [
|
||
createVNode("h3", null, toDisplayString(actionPicker.value.title), 1),
|
||
createVNode("div", { class: "action-picker" }, [
|
||
(openBlock(true), createBlock(Fragment, null, renderList(actionPicker.value.options, (opt, i) => {
|
||
return openBlock(), createBlock("button", {
|
||
key: i,
|
||
class: "action-pick-btn",
|
||
disabled: actionPickerBusy.value,
|
||
onClick: ($event) => pickAction(opt.id)
|
||
}, toDisplayString(opt.label), 9, ["disabled", "onClick"]);
|
||
}), 128))
|
||
])
|
||
])) : createCommentVNode("", true),
|
||
createVNode("div", { class: "dev-section" }, [
|
||
createVNode("h3", null, "OpenRouter Credits"),
|
||
loading.value && !stats.value ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "dev-loading"
|
||
}, "Loading…")) : statsError.value ? (openBlock(), createBlock("div", {
|
||
key: 1,
|
||
class: "dev-error"
|
||
}, toDisplayString(statsError.value), 1)) : stats.value ? (openBlock(), createBlock("div", {
|
||
key: 2,
|
||
class: "credits-widget"
|
||
}, [
|
||
createVNode("div", { class: "credits-bar-track" }, [
|
||
createVNode("div", {
|
||
class: "credits-bar-fill",
|
||
style: { width: usedPct.value + "%" }
|
||
}, null, 4)
|
||
]),
|
||
createVNode("div", { class: "credits-row" }, [
|
||
createVNode("div", { class: "credits-stat" }, [
|
||
createVNode("span", { class: "credits-label" }, "Used"),
|
||
createVNode("span", { class: "credits-amount credits-used" }, "$" + toDisplayString(fmt(stats.value.credits.used)), 1)
|
||
]),
|
||
createVNode("div", { class: "credits-stat" }, [
|
||
createVNode("span", { class: "credits-label" }, "Remaining"),
|
||
createVNode("span", { class: "credits-amount credits-remaining" }, "$" + toDisplayString(fmt(stats.value.credits.remaining)), 1)
|
||
]),
|
||
createVNode("div", { class: "credits-stat" }, [
|
||
createVNode("span", { class: "credits-label" }, "Total"),
|
||
createVNode("span", { class: "credits-amount" }, "$" + toDisplayString(fmt(stats.value.credits.total)), 1)
|
||
])
|
||
])
|
||
])) : createCommentVNode("", true)
|
||
]),
|
||
stats.value ? (openBlock(), createBlock("div", {
|
||
key: 2,
|
||
class: "dev-section"
|
||
}, [
|
||
createVNode("h3", null, "Agents"),
|
||
createVNode("div", { class: "dev-table-wrap" }, [
|
||
createVNode("table", { class: "dev-table" }, [
|
||
createVNode("thead", null, [
|
||
createVNode("tr", null, [
|
||
createVNode("th", null, "Agent"),
|
||
createVNode("th", null, "Model"),
|
||
createVNode("th", null, "Context"),
|
||
createVNode("th", null, "Prompt / 1M"),
|
||
createVNode("th", null, "Completion / 1M")
|
||
])
|
||
]),
|
||
createVNode("tbody", null, [
|
||
(openBlock(true), createBlock(Fragment, null, renderList(stats.value.agents, (a) => {
|
||
return openBlock(), createBlock("tr", {
|
||
key: a.id
|
||
}, [
|
||
createVNode("td", { class: "agent-id" }, toDisplayString(a.id), 1),
|
||
createVNode("td", null, [
|
||
createVNode("code", null, toDisplayString(a.modelId || a.model), 1)
|
||
]),
|
||
createVNode("td", null, toDisplayString(a.contextLength ? (a.contextLength / 1e3).toFixed(0) + "k" : "—"), 1),
|
||
createVNode("td", null, toDisplayString(a.promptPrice !== null ? "$" + a.promptPrice.toFixed(3) : "—"), 1),
|
||
createVNode("td", null, toDisplayString(a.completionPrice !== null ? "$" + a.completionPrice.toFixed(3) : "—"), 1)
|
||
]);
|
||
}), 128))
|
||
])
|
||
])
|
||
])
|
||
])) : createCommentVNode("", true)
|
||
])
|
||
]),
|
||
(openBlock(), createBlock(Teleport, { to: "body" }, [
|
||
unref(breakoutReq) ? (openBlock(), createBlock("div", {
|
||
key: 0,
|
||
class: "breakout-modal-overlay",
|
||
onClick: withModifiers(denyBreakout, ["self"])
|
||
}, [
|
||
createVNode("div", { class: "breakout-modal" }, [
|
||
createVNode("h3", null, "Open Breakout"),
|
||
createVNode("p", null, [
|
||
createTextVNode("Name: "),
|
||
createVNode("strong", null, toDisplayString(unref(breakoutReq).name), 1)
|
||
]),
|
||
createVNode("p", null, [
|
||
createTextVNode("Size: "),
|
||
createVNode("strong", null, toDisplayString(unref(breakoutReq).preset), 1)
|
||
]),
|
||
createVNode("p", { class: "breakout-nonce" }, toDisplayString(unref(breakoutReq).nonce), 1),
|
||
createVNode("div", { class: "breakout-modal-actions" }, [
|
||
createVNode("button", {
|
||
class: "dev-theme-btn",
|
||
onClick: denyBreakout
|
||
}, "Cancel"),
|
||
createVNode("button", {
|
||
class: "dev-theme-btn active",
|
||
onClick: confirmBreakout
|
||
}, "Confirm")
|
||
])
|
||
])
|
||
])) : createCommentVNode("", true)
|
||
]))
|
||
];
|
||
}
|
||
}),
|
||
_: 1
|
||
}, _parent));
|
||
} else {
|
||
_push(`<div${ssrRenderAttrs(mergeProps({ class: "not-logged-in" }, _attrs))} data-v-6fcff79f><p data-v-6fcff79f>`);
|
||
_push(ssrRenderComponent(unref(LockClosedIcon), { class: "w-5 h-5 inline" }, null, _parent));
|
||
_push(` Not logged in</p>`);
|
||
_push(ssrRenderComponent(_component_RouterLink, { to: "/login" }, {
|
||
default: withCtx((_, _push2, _parent2, _scopeId) => {
|
||
if (_push2) {
|
||
_push2(`Sign in →`);
|
||
} else {
|
||
return [
|
||
createTextVNode("Sign in →")
|
||
];
|
||
}
|
||
}),
|
||
_: 1
|
||
}, _parent));
|
||
_push(`</div>`);
|
||
}
|
||
};
|
||
}
|
||
});
|
||
const _sfc_setup = _sfc_main.setup;
|
||
_sfc_main.setup = (props, ctx) => {
|
||
const ssrContext = useSSRContext();
|
||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/views/DevView.vue");
|
||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
||
};
|
||
const DevView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6fcff79f"]]);
|
||
export {
|
||
DevView as default
|
||
};
|