From f560c7a76e7f62b84a75fa223a0feffb0595bcb8 Mon Sep 17 00:00:00 2001 From: HWLAB Code Queue Date: Fri, 22 May 2026 10:51:31 +0000 Subject: [PATCH] feat: add Cloud Workbench Markdown help page --- web/hwlab-cloud-web/app.mjs | 33 +++++++- web/hwlab-cloud-web/help.md | 43 +++++++++++ web/hwlab-cloud-web/index.html | 16 +++- web/hwlab-cloud-web/scripts/build.mjs | 18 ++++- web/hwlab-cloud-web/scripts/check.mjs | 57 +++++++++++++- web/hwlab-cloud-web/styles.css | 73 ++++++++++++++++++ .../third_party/marked/LICENSE | 44 +++++++++++ .../third_party/marked/marked.esm.js | 76 +++++++++++++++++++ 8 files changed, 355 insertions(+), 5 deletions(-) create mode 100644 web/hwlab-cloud-web/help.md create mode 100644 web/hwlab-cloud-web/third_party/marked/LICENSE create mode 100644 web/hwlab-cloud-web/third_party/marked/marked.esm.js diff --git a/web/hwlab-cloud-web/app.mjs b/web/hwlab-cloud-web/app.mjs index 665e675e..1bc93c1e 100644 --- a/web/hwlab-cloud-web/app.mjs +++ b/web/hwlab-cloud-web/app.mjs @@ -1,5 +1,6 @@ import { gateSummary } from "./gate-summary.mjs"; import { runtime } from "./runtime.mjs"; +import { marked } from "./third_party/marked/marked.esm.js"; const API_TIMEOUT_MS = 4500; const rpcReadMethods = Object.freeze([ @@ -71,7 +72,9 @@ const el = { wiringList: byId("wiring-list"), recordsList: byId("records-list"), diagnosticsList: byId("diagnostics-list"), - methodList: byId("method-list") + methodList: byId("method-list"), + helpContent: byId("help-content"), + helpStatus: byId("help-status") }; const state = { @@ -84,6 +87,7 @@ initSideTabs(); initCommandBar(); renderStaticWorkbench(); renderProbePending(); +loadHelpSurface(); loadLiveSurface().then(renderLiveSurface); function byId(id) { @@ -139,6 +143,33 @@ function initExplorerToggle() { }); } +async function loadHelpSurface() { + el.helpStatus.textContent = "加载中"; + el.helpStatus.className = "state-tag tone-dry-run"; + el.helpContent.dataset.helpState = "loading"; + + try { + const response = await fetch("./help.md", { cache: "no-store" }); + if (!response.ok) { + throw new Error(`help.md HTTP ${response.status}`); + } + const markdown = await response.text(); + el.helpContent.innerHTML = marked.parse(markdown, { gfm: true, breaks: false }); + el.helpContent.dataset.helpState = "ready"; + el.helpStatus.textContent = "已就绪"; + el.helpStatus.className = "state-tag tone-source"; + } catch (error) { + el.helpContent.dataset.helpState = "error"; + el.helpContent.replaceChildren(); + const notice = document.createElement("div"); + notice.className = "help-error"; + notice.textContent = `帮助内容加载失败:${error.message}。默认工作台仍可继续使用。`; + el.helpContent.append(notice); + el.helpStatus.textContent = "加载失败"; + el.helpStatus.className = "state-tag tone-blocked"; + } +} + function initSideTabs() { for (const tab of document.querySelectorAll("[data-side-tab]")) { tab.addEventListener("click", () => selectSideTab(tab.dataset.sideTab)); diff --git a/web/hwlab-cloud-web/help.md b/web/hwlab-cloud-web/help.md new file mode 100644 index 00000000..93c1c880 --- /dev/null +++ b/web/hwlab-cloud-web/help.md @@ -0,0 +1,43 @@ +# 云工作台内部使用说明 + +本页面说明当前 Cloud Workbench 的前端区域与状态含义。默认 `/` 仍进入工作台;本说明只通过工作台内部的 `#help` 入口打开。 + +## 左侧资源与功能导航 + +- 活动栏:`台` 回到默认工作台,`证` 跳到右侧可信记录,`诊` 打开 Gate / 诊断二级入口,`帮` 打开本说明,`树` 展开或收起资源树。 +- 资源树:展示当前项目、Gateway-SIMU、BOX-SIMU、`hwlab-patch-panel`、Agent manager / worker 与 M0-M5 Gate 状态。它只解释来源状态,不提供硬件写操作。 +- 来源条:展示 `SOURCE`、`DRY-RUN`、`DEV-LIVE`、`BLOCKED` 的当前解释。`LOCAL` 只表示浏览器本地草稿,不等同于 DEV-LIVE。 + +## 中间 Agent 对话与 trace + +- Agent 对话区显示工作台范围、当前验收摘要、阻塞项和可执行的本地草稿动作。 +- 执行轨迹区展示 M0-M5 计划步骤、依赖关系和输出数量,用于复核流程状态。 +- 底部输入栏只把文字保存为浏览器本地草稿,不调用硬件写 API,不提交 patch-panel 变更,也不写入审计或证据记录。 + +## 右侧硬件与状态面板 + +- BOX-SIMU / Gateway-SIMU / Patch Panel 卡片展示只读计数、source fallback 与当前阻塞状态。 +- M3 虚拟硬件可信闭环的上位约束是:`res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1`。只有观察到这条完整链路并带有可信记录时,才可作为 M3 DEV-LIVE 依据。 +- Web 前端不会新增 `hardware.*` 写 RPC、patch-panel 写接口、audit 写接口或 evidence 写接口。 + +## 右侧二级入口 + +- 控制:显示本地草稿和只读能力边界。这里的控制项保持禁用或本地记录状态。 +- 接线:解释 `hwlab-patch-panel` 当前 source wiring,帮助确认 DO1 到 DI1 的可信闭环路径是否仍由 patch-panel 拥有。 +- 可信记录:合并 source fixture 与只读 `evidence.record.query` 结果。source、fixture、LOCAL、DRY-RUN 记录不能升级成 DEV-LIVE。 +- 诊断:只检查 same-origin `/health/live`、same-origin `/v1` 与只读 `/json-rpc` 方法。允许的方法包括 `system.health`、`cloud.adapter.describe`、`audit.event.query`、`evidence.record.query`。 +- Gate:从活动栏 `诊` 进入,作为验收复核二级页面保留,不替代默认工作台。 + +## 来源标签含义 + +- `SOURCE`:来自仓库内 source report、静态配置或已签入摘要,用于解释当前界面。 +- `LOCAL`:只存在于当前浏览器会话的本地输入或草稿。 +- `DRY-RUN`:演练或 fixture 证据,不能声称真实硬件闭环已经通过。 +- `DEV-LIVE`:必须来自同源只读探测或可信记录,并且满足 DB readiness、阻塞清零与 M3 闭环证据要求。 +- `BLOCKED`:表示当前前置条件未满足、探测失败、证据不足或不能把 SOURCE / LOCAL / DRY-RUN / fixture 升级为 DEV-LIVE。 + +## 端口与只读边界 + +- 前端入口保持 `:16666`,API / edge 入口保持 `:16667`。 +- 浏览器内 API 访问保持 same-origin `/v1`、只读 `/json-rpc` 与 `/health/live`。 +- 旧公网 `:6666` / `:6667` 不是当前前端验收口径;内部 k3s 服务端口说明不改变浏览器入口。 diff --git a/web/hwlab-cloud-web/index.html b/web/hwlab-cloud-web/index.html index 9858cd87..1524ea76 100644 --- a/web/hwlab-cloud-web/index.html +++ b/web/hwlab-cloud-web/index.html @@ -8,11 +8,12 @@ -
+
@@ -87,6 +88,19 @@ + +