import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const repoRoot = path.resolve(rootDir, "../.."); const requiredFiles = Object.freeze([ "index.html", "styles.css", "auth.mjs", "app.mjs", "code-agent-facts.mjs", "code-agent-status.mjs", "message-markdown.mjs", "live-status.mjs", "runtime.mjs", "favicon.svg", "favicon.ico", "help.md", "third_party/marked/marked.esm.js", "third_party/marked/LICENSE" ]); for (const file of requiredFiles) { const filePath = path.resolve(rootDir, file); if (!fs.existsSync(filePath)) throw new Error(`missing web asset: ${file}`); } runJavaScriptSyntaxCheck(); const html = readWeb("index.html"); const styles = readWeb("styles.css"); const app = readWeb("app.mjs"); const liveStatus = readWeb("live-status.mjs"); const helpMarkdown = readWeb("help.md"); const faviconSvg = readWeb("favicon.svg"); const faviconIco = readWeb("favicon.ico"); const distContractScript = readWeb("scripts/dist-contract.mjs"); const cloudApiServer = readRepo("internal/cloud/server.mjs"); const devicePodData = readRepo("internal/device-pod/fake-data.mjs"); const devicePodService = readRepo("cmd/hwlab-device-pod/main.mjs"); const protocol = readRepo("internal/protocol/index.mjs"); const deployJson = readRepo("deploy/deploy.json"); const artifactCatalog = readRepo("deploy/artifact-catalog.dev.json"); const rightSidebar = sectionById(html, "aside", "device-pod-sidebar"); assert.ok(rightSidebar, "Device Pod right sidebar must exist"); for (const term of [ "Device Pod", "设备目标看板", "id=\"device-pod-select\"", "id=\"device-pod-summary\"", "data-device-detail=\"pod\"", "id=\"device-pod-interfaces\"", "id=\"device-event-scroll\"", "id=\"device-event-text\"", "id=\"device-detail-dialog\"" ]) { assertIncludes(rightSidebar, term, `right sidebar missing ${term}`); } assert.doesNotMatch(rightSidebar, /]*role="button"[^>]*tabindex="0"/u, "Pod summary is a click/keyboard summary tile"); assert.match(rightSidebar, /