推进 INI 面板 entry docs strict gate

This commit is contained in:
2026-06-14 23:40:26 +08:00
parent ef4769b4b4
commit ac463453da
3 changed files with 94 additions and 7 deletions

View File

@@ -1570,3 +1570,66 @@ host_wasm_opfs_browser_smokes=ok
继续压缩表述面。下一批建议让 `ui-shell.js` 直接成为 launcher 页面和 docs 的唯一入口
来源,或者再补一个更短的 `ui-shell.md` 汇总 shell、launcher、control-page 三者关系;仍保持
只读,不新增控制按钮,不解析 G-code。
二十、2026-06-14 继续执行记录INI panel entry docs strict gate
本轮按“加快实质性推进”加强 `panel-entry.md` 的一致性 gate从字符串存在检查升级为完整
shell export、页面路径和 manifest 表校验,减少入口文档漂移风险。
完成内容:
- `wasm-port/docs/panel-entry.md` 的 shell import 示例补齐:
- `INI_PANEL_ENTRIES`
- `getIniPanelEntryByHref`
- `getIniPanelEntryManifest`
- `createMachineSessionControlPageController`
- `renderMachineSessionControlView`
- `wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs` 现在校验:
- `ui-shell.js` 实际导出名;
- 文档中的 shell import 名;
- `launch.html`、`index.html`、`control-page.html` 页面路径;
- `getIniPanelEntryManifest()` 与 `INI_PANEL_ENTRIES` 一致;
- 文档 manifest 表中每个 entry 的 id、href、title
- 未新增控制按钮;
- 未解析 G-code
- 未解释 canonical events
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
LinuxCNC-owned runtime semantics。
验证已通过:
```bash
git diff --check
wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
wasm-port/tests/browser/verify_ini_panel_browser.sh
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
wasm-port/tests/host/verify_host_smokes.sh
```
关键输出:
```text
ini_panel_entry_docs_node_smoke=ok
ui_node_smokes=ok
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
vendor sync up to date
standalone CNC semantics guard complete
interp_wasm_node_smoke=ok
sim_configs_wasm_node_inventory_executed=28
sim_configs_wasm_node_inventory_passed=28
sim_configs_wasm_node_inventory_skipped=131
sim_configs_wasm_node_inventory_unexpected_fail=0
host_wasm_opfs_browser_smokes=ok
```
下一步建议:
继续推进实质 UI/API surface。下一批建议把 `ui-shell.js` 中用于 launcher 的入口列表再封装成
`getVisibleIniPanelEntries()`,让页面不需要知道 manifest 复制语义;仍保持只读,不新增控制
按钮,不解析 G-code。

View File

@@ -9,6 +9,8 @@ control view:
```js
import {
INI_PANEL_ENTRIES,
getIniPanelEntryByHref,
getIniPanelEntryManifest,
createMachineSessionControlPageController,
renderMachineSessionControlView,

View File

@@ -4,21 +4,43 @@ import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import {
INI_PANEL_ENTRIES,
getIniPanelEntryManifest,
} from "../../../runtime/ui/ini-panel/ui-shell.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "../../..");
const docText = readFileSync(resolve(root, "docs/panel-entry.md"), "utf8");
const shellText = readFileSync(resolve(root, "runtime/ui/ini-panel/ui-shell.js"), "utf8");
assert.match(docText, /runtime\/ui\/ini-panel\/ui-shell\.js/);
assert.match(docText, /createMachineSessionControlPageController/);
assert.match(docText, /renderMachineSessionControlView/);
assert.match(docText, /runtime\/ui\/ini-panel\/launch\.html/);
assert.match(docText, /runtime\/ui\/ini-panel\/control-page\.html/);
const requiredShellExports = [
"INI_PANEL_ENTRIES",
"getIniPanelEntryByHref",
"getIniPanelEntryManifest",
"createMachineSessionControlPageController",
"renderMachineSessionControlView",
];
for (const entry of getIniPanelEntryManifest()) {
assert.match(docText, new RegExp(`\\| \`${entry.id}\` \\| \`${entry.href.replace(".", "\\.")}\` \\| ${entry.title} \\|`));
for (const exportName of requiredShellExports) {
assert.match(shellText, new RegExp(`\\b${exportName}\\b`));
assert.match(docText, new RegExp(`\\b${exportName}\\b`));
}
const requiredPages = [
["Launch", "runtime/ui/ini-panel/launch.html"],
["Edit and run", "runtime/ui/ini-panel/index.html"],
["Read-only control view", "runtime/ui/ini-panel/control-page.html"],
];
for (const [label, path] of requiredPages) {
assert.match(docText, new RegExp(`\\| ${label} \\| \`${path.replaceAll("/", "\\/")}\``));
}
assert.deepEqual(getIniPanelEntryManifest(), INI_PANEL_ENTRIES);
for (const entry of INI_PANEL_ENTRIES) {
const escapedHref = entry.href.replace(".", "\\.");
assert.match(docText, new RegExp(`\\| \`${entry.id}\` \\| \`${escapedHref}\` \\| ${entry.title} \\|`));
}
console.log("ini_panel_entry_docs_node_smoke=ok");