// SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p9-desktop-view-density. // SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p9-multi-web-probe-sentinel. // SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p10-monitor-web-aggregation. // Responsibility: Static dashboard shell and asset serving for the web-probe sentinel frontend. import { readFileSync } from "node:fs"; import { rootPath } from "./config"; interface DashboardShellConfig { readonly node: string; readonly lane: string; readonly sentinelId: string; readonly plan: { readonly ok: boolean; readonly sentinels?: readonly Record[] }; readonly publicExposure: Record; } const DASHBOARD_ASSET_ROOT = "scripts/assets/web-probe-sentinel-dashboard"; const DASHBOARD_CONTRACT_VERSION = "draft-2026-06-26-p10-monitor-web-aggregation"; export function renderWebProbeSentinelDashboardHtml(config: DashboardShellConfig): string { const publicOrigin = stringOrNull(config.publicExposure.publicBaseUrl) ?? ""; const basePath = publicBasePath(publicOrigin); const registryHtml = renderSentinelRegistryStrip(config, basePath); return ` HWLAB Web哨兵

HWLAB Web哨兵

${escapeHtml(config.node)} / ${escapeHtml(config.lane)} · ${escapeHtml(config.sentinelId)}

空闲
${registryHtml}

运行历史

-
运行 状态 场景 发现 更新

运行详情

未选择运行

发现分析

-

运行时间线

-
`; } function renderSentinelRegistryStrip(config: DashboardShellConfig, basePath: string): string { const rows = Array.isArray(config.plan.sentinels) ? config.plan.sentinels.map((item) => ({ id: stringOrNull(item.id) ?? "", enabled: item.enabled !== false, })).filter((item) => item.id.length > 0) : []; if (rows.length <= 1) return ""; return `
哨兵入口 当前 workspace 共 ${rows.length} 条
`; } function renderSentinelRegistryLink(id: string, enabled: boolean, current: boolean, basePath: string): string { const href = current ? `${basePath || "/"}` : id === "workbench-dsflash-go-tool-call-10x" ? "/" : `/sentinels/${encodeURIComponent(id)}/`; return ` ${escapeHtml(id)} ${current ? "当前" : enabled ? "查看" : "停用"} `; } function publicBasePath(publicBaseUrl: string): string { try { const path = new URL(publicBaseUrl).pathname.replace(/\/+$/u, ""); return path === "/" ? "" : path; } catch { return ""; } } export function webProbeSentinelDashboardAssetResponse(pathname: string): Response | null { if (pathname === "/dashboard/assets/dashboard.css") return textAsset(`${DASHBOARD_ASSET_ROOT}/dashboard.css`, "text/css; charset=utf-8"); if (pathname === "/dashboard/assets/dashboard.js") return textAsset(`${DASHBOARD_ASSET_ROOT}/dashboard.js`, "application/javascript; charset=utf-8"); return null; } function textAsset(path: string, contentType: string): Response { return new Response(readFileSync(rootPath(path), "utf8"), { headers: { "cache-control": "no-store", "content-type": contentType, }, }); } function stringOrNull(value: unknown): string | null { return typeof value === "string" && value.length > 0 ? value : null; } function escapeHtml(value: string): string { return value.replace(/&/gu, "&").replace(//gu, ">").replace(/"/gu, """); } function escapeAttr(value: string): string { return escapeHtml(value).replace(/'/gu, "'"); }