feat: enrich cloud workbench hardware status

This commit is contained in:
HWLAB Code Queue
2026-05-22 14:08:56 +00:00
parent c7de4745f4
commit 92799a006a
5 changed files with 314 additions and 31 deletions
@@ -73,6 +73,21 @@ const requiredWiringColumns = Object.freeze([
"trace/evidence"
]);
const requiredHardwareStatusTerms = Object.freeze([
"hardware-source-status",
"hardwareGroup",
"hardwareRow",
"Gateway/Box 在线",
"BOX-SIMU 端口",
"Patch Panel 连线",
"DO1 -> patch-panel -> DI1",
"AI/AO/FREQ",
"future capability",
"SOURCE",
"DEV-LIVE",
"BLOCKED"
]);
const workbenchMarkers = Object.freeze([
"data-app-shell",
"workbench-shell",
@@ -192,6 +207,11 @@ function runStaticSmoke() {
evidence: requiredWiringColumns
});
addCheck(checks, blockers, "hardware-status-rich-structure", hardwareStatusStructureContract(files), "Right hardware status renders Gateway/Box, DI/DO/AI/AO/FREQ, patch-panel, and DO1 -> DI1 source-labeled link state.", {
blocker: "contract_blocker",
evidence: requiredHardwareStatusTerms
});
addCheck(checks, blockers, "outer-scroll-contract", hasScrollLockContract(files.styles), "Outer page scrolling is locked and internal workbench panes own scrolling.", {
blocker: "contract_blocker",
evidence: ["html/body overflow hidden", "workbench-shell 100vh/100dvh overflow hidden", ".view overflow auto"]
@@ -427,6 +447,23 @@ function wiringTableContract(html) {
return requiredWiringColumns.every((column) => wiringPanel.includes(`<th>${column}</th>`));
}
function hardwareStatusStructureContract({ html, app, styles }) {
const source = `${html}\n${app}\n${styles}`;
return (
requiredHardwareStatusTerms.every((term) => source.includes(term)) &&
/id=["']hardware-source-status["']/u.test(html) &&
/function\s+renderHardwareStatus\s*\(/u.test(app) &&
/function\s+hardwareGroup\s*\(/u.test(app) &&
/function\s+hardwareRow\s*\(/u.test(app) &&
/function\s+trustedM3Link\s*\(/u.test(app) &&
/function\s+linkStatusLabel\s*\(/u.test(app) &&
/function\s+normalizePort\s*\(/u.test(app) &&
/Web 不提供硬件写 RPC;不会新增伪硬件写操作。/u.test(app) &&
/\.hardware-section\s*\{/u.test(styles) &&
/\.hardware-row\s*\{/u.test(styles)
);
}
function finalRouteFallback(app) {
const body = app.match(/function\s+routeFromLocation\s*\(\)\s*\{([\s\S]*?)\n\}/u)?.[1] ?? "";
const returns = [...body.matchAll(/return\s+["']([^"']+)["']\s*;/gu)].map((match) => match[1]);