推进 INI 面板 shell handoff snapshot API
This commit is contained in:
85
text12.txt
85
text12.txt
@@ -2086,3 +2086,88 @@ host_wasm_opfs_browser_smokes=ok
|
||||
继续推进 SDK/API surface。下一批建议为 shell/session handoff summary 增加 focused compatibility
|
||||
predicate 或 versioned summary schema(例如 `createIniPanelShellSessionHandoffSummarySchema()`),
|
||||
让外部 shell 能独立判断 summary shape 是否可消费;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
|
||||
二十六、2026-06-15 继续执行记录:INI panel shell session handoff summary schema gate
|
||||
|
||||
本轮按“第一原则:加快实质性推进”继续推进 SDK/API surface,为 shell/session handoff
|
||||
summary 增加 versioned schema 与 focused compatibility predicate,并暴露到真实 launch browser
|
||||
API,让外部 shell 能在消费 summary 前独立判断 shape 是否可支持。
|
||||
|
||||
完成内容:
|
||||
|
||||
- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffSummarySchema()`;
|
||||
- `ui-shell.js` 新增 `isSupportedIniPanelShellSessionHandoffSummary()`;
|
||||
- `createIniPanelShellSessionHandoffSummary()` 新增:
|
||||
- `apiName: "ini-panel-shell-session-handoff-summary"`;
|
||||
- `summaryVersion: 1`;
|
||||
- `createIniPanelLaunchApiManifest().methods` 新增:
|
||||
- `getShellSessionHandoffSummarySchema`;
|
||||
- `isSupportedShellSessionHandoffSummary`;
|
||||
- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增:
|
||||
- `getShellSessionHandoffSummarySchema()`;
|
||||
- `isSupportedShellSessionHandoffSummary()`;
|
||||
- `ini_panel_launch_smoke.html` 在真实 launch iframe 中校验:
|
||||
- summary schema version;
|
||||
- 当前 summary 可支持;
|
||||
- 错误 summary version 被拒绝;
|
||||
- `ini_panel_shell_integration_workflow_smoke.html` 在 browser shell handoff workflow 中校验:
|
||||
- launch API 暴露 summary schema 与 predicate;
|
||||
- 当前 handoff summary 可支持;
|
||||
- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖:
|
||||
- summary schema 完整 shape;
|
||||
- valid summary 支持;
|
||||
- 错误 version、错误 apiName、缺字段、null 被拒绝;
|
||||
- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_ui_shell.mjs`、
|
||||
`verify_ini_panel_entry_docs.mjs` 与 `docs/panel-entry.md` 同步记录和校验新 API;
|
||||
- 未新增控制按钮;
|
||||
- 未解析 G-code;
|
||||
- 未解释 canonical events;
|
||||
- 未新增 JS CNC 语义;
|
||||
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
|
||||
LinuxCNC-owned runtime semantics。
|
||||
|
||||
验证已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 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_shell_integration_manifest_node_smoke=ok
|
||||
ini_panel_launch_api_manifest_node_smoke=ok
|
||||
ini_panel_ui_shell_node_smoke=ok
|
||||
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
|
||||
browser_ini_shell_integration_workflow_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
|
||||
```
|
||||
|
||||
下一步建议:
|
||||
|
||||
继续推进 SDK/API surface 与 browser/UI workflow 的交界。下一批建议增加一个
|
||||
`createIniPanelShellSessionHandoffCompatibilityReport()` 或等价 helper,把 summary schema
|
||||
支持状态、缺失字段、version/apiName mismatch 与 blocking reasons 合并成可显示报告,便于外部
|
||||
shell 在 UI 中解释为什么不能消费 handoff summary;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
|
||||
509
text13.txt
Normal file
509
text13.txt
Normal file
@@ -0,0 +1,509 @@
|
||||
项目整体完成情况与后续执行计划
|
||||
|
||||
生成时间:2026-06-15 CST
|
||||
|
||||
本文件接替 `text12.txt`。后续工作按 `text13.txt` 执行;除非明确要求审计旧记录,
|
||||
不要再回到 `text1/text2/text3/text4/text5/text6/text7/text8/text9/text10/text11/text12`
|
||||
扩展进度。`text12.txt` 作为历史归档保留。
|
||||
|
||||
一、第一原则:加快实质性推进
|
||||
|
||||
后续批次必须以“实质性能力优先”为第一遵守原则。
|
||||
|
||||
1. 优先级从高到低:
|
||||
|
||||
- OPFS/session persistence;
|
||||
- SDK/API surface;
|
||||
- browser/UI workflow;
|
||||
- sim config coverage promotion;
|
||||
- host/runtime boundary proof;
|
||||
- 文档化可执行工作流。
|
||||
|
||||
2. 每批默认应产出至少一种可直接复用的能力:
|
||||
|
||||
- 可调用 helper;
|
||||
- 可复用 API;
|
||||
- 可验证用户流程;
|
||||
- 可执行 gate;
|
||||
- 可提升覆盖面的 runtime boundary proof;
|
||||
- 能直接指导下一步实现的设计/清单。
|
||||
|
||||
3. 暂停低收益推进:
|
||||
|
||||
- 不再把“局部常量化、路径变量收敛、断言分组整理”作为主目标;
|
||||
- 只有当它支撑可复用 workflow/API/gate 时,才允许做测试胶水;
|
||||
- 禁止为了推进而扩大 CNC 语义边界;
|
||||
- 禁止启动性能测试,除非已有明确用户流程需要性能基线。
|
||||
|
||||
4. LinuxCNC 仍是唯一 CNC 语义来源:
|
||||
|
||||
- G-code、remap、tool、parameter、planner、kinematics、user-M、tool DB、Python remap
|
||||
等语义必须来自 LinuxCNC upstream 或 vendored LinuxCNC C/C++/配置/脚本源码;
|
||||
- JS/browser 只允许做 build、source sync、runtime shim、filesystem staging、OPFS、
|
||||
WASM/browser boundary、测试胶水、文档和机器可读 gate/artifact;
|
||||
- 不在 JS 中重写 G-code 或 CNC 语义;
|
||||
- 不修改 vendored LinuxCNC 源文件来让测试通过;
|
||||
- 不把 full-process/HAL/UI/Python/tool DB 依赖伪装成 standalone pass;
|
||||
- 不把 expected failure 硬改成 pass,除非已有 LinuxCNC-owned runtime proof,并且
|
||||
native、Node、browser gate 都按顺序通过;
|
||||
- browser 不能依赖目录枚举。
|
||||
|
||||
二、续接状态与防重规则
|
||||
|
||||
1. 当前续接点。
|
||||
|
||||
`text12.txt` 已推进到:
|
||||
|
||||
```text
|
||||
二十六、2026-06-15 继续执行记录:INI panel shell session handoff summary schema gate
|
||||
```
|
||||
|
||||
本文件从 `text13.txt` 重新开始记录后续进度。
|
||||
|
||||
2. 每轮开始前必须先执行:
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git log -5 --oneline
|
||||
tail -n 120 text13.txt
|
||||
awk '/^[一二三四五六七八九十百]+、/ {print}' text13.txt | sort | uniq -d
|
||||
```
|
||||
|
||||
执行规则:
|
||||
|
||||
- 如果 `git status --short` 是 clean,且最新提交已经包含当前建议工作,不要重复追加记录;
|
||||
- 每轮只追加一个新的中文编号记录;
|
||||
- 提交前再次检查标题唯一性;
|
||||
- `text13.txt` 只记录新的后续进度,不复制 `text12.txt` 的长历史;
|
||||
- 每批完成后,如果要写记录,先写 `text13.txt`,再提交该批代码和记录;
|
||||
- 如果发现重复记录,先做 dedupe 清理并提交,再继续新功能或新 guard;
|
||||
- `text12.txt` 不再追加新进度,除非明确要求审计或修正历史记录。
|
||||
|
||||
三、当前完成情况摘要
|
||||
|
||||
1. 当前工作树状态。
|
||||
|
||||
切换到 `text13.txt` 时工作树包含上一批未提交改动:
|
||||
|
||||
```text
|
||||
M text12.txt
|
||||
M wasm-port/docs/panel-entry.md
|
||||
M wasm-port/runtime/ui/ini-panel/launch.html
|
||||
M wasm-port/runtime/ui/ini-panel/ui-shell.js
|
||||
M wasm-port/tests/browser/ini_panel_launch_smoke.html
|
||||
M wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html
|
||||
M wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs
|
||||
M wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs
|
||||
M wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs
|
||||
M wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs
|
||||
```
|
||||
|
||||
上述改动对应 `text12.txt` 第 26 条:shell session handoff summary schema gate。
|
||||
|
||||
2. 最近提交:
|
||||
|
||||
```text
|
||||
01817f6 推进 INI 面板 shell handoff summary browser API
|
||||
b31b9a2 推进 INI 面板 shell session handoff summary
|
||||
ee665c4 推进 INI 面板 shell integration workflow plan
|
||||
a663c8d 推进 INI 面板 shell integration browser workflow smoke
|
||||
1f9a8c3 推进 INI 面板 shell integration readiness helper
|
||||
```
|
||||
|
||||
3. 关键基线保持稳定。
|
||||
|
||||
- `linuxcnc/nc_files` native Layer 1:
|
||||
- `total 107`
|
||||
- `pass 101`
|
||||
- `expected_fail 6`
|
||||
- `unexpected_fail 0`
|
||||
- `linuxcnc/configs/sim` native Layer 2:
|
||||
- `total 159`
|
||||
- `pass 151`
|
||||
- `expected_fail 8`
|
||||
- `unexpected_fail 0`
|
||||
- Node sim-config inventory:
|
||||
- `executed=28`
|
||||
- `passed=28`
|
||||
- `skipped=131`
|
||||
- `unexpected_fail=0`
|
||||
|
||||
4. blocked runtime family 仍未 promotion。
|
||||
|
||||
仍 blocked,不允许 promotion:
|
||||
|
||||
- `L4-USER-M-PROCESS`
|
||||
- `L4-TOOL-DB`
|
||||
- `L4-PYTHON-REMAP`
|
||||
|
||||
当前 host 仍按缺少 LinuxCNC host runtime 处理,不执行任何:
|
||||
|
||||
```bash
|
||||
ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_millturn_user_m_runtime.sh
|
||||
ENABLE_TOOL_DB_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_tool_db_runtime.sh
|
||||
ENABLE_PYTHON_REMAP_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_python_remap_runtime.sh
|
||||
```
|
||||
|
||||
四、当前实质能力进展
|
||||
|
||||
1. INI panel/UI helper 能力。
|
||||
|
||||
当前 UI helper 已覆盖:
|
||||
|
||||
- run summary;
|
||||
- run workflow;
|
||||
- session snapshot summary;
|
||||
- session load summary;
|
||||
- machine file save/load summary;
|
||||
- panel state summary;
|
||||
- session snapshot save/restore workflow;
|
||||
- entry manifest、launcher link view-model、shell view-model;
|
||||
- read-only control-page controller;
|
||||
- read-only control-page refresh workflow;
|
||||
- read-only control-page session readiness workflow;
|
||||
- shell integration readiness、workflow plan、session handoff summary;
|
||||
- shell session handoff summary versioned schema 与 compatibility predicate。
|
||||
|
||||
当前聚合验证入口:
|
||||
|
||||
```bash
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
```
|
||||
|
||||
2. Browser/UI workflow 验证。
|
||||
|
||||
当前 browser INI panel smoke 覆盖真实 OPFS/session persistence workflow 与外部 shell handoff:
|
||||
|
||||
```bash
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
|
||||
```
|
||||
|
||||
关键输出:
|
||||
|
||||
```text
|
||||
browser_ini_opfs_smoke=ok
|
||||
browser_ini_control_page_smoke=ok
|
||||
browser_ini_launch_smoke=ok
|
||||
browser_ini_shell_integration_workflow_smoke=ok
|
||||
```
|
||||
|
||||
五、当前必须保持通过的验证入口
|
||||
|
||||
每批后续改动至少运行:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
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
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
wasm-port/tests/host/verify_host_smokes.sh
|
||||
```
|
||||
|
||||
如果涉及 browser interpreter smoke,再运行:
|
||||
|
||||
```bash
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh
|
||||
```
|
||||
|
||||
涉及 native baseline 或大范围 source/staging 改动时,再运行:
|
||||
|
||||
```bash
|
||||
wasm-port/tests/native/verify_nc_files.sh
|
||||
wasm-port/tests/native/verify_sim_configs.sh
|
||||
```
|
||||
|
||||
六、下一步建议
|
||||
|
||||
继续推进 SDK/API surface 与 browser/UI workflow 的交界。下一批建议增加一个
|
||||
`createIniPanelShellSessionHandoffCompatibilityReport()` 或等价 helper,把 summary schema
|
||||
支持状态、缺失字段、version/apiName mismatch 与 blocking reasons 合并成可显示报告,便于外部
|
||||
shell 在 UI 中解释为什么不能消费 handoff summary;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
|
||||
一、2026-06-15 继续执行记录:INI panel shell session handoff compatibility report
|
||||
|
||||
本轮按“第一原则:加快实质性推进”创建 `text13.txt` 续接文件,并继续推进 SDK/API
|
||||
surface 与 browser/UI workflow 的交界:新增 shell session handoff compatibility report,让外部
|
||||
shell 能读取 display-ready 诊断,判断 handoff summary 是否可消费以及失败原因。
|
||||
|
||||
完成内容:
|
||||
|
||||
- 新建 `text13.txt`,接替 `text12.txt` 作为后续执行记录;
|
||||
- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffCompatibilityReport()`;
|
||||
- compatibility report 输出:
|
||||
- `apiName: "ini-panel-shell-session-handoff-compatibility-report"`;
|
||||
- `reportVersion: 1`;
|
||||
- `phase: "ready" | "blocked"`;
|
||||
- `compatible`;
|
||||
- `summarySupported`;
|
||||
- `handoffReady`;
|
||||
- `schema`;
|
||||
- `summary`;
|
||||
- `missingFields`;
|
||||
- `mismatchFields`;
|
||||
- `blockingReasons`;
|
||||
- `createIniPanelShellViewModel()` 新增:
|
||||
- `shellSessionHandoffCompatibilityReport`;
|
||||
- `createShellSessionHandoffCompatibilityReport`;
|
||||
- `createIniPanelLaunchApiManifest().methods` 新增
|
||||
`getShellSessionHandoffCompatibilityReport`;
|
||||
- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增真实 browser 入口
|
||||
`getShellSessionHandoffCompatibilityReport()`;
|
||||
- `ini_panel_launch_smoke.html` 校验真实 launch iframe 的 compatibility report:
|
||||
- `compatible === true`;
|
||||
- `summarySupported === true`;
|
||||
- `missingFields` 为空;
|
||||
- `ini_panel_shell_integration_workflow_smoke.html` 校验外部 shell handoff workflow 能读取
|
||||
compatibility report,并确认当前 report 无 blocking reasons;
|
||||
- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖:
|
||||
- ready report 完整 shape;
|
||||
- 错误 `summaryVersion` 进入 `mismatchFields`;
|
||||
- 缺字段进入 `missingFields`;
|
||||
- `null` summary 返回完整缺字段列表;
|
||||
- blocked workflow 的 `blockingReasons` 和 `compatible === false`;
|
||||
- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_ui_shell.mjs`、
|
||||
`verify_ini_panel_entry_docs.mjs` 与 `docs/panel-entry.md` 同步记录和校验新 helper/API;
|
||||
- 未新增控制按钮;
|
||||
- 未解析 G-code;
|
||||
- 未解释 canonical events;
|
||||
- 未新增 JS CNC 语义;
|
||||
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
|
||||
LinuxCNC-owned runtime semantics。
|
||||
|
||||
验证已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 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_shell_integration_manifest_node_smoke=ok
|
||||
ini_panel_launch_api_manifest_node_smoke=ok
|
||||
ini_panel_ui_shell_node_smoke=ok
|
||||
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
|
||||
browser_ini_shell_integration_workflow_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
|
||||
```
|
||||
|
||||
下一步建议:
|
||||
|
||||
继续推进 browser/UI workflow。下一批建议把 compatibility report 用到一个真实的外部 shell
|
||||
display view-model 或 DOM smoke 中,让 launch 页面能直接展示 handoff 是否可消费、缺失字段和
|
||||
blocking reasons;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
|
||||
二、2026-06-15 继续执行记录:INI panel shell handoff display view-model
|
||||
|
||||
本轮按“第一原则:加快实质性推进”继续推进 browser/UI workflow,把上一批 compatibility
|
||||
report 接入可复用 display view-model 与真实 launch DOM,让外部 shell 能直接展示 handoff
|
||||
是否可消费、缺失字段、mismatch fields 与 blocking reasons。
|
||||
|
||||
完成内容:
|
||||
|
||||
- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffDisplayViewModel()`;
|
||||
- display view-model 输出:
|
||||
- `phase: "ready" | "blocked"`;
|
||||
- `title`;
|
||||
- `statusText`;
|
||||
- `detailText`;
|
||||
- `rows`;
|
||||
- `rows` 固定覆盖:
|
||||
- `summary-supported`;
|
||||
- `handoff-ready`;
|
||||
- `missing-fields`;
|
||||
- `mismatch-fields`;
|
||||
- `blocking-reasons`;
|
||||
- `createIniPanelShellViewModel()` 新增:
|
||||
- `shellSessionHandoffDisplayViewModel`;
|
||||
- `createShellSessionHandoffDisplayViewModel`;
|
||||
- `createIniPanelLaunchApiManifest().methods` 新增
|
||||
`getShellSessionHandoffDisplayViewModel`;
|
||||
- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增真实 browser 入口
|
||||
`getShellSessionHandoffDisplayViewModel()`;
|
||||
- `launch.html` 新增只读 DOM 展示区域:
|
||||
- `[data-handoff-status]`;
|
||||
- `[data-handoff-rows]`;
|
||||
- `[data-handoff-value="missing-fields"]`;
|
||||
- `[data-handoff-value="blocking-reasons"]`;
|
||||
- `ini_panel_launch_smoke.html` 校验真实 launch iframe:
|
||||
- display view-model `statusText === "Ready"`;
|
||||
- display rows 数量为 5;
|
||||
- DOM status 为 `Ready: No blocking reasons`;
|
||||
- DOM missing fields 为 `none`;
|
||||
- DOM blocking reasons 为 `none`;
|
||||
- `ini_panel_shell_integration_workflow_smoke.html` 校验外部 shell workflow 能读取
|
||||
display view-model,并确认 display status/detail 与 compatibility report 一致;
|
||||
- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖:
|
||||
- ready display view-model 完整 shape;
|
||||
- 错误 `summaryVersion` 显示到 `mismatch-fields` row;
|
||||
- `verify_ini_panel_ui_shell.mjs` 覆盖 shell view-model 的 display view-model shape;
|
||||
- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_entry_docs.mjs` 与
|
||||
`docs/panel-entry.md` 同步记录和校验新 helper/API/DOM 节点;
|
||||
- 未新增控制按钮;
|
||||
- 未解析 G-code;
|
||||
- 未解释 canonical events;
|
||||
- 未新增 JS CNC 语义;
|
||||
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
|
||||
LinuxCNC-owned runtime semantics。
|
||||
|
||||
验证已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 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_ui_shell_node_smoke=ok
|
||||
ini_panel_shell_integration_manifest_node_smoke=ok
|
||||
ini_panel_launch_api_manifest_node_smoke=ok
|
||||
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
|
||||
browser_ini_shell_integration_workflow_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
|
||||
```
|
||||
|
||||
下一步建议:
|
||||
|
||||
继续推进 OPFS/session persistence 与 browser/UI workflow 的交界。下一批建议新增一个只读
|
||||
`createIniPanelShellSessionHandoffSnapshot()` 或等价 helper,把 integration readiness、handoff
|
||||
summary、compatibility report、display view-model 聚合成单次外部 shell snapshot API,减少外部
|
||||
shell 多次读取 launch API 的组合风险;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
|
||||
三、2026-06-15 继续执行记录:INI panel shell handoff snapshot API
|
||||
|
||||
本轮按“第一原则:加快实质性推进”继续推进 OPFS/session persistence 与 browser/UI workflow
|
||||
的交界,新增只读 shell handoff snapshot API,把 integration readiness、handoff summary、
|
||||
compatibility report 和 display view-model 聚合成单次外部 shell 读取。
|
||||
|
||||
完成内容:
|
||||
|
||||
- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffSnapshot()`;
|
||||
- snapshot 输出:
|
||||
- `apiName: "ini-panel-shell-session-handoff-snapshot"`;
|
||||
- `snapshotVersion: 1`;
|
||||
- `phase`;
|
||||
- `ready`;
|
||||
- `readiness`;
|
||||
- `summary`;
|
||||
- `compatibilityReport`;
|
||||
- `displayViewModel`;
|
||||
- `createIniPanelShellViewModel()` 新增:
|
||||
- `shellSessionHandoffSnapshot`;
|
||||
- `createShellSessionHandoffSnapshot`;
|
||||
- `createIniPanelLaunchApiManifest().methods` 新增
|
||||
`getShellSessionHandoffSnapshot`;
|
||||
- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增真实 browser 入口
|
||||
`getShellSessionHandoffSnapshot()`;
|
||||
- `ini_panel_launch_smoke.html` 校验真实 launch iframe:
|
||||
- snapshot version 为 1;
|
||||
- snapshot `ready === true`;
|
||||
- snapshot readiness 与独立 readiness API 一致;
|
||||
- snapshot summary 与独立 summary API 一致;
|
||||
- snapshot display view-model 与独立 display API 一致;
|
||||
- `ini_panel_shell_integration_workflow_smoke.html` 校验外部 shell workflow 能读取 snapshot,
|
||||
并确认 snapshot display status 为 `Ready`;
|
||||
- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖:
|
||||
- ready snapshot 完整 shape;
|
||||
- default snapshot 包含 5 个 display rows;
|
||||
- `verify_ini_panel_ui_shell.mjs` 覆盖 shell view-model 的 snapshot 聚合关系;
|
||||
- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_entry_docs.mjs` 与
|
||||
`docs/panel-entry.md` 同步记录和校验新 helper/API;
|
||||
- 未新增控制按钮;
|
||||
- 未解析 G-code;
|
||||
- 未解释 canonical events;
|
||||
- 未新增 JS CNC 语义;
|
||||
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
|
||||
LinuxCNC-owned runtime semantics。
|
||||
|
||||
验证已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 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_shell_integration_manifest_node_smoke=ok
|
||||
ini_panel_launch_api_manifest_node_smoke=ok
|
||||
ini_panel_ui_shell_node_smoke=ok
|
||||
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
|
||||
browser_ini_shell_integration_workflow_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
|
||||
```
|
||||
|
||||
下一步建议:
|
||||
|
||||
继续推进 browser/UI workflow。下一批建议在 launch 页面或等价外部 shell view 中增加一个只读
|
||||
snapshot consumer helper,把 snapshot 直接压成 launch-side render state,并对 blocked snapshot
|
||||
做 focused browser smoke;仍保持只读,不新增控制按钮,不解析 G-code。
|
||||
@@ -21,7 +21,11 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummarySchema,
|
||||
createIniPanelShellViewModel,
|
||||
getIniPanelEntryByHref,
|
||||
getVisibleIniPanelEntries,
|
||||
@@ -37,6 +41,7 @@ import {
|
||||
isSupportedIniPanelControlPageApiManifest,
|
||||
isSupportedIniPanelLaunchApiManifest,
|
||||
isSupportedIniPanelShellIntegrationManifest,
|
||||
isSupportedIniPanelShellSessionHandoffSummary,
|
||||
} from "../runtime/ui/ini-panel/ui-shell.js";
|
||||
```
|
||||
|
||||
@@ -135,6 +140,25 @@ read-only display summary of readiness, target page, persistence capabilities,
|
||||
readonly status fields, handoff methods, and blocking reasons. Browser shells
|
||||
can read the same summary through
|
||||
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSummary()`.
|
||||
Use `createIniPanelShellSessionHandoffSummarySchema()` or
|
||||
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSummarySchema()` for the
|
||||
versioned summary shape, and `isSupportedIniPanelShellSessionHandoffSummary()`
|
||||
or `linuxCncIniPanelLaunchApi.isSupportedShellSessionHandoffSummary()` before
|
||||
consuming a summary from a browser shell.
|
||||
Use `createIniPanelShellSessionHandoffCompatibilityReport()` or
|
||||
`linuxCncIniPanelLaunchApi.getShellSessionHandoffCompatibilityReport()` when an
|
||||
outer shell needs display-ready diagnostics for schema support, missing fields,
|
||||
api/version mismatches, and current blocking reasons before consuming the
|
||||
handoff summary.
|
||||
Use `createIniPanelShellSessionHandoffDisplayViewModel()` or
|
||||
`linuxCncIniPanelLaunchApi.getShellSessionHandoffDisplayViewModel()` when an
|
||||
outer shell needs the same diagnostics as stable read-only label/value rows for
|
||||
DOM display. The launch page renders those rows in `[data-handoff-status]` and
|
||||
`[data-handoff-rows]` without adding control actions.
|
||||
Use `createIniPanelShellSessionHandoffSnapshot()` or
|
||||
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSnapshot()` when an outer shell
|
||||
needs one read-only API read that includes readiness, handoff summary,
|
||||
compatibility report, and display view-model together.
|
||||
The browser workflow smoke
|
||||
`tests/browser/ini_panel_shell_integration_workflow_smoke.html` verifies the
|
||||
same external shell handoff: read integration manifest, pass readiness gate,
|
||||
|
||||
@@ -46,6 +46,27 @@
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
.handoff-status {
|
||||
border-top: 1px solid var(--border);
|
||||
padding-top: 12px;
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
.handoff-status dl {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(120px, 180px) 1fr;
|
||||
gap: 6px 12px;
|
||||
font: 13px/1.4 "Segoe UI", "Noto Sans", sans-serif;
|
||||
}
|
||||
.handoff-status dt {
|
||||
color: var(--muted);
|
||||
}
|
||||
.handoff-status dd {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
@@ -70,6 +91,10 @@
|
||||
<a data-entry-id="edit-run" href="./index.html">Open edit and run panel</a>
|
||||
<a data-entry-id="control-view" href="./control-page.html">Open read-only control view</a>
|
||||
</div>
|
||||
<section class="handoff-status" aria-label="Shell handoff compatibility">
|
||||
<p data-handoff-status>Checking shell handoff compatibility.</p>
|
||||
<dl data-handoff-rows></dl>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
<script type="module">
|
||||
@@ -89,6 +114,18 @@
|
||||
link.textContent = linkModel.label;
|
||||
link.href = linkModel.href;
|
||||
}
|
||||
const handoffDisplay = shellViewModel.shellSessionHandoffDisplayViewModel;
|
||||
document.querySelector("[data-handoff-status]").textContent = `${handoffDisplay.statusText}: ${handoffDisplay.detailText}`;
|
||||
const handoffRows = document.querySelector("[data-handoff-rows]");
|
||||
for (const row of handoffDisplay.rows) {
|
||||
const term = document.createElement("dt");
|
||||
term.dataset.handoffRow = row.id;
|
||||
term.textContent = row.label;
|
||||
const detail = document.createElement("dd");
|
||||
detail.dataset.handoffValue = row.id;
|
||||
detail.textContent = row.value;
|
||||
handoffRows.append(term, detail);
|
||||
}
|
||||
|
||||
window.linuxCncIniPanelLaunchApi = {
|
||||
isSupportedLaunchApiManifest: isSupportedIniPanelLaunchApiManifest,
|
||||
@@ -97,7 +134,12 @@
|
||||
getShellIntegrationSchema: () => shellViewModel.shellIntegrationSchema,
|
||||
getShellIntegrationManifest: () => shellViewModel.shellIntegrationManifest,
|
||||
getShellIntegrationReadiness: () => shellViewModel.shellIntegrationReadiness,
|
||||
getShellSessionHandoffSummarySchema: () => shellViewModel.shellSessionHandoffSummarySchema,
|
||||
getShellSessionHandoffSummary: () => shellViewModel.shellSessionHandoffSummary,
|
||||
isSupportedShellSessionHandoffSummary: shellViewModel.isSupportedShellSessionHandoffSummary,
|
||||
getShellSessionHandoffCompatibilityReport: () => shellViewModel.shellSessionHandoffCompatibilityReport,
|
||||
getShellSessionHandoffDisplayViewModel: () => shellViewModel.shellSessionHandoffDisplayViewModel,
|
||||
getShellSessionHandoffSnapshot: () => shellViewModel.shellSessionHandoffSnapshot,
|
||||
getLauncherLinks: () => shellViewModel.launcherLinks,
|
||||
getControlPageApiMethods: () => shellViewModel.controlPage.browserApiMethods,
|
||||
};
|
||||
|
||||
@@ -126,7 +126,12 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr
|
||||
"getShellIntegrationSchema",
|
||||
"getShellIntegrationManifest",
|
||||
"getShellIntegrationReadiness",
|
||||
"getShellSessionHandoffSummarySchema",
|
||||
"getShellSessionHandoffSummary",
|
||||
"isSupportedShellSessionHandoffSummary",
|
||||
"getShellSessionHandoffCompatibilityReport",
|
||||
"getShellSessionHandoffDisplayViewModel",
|
||||
"getShellSessionHandoffSnapshot",
|
||||
"getLauncherLinks",
|
||||
"getControlPageApiMethods",
|
||||
],
|
||||
@@ -381,11 +386,44 @@ export function createIniPanelShellIntegrationWorkflowPlan({
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffSummarySchema() {
|
||||
return {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 1,
|
||||
fields: [
|
||||
"apiName",
|
||||
"summaryVersion",
|
||||
"phase",
|
||||
"ready",
|
||||
"targetPage",
|
||||
"readiness",
|
||||
"persistenceCapabilities",
|
||||
"readonlyStatusFields",
|
||||
"handoffMethods",
|
||||
"blockingReasons",
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function isSupportedIniPanelShellSessionHandoffSummary(
|
||||
summary,
|
||||
schema = createIniPanelShellSessionHandoffSummarySchema(),
|
||||
) {
|
||||
if (!summary || typeof summary !== "object") {
|
||||
return false;
|
||||
}
|
||||
if (summary.apiName !== schema.apiName || summary.summaryVersion !== schema.summaryVersion) {
|
||||
return false;
|
||||
}
|
||||
return schema.fields.every((fieldName) => Object.hasOwn(summary, fieldName));
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffSummary({
|
||||
manifest = createIniPanelShellIntegrationManifest(),
|
||||
readiness = createIniPanelShellIntegrationReadiness(manifest),
|
||||
workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness }),
|
||||
} = {}) {
|
||||
const schema = createIniPanelShellSessionHandoffSummarySchema();
|
||||
const persistenceCapabilities = Array.isArray(manifest?.persistenceCapabilities)
|
||||
? manifest.persistenceCapabilities.map(({ id, label, scope }) => ({ id, label, scope }))
|
||||
: [];
|
||||
@@ -393,6 +431,8 @@ export function createIniPanelShellSessionHandoffSummary({
|
||||
? [...workflowPlan.readonlyStatusHandoff.expectedStatusFields]
|
||||
: [];
|
||||
return {
|
||||
apiName: schema.apiName,
|
||||
summaryVersion: schema.summaryVersion,
|
||||
phase: workflowPlan.ready ? "ready" : "blocked",
|
||||
ready: Boolean(workflowPlan.ready),
|
||||
targetPage: workflowPlan.targetPage,
|
||||
@@ -412,6 +452,107 @@ export function createIniPanelShellSessionHandoffSummary({
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffCompatibilityReport(
|
||||
summary = createIniPanelShellSessionHandoffSummary(),
|
||||
schema = createIniPanelShellSessionHandoffSummarySchema(),
|
||||
) {
|
||||
const summaryObject = summary && typeof summary === "object" ? summary : {};
|
||||
const missingFields = schema.fields.filter((fieldName) => !Object.hasOwn(summaryObject, fieldName));
|
||||
const mismatchFields = [
|
||||
...(summaryObject.apiName === schema.apiName ? [] : ["apiName"]),
|
||||
...(summaryObject.summaryVersion === schema.summaryVersion ? [] : ["summaryVersion"]),
|
||||
];
|
||||
const summarySupported = missingFields.length === 0 && mismatchFields.length === 0;
|
||||
const blockingReasons = Array.isArray(summaryObject.blockingReasons)
|
||||
? [...summaryObject.blockingReasons]
|
||||
: [];
|
||||
const handoffReady = summarySupported && summaryObject.ready === true && blockingReasons.length === 0;
|
||||
|
||||
return {
|
||||
apiName: "ini-panel-shell-session-handoff-compatibility-report",
|
||||
reportVersion: 1,
|
||||
phase: handoffReady ? "ready" : "blocked",
|
||||
compatible: handoffReady,
|
||||
summarySupported,
|
||||
handoffReady,
|
||||
schema: {
|
||||
apiName: schema.apiName,
|
||||
summaryVersion: schema.summaryVersion,
|
||||
fields: [...schema.fields],
|
||||
},
|
||||
summary: {
|
||||
apiName: summaryObject.apiName ?? null,
|
||||
summaryVersion: summaryObject.summaryVersion ?? null,
|
||||
phase: summaryObject.phase ?? null,
|
||||
ready: summaryObject.ready ?? false,
|
||||
},
|
||||
missingFields,
|
||||
mismatchFields,
|
||||
blockingReasons,
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffDisplayViewModel(
|
||||
report = createIniPanelShellSessionHandoffCompatibilityReport(),
|
||||
) {
|
||||
const missingFields = Array.isArray(report?.missingFields) ? report.missingFields : [];
|
||||
const mismatchFields = Array.isArray(report?.mismatchFields) ? report.mismatchFields : [];
|
||||
const blockingReasons = Array.isArray(report?.blockingReasons) ? report.blockingReasons : [];
|
||||
const problems = [...missingFields, ...mismatchFields, ...blockingReasons];
|
||||
|
||||
return {
|
||||
phase: report?.phase === "ready" ? "ready" : "blocked",
|
||||
title: "Shell handoff compatibility",
|
||||
statusText: report?.compatible ? "Ready" : "Blocked",
|
||||
detailText: problems.length === 0 ? "No blocking reasons" : problems.join(", "),
|
||||
rows: [
|
||||
{
|
||||
id: "summary-supported",
|
||||
label: "Summary schema",
|
||||
value: report?.summarySupported ? "supported" : "blocked",
|
||||
},
|
||||
{
|
||||
id: "handoff-ready",
|
||||
label: "Handoff readiness",
|
||||
value: report?.handoffReady ? "ready" : "blocked",
|
||||
},
|
||||
{
|
||||
id: "missing-fields",
|
||||
label: "Missing fields",
|
||||
value: missingFields.length === 0 ? "none" : missingFields.join(", "),
|
||||
},
|
||||
{
|
||||
id: "mismatch-fields",
|
||||
label: "Mismatched fields",
|
||||
value: mismatchFields.length === 0 ? "none" : mismatchFields.join(", "),
|
||||
},
|
||||
{
|
||||
id: "blocking-reasons",
|
||||
label: "Blocking reasons",
|
||||
value: blockingReasons.length === 0 ? "none" : blockingReasons.join(", "),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffSnapshot({
|
||||
readiness = createIniPanelShellIntegrationReadiness(),
|
||||
summary = createIniPanelShellSessionHandoffSummary(),
|
||||
compatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(summary),
|
||||
displayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(compatibilityReport),
|
||||
} = {}) {
|
||||
return {
|
||||
apiName: "ini-panel-shell-session-handoff-snapshot",
|
||||
snapshotVersion: 1,
|
||||
phase: compatibilityReport.phase,
|
||||
ready: Boolean(compatibilityReport.compatible),
|
||||
readiness,
|
||||
summary,
|
||||
compatibilityReport,
|
||||
displayViewModel,
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) {
|
||||
const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries);
|
||||
const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest);
|
||||
@@ -419,6 +560,23 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
|
||||
manifest: shellIntegrationManifest,
|
||||
readiness: shellIntegrationReadiness,
|
||||
});
|
||||
const shellSessionHandoffSummary = createIniPanelShellSessionHandoffSummary({
|
||||
manifest: shellIntegrationManifest,
|
||||
readiness: shellIntegrationReadiness,
|
||||
workflowPlan: shellIntegrationWorkflowPlan,
|
||||
});
|
||||
const shellSessionHandoffCompatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(
|
||||
shellSessionHandoffSummary,
|
||||
);
|
||||
const shellSessionHandoffDisplayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(
|
||||
shellSessionHandoffCompatibilityReport,
|
||||
);
|
||||
const shellSessionHandoffSnapshot = createIniPanelShellSessionHandoffSnapshot({
|
||||
readiness: shellIntegrationReadiness,
|
||||
summary: shellSessionHandoffSummary,
|
||||
compatibilityReport: shellSessionHandoffCompatibilityReport,
|
||||
displayViewModel: shellSessionHandoffDisplayViewModel,
|
||||
});
|
||||
return {
|
||||
pages: entries.map(({ id, href, title }) => ({
|
||||
id,
|
||||
@@ -430,17 +588,22 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
|
||||
shellIntegrationManifest,
|
||||
shellIntegrationReadiness,
|
||||
shellIntegrationWorkflowPlan,
|
||||
shellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary({
|
||||
manifest: shellIntegrationManifest,
|
||||
readiness: shellIntegrationReadiness,
|
||||
workflowPlan: shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
shellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema(),
|
||||
shellSessionHandoffSummary,
|
||||
shellSessionHandoffCompatibilityReport,
|
||||
shellSessionHandoffDisplayViewModel,
|
||||
shellSessionHandoffSnapshot,
|
||||
launchApiSchema: createIniPanelLaunchApiSchema(),
|
||||
launchApiManifest: createIniPanelLaunchApiManifest(entries),
|
||||
isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest,
|
||||
createShellIntegrationReadiness: createIniPanelShellIntegrationReadiness,
|
||||
createShellIntegrationWorkflowPlan: createIniPanelShellIntegrationWorkflowPlan,
|
||||
isSupportedShellSessionHandoffSummary: isSupportedIniPanelShellSessionHandoffSummary,
|
||||
createShellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema,
|
||||
createShellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary,
|
||||
createShellSessionHandoffCompatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
createShellSessionHandoffDisplayViewModel: createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
createShellSessionHandoffSnapshot: createIniPanelShellSessionHandoffSnapshot,
|
||||
controlPage: {
|
||||
browserApiSchema: createControlPageBrowserApiSchema(),
|
||||
browserApiManifest: createControlPageBrowserApiManifest(),
|
||||
|
||||
@@ -73,7 +73,12 @@
|
||||
!launchApi?.getShellIntegrationSchema ||
|
||||
!launchApi?.getShellIntegrationManifest ||
|
||||
!launchApi?.getShellIntegrationReadiness ||
|
||||
!launchApi?.getShellSessionHandoffSummarySchema ||
|
||||
!launchApi?.getShellSessionHandoffSummary ||
|
||||
!launchApi?.isSupportedShellSessionHandoffSummary ||
|
||||
!launchApi?.getShellSessionHandoffCompatibilityReport ||
|
||||
!launchApi?.getShellSessionHandoffDisplayViewModel ||
|
||||
!launchApi?.getShellSessionHandoffSnapshot ||
|
||||
!launchApi?.getLauncherLinks ||
|
||||
!launchApi?.getControlPageApiMethods
|
||||
) {
|
||||
@@ -113,13 +118,17 @@
|
||||
);
|
||||
assertEqual(
|
||||
launchApiManifest.methods.join(","),
|
||||
"isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummary,getLauncherLinks,getControlPageApiMethods",
|
||||
"isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getLauncherLinks,getControlPageApiMethods",
|
||||
"launch API manifest methods",
|
||||
);
|
||||
const shellIntegrationSchema = launchApi.getShellIntegrationSchema();
|
||||
const shellIntegrationManifest = launchApi.getShellIntegrationManifest();
|
||||
const shellIntegrationReadiness = launchApi.getShellIntegrationReadiness();
|
||||
const shellSessionHandoffSummarySchema = launchApi.getShellSessionHandoffSummarySchema();
|
||||
const shellSessionHandoffSummary = launchApi.getShellSessionHandoffSummary();
|
||||
const shellSessionHandoffCompatibilityReport = launchApi.getShellSessionHandoffCompatibilityReport();
|
||||
const shellSessionHandoffDisplayViewModel = launchApi.getShellSessionHandoffDisplayViewModel();
|
||||
const shellSessionHandoffSnapshot = launchApi.getShellSessionHandoffSnapshot();
|
||||
assertEqual(
|
||||
shellIntegrationSchema.manifestVersion,
|
||||
1,
|
||||
@@ -165,6 +174,86 @@
|
||||
true,
|
||||
"shell session handoff summary readiness",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffSummarySchema.summaryVersion,
|
||||
1,
|
||||
"shell session handoff summary schema version",
|
||||
);
|
||||
assertEqual(
|
||||
launchApi.isSupportedShellSessionHandoffSummary(shellSessionHandoffSummary),
|
||||
true,
|
||||
"shell session handoff summary supported",
|
||||
);
|
||||
assertEqual(
|
||||
launchApi.isSupportedShellSessionHandoffSummary({ ...shellSessionHandoffSummary, summaryVersion: 2 }),
|
||||
false,
|
||||
"shell session handoff summary rejects version",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffCompatibilityReport.compatible,
|
||||
true,
|
||||
"shell session handoff compatibility report",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffCompatibilityReport.summarySupported,
|
||||
true,
|
||||
"shell session handoff summary support report",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffCompatibilityReport.missingFields.join(","),
|
||||
"",
|
||||
"shell session handoff compatibility missing fields",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffDisplayViewModel.statusText,
|
||||
"Ready",
|
||||
"shell session handoff display status",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffDisplayViewModel.rows.length,
|
||||
5,
|
||||
"shell session handoff display rows",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffSnapshot.snapshotVersion,
|
||||
1,
|
||||
"shell session handoff snapshot version",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffSnapshot.ready,
|
||||
true,
|
||||
"shell session handoff snapshot readiness",
|
||||
);
|
||||
assertEqual(
|
||||
JSON.stringify(shellSessionHandoffSnapshot.readiness),
|
||||
JSON.stringify(shellIntegrationReadiness),
|
||||
"shell session handoff snapshot readiness object",
|
||||
);
|
||||
assertEqual(
|
||||
JSON.stringify(shellSessionHandoffSnapshot.summary),
|
||||
JSON.stringify(shellSessionHandoffSummary),
|
||||
"shell session handoff snapshot summary object",
|
||||
);
|
||||
assertEqual(
|
||||
JSON.stringify(shellSessionHandoffSnapshot.displayViewModel),
|
||||
JSON.stringify(shellSessionHandoffDisplayViewModel),
|
||||
"shell session handoff snapshot display object",
|
||||
);
|
||||
assertEqual(
|
||||
launchDoc.querySelector("[data-handoff-status]").textContent,
|
||||
"Ready: No blocking reasons",
|
||||
"shell session handoff DOM status",
|
||||
);
|
||||
assertEqual(
|
||||
launchDoc.querySelector('[data-handoff-value="missing-fields"]').textContent,
|
||||
"none",
|
||||
"shell session handoff DOM missing fields",
|
||||
);
|
||||
assertEqual(
|
||||
launchDoc.querySelector('[data-handoff-value="blocking-reasons"]').textContent,
|
||||
"none",
|
||||
"shell session handoff DOM blocking reasons",
|
||||
);
|
||||
assertEqual(
|
||||
shellSessionHandoffSummary.targetPage.href,
|
||||
"./control-page.html",
|
||||
|
||||
@@ -64,14 +64,36 @@ TOOL_TABLE = browser-shell-tool.tbl
|
||||
if (
|
||||
!launchApi?.getShellIntegrationManifest ||
|
||||
!launchApi?.getShellIntegrationReadiness ||
|
||||
!launchApi?.getShellSessionHandoffSummary
|
||||
!launchApi?.getShellSessionHandoffSummarySchema ||
|
||||
!launchApi?.getShellSessionHandoffSummary ||
|
||||
!launchApi?.isSupportedShellSessionHandoffSummary ||
|
||||
!launchApi?.getShellSessionHandoffCompatibilityReport ||
|
||||
!launchApi?.getShellSessionHandoffDisplayViewModel ||
|
||||
!launchApi?.getShellSessionHandoffSnapshot
|
||||
) {
|
||||
throw new Error("launch API namespace did not expose shell integration helpers");
|
||||
}
|
||||
|
||||
const integrationManifest = launchApi.getShellIntegrationManifest();
|
||||
const readiness = launchApi.getShellIntegrationReadiness();
|
||||
const handoffSummarySchema = launchApi.getShellSessionHandoffSummarySchema();
|
||||
const handoffSummary = launchApi.getShellSessionHandoffSummary();
|
||||
const compatibilityReport = launchApi.getShellSessionHandoffCompatibilityReport();
|
||||
const handoffDisplay = launchApi.getShellSessionHandoffDisplayViewModel();
|
||||
const handoffSnapshot = launchApi.getShellSessionHandoffSnapshot();
|
||||
assertEqual(handoffSummarySchema.summaryVersion, 1, "shell handoff summary schema version");
|
||||
assertEqual(
|
||||
launchApi.isSupportedShellSessionHandoffSummary(handoffSummary),
|
||||
true,
|
||||
"shell handoff summary supported",
|
||||
);
|
||||
assertEqual(compatibilityReport.compatible, true, "shell handoff compatibility report");
|
||||
assertEqual(compatibilityReport.summarySupported, true, "shell handoff summary report support");
|
||||
assertEqual(compatibilityReport.blockingReasons.join(","), "", "shell handoff report blocking reasons");
|
||||
assertEqual(handoffDisplay.statusText, "Ready", "shell handoff display status");
|
||||
assertEqual(handoffDisplay.detailText, "No blocking reasons", "shell handoff display detail");
|
||||
assertEqual(handoffSnapshot.ready, true, "shell handoff snapshot readiness");
|
||||
assertEqual(handoffSnapshot.displayViewModel.statusText, "Ready", "shell handoff snapshot display status");
|
||||
assertEqual(readiness.phase, "ready", "shell integration readiness phase");
|
||||
assertEqual(readiness.ready, true, "shell integration readiness");
|
||||
assertEqual(readiness.missing.join(","), "", "shell integration readiness missing checks");
|
||||
|
||||
@@ -18,7 +18,11 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummarySchema,
|
||||
createIniPanelShellViewModel,
|
||||
createMachineSessionReadonlyStatus,
|
||||
createMachineSessionReadonlyStatusApiManifest,
|
||||
@@ -29,6 +33,7 @@ import {
|
||||
isSupportedIniPanelControlPageApiManifest,
|
||||
isSupportedIniPanelLaunchApiManifest,
|
||||
isSupportedIniPanelShellIntegrationManifest,
|
||||
isSupportedIniPanelShellSessionHandoffSummary,
|
||||
} from "../../../runtime/ui/ini-panel/ui-shell.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
@@ -66,13 +71,18 @@ const requiredShellExports = [
|
||||
"createIniPanelShellIntegrationReadiness",
|
||||
"createIniPanelShellIntegrationSchema",
|
||||
"createIniPanelShellIntegrationWorkflowPlan",
|
||||
"createIniPanelShellSessionHandoffCompatibilityReport",
|
||||
"createIniPanelShellSessionHandoffDisplayViewModel",
|
||||
"createIniPanelShellSessionHandoffSnapshot",
|
||||
"createIniPanelShellSessionHandoffSummary",
|
||||
"createIniPanelShellSessionHandoffSummarySchema",
|
||||
"createIniPanelShellViewModel",
|
||||
"getIniPanelEntryByHref",
|
||||
"getVisibleIniPanelEntries",
|
||||
"isSupportedIniPanelControlPageApiManifest",
|
||||
"isSupportedIniPanelLaunchApiManifest",
|
||||
"isSupportedIniPanelShellIntegrationManifest",
|
||||
"isSupportedIniPanelShellSessionHandoffSummary",
|
||||
"createMachineSessionControlPageController",
|
||||
"createMachineSessionReadonlyStatus",
|
||||
"createMachineSessionReadonlyStatusApiManifest",
|
||||
@@ -152,6 +162,28 @@ assert.deepEqual(
|
||||
workflowPlan: createIniPanelShellViewModel().shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellViewModel().shellSessionHandoffSummarySchema,
|
||||
createIniPanelShellSessionHandoffSummarySchema(),
|
||||
);
|
||||
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(createIniPanelShellViewModel().shellSessionHandoffSummary), true);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellViewModel().shellSessionHandoffSummary),
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellViewModel().shellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel(createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport),
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellViewModel().shellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSnapshot({
|
||||
readiness: createIniPanelShellViewModel().shellIntegrationReadiness,
|
||||
summary: createIniPanelShellViewModel().shellSessionHandoffSummary,
|
||||
compatibilityReport: createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport,
|
||||
displayViewModel: createIniPanelShellViewModel().shellSessionHandoffDisplayViewModel,
|
||||
}),
|
||||
);
|
||||
assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true);
|
||||
assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema());
|
||||
assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, createIniPanelLaunchApiManifest());
|
||||
@@ -206,10 +238,15 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationSchema\
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSnapshot\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelControlPageApiManifest\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelLaunchApiManifest\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(controlPageText, /\bisSupportedControlPageApiManifest\b/);
|
||||
assert.match(controlPageText, /\bgetControlPageApiSchema\b/);
|
||||
assert.match(controlPageText, /\bgetControlPageApiManifest\b/);
|
||||
@@ -221,7 +258,14 @@ assert.match(launchText, /\bgetLaunchApiManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSummary\b/);
|
||||
assert.match(launchText, /\bisSupportedShellSessionHandoffSummary\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/);
|
||||
assert.match(launchText, /\bdata-handoff-status\b/);
|
||||
assert.match(launchText, /\bdata-handoff-rows\b/);
|
||||
assert.match(launchText, /\bgetControlPageApiMethods\b/);
|
||||
assert.match(controlPageText, /\bgetControlPageContract\b/);
|
||||
assert.match(controlPageText, /\breadControlPageStatus\b/);
|
||||
@@ -240,22 +284,38 @@ assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationSchema\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelControlPageApiManifest\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelLaunchApiManifest\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedLaunchApiManifest\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getLaunchApiSchema\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getLaunchApiManifest\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationSchema\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSnapshot\b/);
|
||||
assert.match(docText, /\bdata-handoff-status\b/);
|
||||
assert.match(docText, /\bdata-handoff-rows\b/);
|
||||
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getControlPageApiMethods\b/);
|
||||
assert.match(docText, /\bini_panel_shell_integration_workflow_smoke\.html\b/);
|
||||
assert.match(browserIniPanelText, /\bini_panel_shell_integration_workflow_smoke\.html\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellIntegrationReadiness\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSummary\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bisSupportedShellSessionHandoffSummary\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSnapshot\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bhandoffSummary\.handoffMethods\.readStatus\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\breadControlPageStatus\b/);
|
||||
assert.match(shellIntegrationWorkflowSmokeText, /\bbrowser_ini_shell_integration_workflow_smoke=ok\b/);
|
||||
|
||||
@@ -46,7 +46,12 @@ assert.deepEqual(manifest, {
|
||||
"getShellIntegrationSchema",
|
||||
"getShellIntegrationManifest",
|
||||
"getShellIntegrationReadiness",
|
||||
"getShellSessionHandoffSummarySchema",
|
||||
"getShellSessionHandoffSummary",
|
||||
"isSupportedShellSessionHandoffSummary",
|
||||
"getShellSessionHandoffCompatibilityReport",
|
||||
"getShellSessionHandoffDisplayViewModel",
|
||||
"getShellSessionHandoffSnapshot",
|
||||
"getLauncherLinks",
|
||||
"getControlPageApiMethods",
|
||||
],
|
||||
@@ -147,7 +152,12 @@ assert.match(launchText, /\bgetLaunchApiManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSummary\b/);
|
||||
assert.match(launchText, /\bisSupportedShellSessionHandoffSummary\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/);
|
||||
assert.match(launchText, /\blinuxCncIniPanelLaunchApi\b/);
|
||||
|
||||
console.log("ini_panel_launch_api_manifest_node_smoke=ok");
|
||||
|
||||
@@ -14,9 +14,14 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummarySchema,
|
||||
getVisibleIniPanelEntries,
|
||||
isSupportedIniPanelShellIntegrationManifest,
|
||||
isSupportedIniPanelShellSessionHandoffSummary,
|
||||
} from "../../../runtime/ui/ini-panel/ui-shell.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
@@ -30,6 +35,15 @@ const manifest = createIniPanelShellIntegrationManifest();
|
||||
const readiness = createIniPanelShellIntegrationReadiness(manifest);
|
||||
const workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness });
|
||||
const handoffSummary = createIniPanelShellSessionHandoffSummary({ manifest, readiness, workflowPlan });
|
||||
const handoffSummarySchema = createIniPanelShellSessionHandoffSummarySchema();
|
||||
const handoffCompatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(handoffSummary);
|
||||
const handoffDisplayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(handoffCompatibilityReport);
|
||||
const handoffSnapshot = createIniPanelShellSessionHandoffSnapshot({
|
||||
readiness,
|
||||
summary: handoffSummary,
|
||||
compatibilityReport: handoffCompatibilityReport,
|
||||
displayViewModel: handoffDisplayViewModel,
|
||||
});
|
||||
|
||||
assert.deepEqual(schema, {
|
||||
apiName: "ini-panel-shell-integration",
|
||||
@@ -85,7 +99,7 @@ assert.deepEqual(readiness, {
|
||||
counts: {
|
||||
pages: 2,
|
||||
launcherLinks: 2,
|
||||
launchMethods: 9,
|
||||
launchMethods: 14,
|
||||
controlPageMethods: 11,
|
||||
persistenceCapabilities: 3,
|
||||
},
|
||||
@@ -133,6 +147,8 @@ assert.deepEqual(workflowPlan, {
|
||||
},
|
||||
});
|
||||
assert.deepEqual(handoffSummary, {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 1,
|
||||
phase: "ready",
|
||||
ready: true,
|
||||
targetPage: {
|
||||
@@ -145,7 +161,7 @@ assert.deepEqual(handoffSummary, {
|
||||
counts: {
|
||||
pages: 2,
|
||||
launcherLinks: 2,
|
||||
launchMethods: 9,
|
||||
launchMethods: 14,
|
||||
controlPageMethods: 11,
|
||||
persistenceCapabilities: 3,
|
||||
},
|
||||
@@ -189,6 +205,149 @@ assert.deepEqual(handoffSummary, {
|
||||
},
|
||||
blockingReasons: [],
|
||||
});
|
||||
assert.deepEqual(handoffSummarySchema, {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 1,
|
||||
fields: [
|
||||
"apiName",
|
||||
"summaryVersion",
|
||||
"phase",
|
||||
"ready",
|
||||
"targetPage",
|
||||
"readiness",
|
||||
"persistenceCapabilities",
|
||||
"readonlyStatusFields",
|
||||
"handoffMethods",
|
||||
"blockingReasons",
|
||||
],
|
||||
});
|
||||
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(handoffSummary), true);
|
||||
assert.equal(
|
||||
isSupportedIniPanelShellSessionHandoffSummary({ ...handoffSummary, summaryVersion: 2 }),
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
isSupportedIniPanelShellSessionHandoffSummary({ ...handoffSummary, apiName: "other" }),
|
||||
false,
|
||||
);
|
||||
const missingSummaryField = { ...handoffSummary };
|
||||
delete missingSummaryField.readonlyStatusFields;
|
||||
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(missingSummaryField), false);
|
||||
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(null), false);
|
||||
assert.deepEqual(handoffCompatibilityReport, {
|
||||
apiName: "ini-panel-shell-session-handoff-compatibility-report",
|
||||
reportVersion: 1,
|
||||
phase: "ready",
|
||||
compatible: true,
|
||||
summarySupported: true,
|
||||
handoffReady: true,
|
||||
schema: {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 1,
|
||||
fields: [
|
||||
"apiName",
|
||||
"summaryVersion",
|
||||
"phase",
|
||||
"ready",
|
||||
"targetPage",
|
||||
"readiness",
|
||||
"persistenceCapabilities",
|
||||
"readonlyStatusFields",
|
||||
"handoffMethods",
|
||||
"blockingReasons",
|
||||
],
|
||||
},
|
||||
summary: {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 1,
|
||||
phase: "ready",
|
||||
ready: true,
|
||||
},
|
||||
missingFields: [],
|
||||
mismatchFields: [],
|
||||
blockingReasons: [],
|
||||
});
|
||||
assert.deepEqual(handoffDisplayViewModel, {
|
||||
phase: "ready",
|
||||
title: "Shell handoff compatibility",
|
||||
statusText: "Ready",
|
||||
detailText: "No blocking reasons",
|
||||
rows: [
|
||||
{
|
||||
id: "summary-supported",
|
||||
label: "Summary schema",
|
||||
value: "supported",
|
||||
},
|
||||
{
|
||||
id: "handoff-ready",
|
||||
label: "Handoff readiness",
|
||||
value: "ready",
|
||||
},
|
||||
{
|
||||
id: "missing-fields",
|
||||
label: "Missing fields",
|
||||
value: "none",
|
||||
},
|
||||
{
|
||||
id: "mismatch-fields",
|
||||
label: "Mismatched fields",
|
||||
value: "none",
|
||||
},
|
||||
{
|
||||
id: "blocking-reasons",
|
||||
label: "Blocking reasons",
|
||||
value: "none",
|
||||
},
|
||||
],
|
||||
});
|
||||
assert.deepEqual(handoffSnapshot, {
|
||||
apiName: "ini-panel-shell-session-handoff-snapshot",
|
||||
snapshotVersion: 1,
|
||||
phase: "ready",
|
||||
ready: true,
|
||||
readiness,
|
||||
summary: handoffSummary,
|
||||
compatibilityReport: handoffCompatibilityReport,
|
||||
displayViewModel: handoffDisplayViewModel,
|
||||
});
|
||||
assert.equal(createIniPanelShellSessionHandoffSnapshot().displayViewModel.rows.length, 5);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffDisplayViewModel(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }),
|
||||
).rows.find((row) => row.id === "mismatch-fields"),
|
||||
{
|
||||
id: "mismatch-fields",
|
||||
label: "Mismatched fields",
|
||||
value: "summaryVersion",
|
||||
},
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }),
|
||||
{
|
||||
...handoffCompatibilityReport,
|
||||
phase: "blocked",
|
||||
compatible: false,
|
||||
summarySupported: false,
|
||||
handoffReady: false,
|
||||
summary: {
|
||||
apiName: "ini-panel-shell-session-handoff-summary",
|
||||
summaryVersion: 2,
|
||||
phase: "ready",
|
||||
ready: true,
|
||||
},
|
||||
mismatchFields: ["summaryVersion"],
|
||||
},
|
||||
);
|
||||
const missingFieldReportInput = { ...handoffSummary };
|
||||
delete missingFieldReportInput.readonlyStatusFields;
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(missingFieldReportInput).missingFields,
|
||||
["readonlyStatusFields"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(null).missingFields,
|
||||
handoffSummarySchema.fields,
|
||||
);
|
||||
const blockedManifest = {
|
||||
...createIniPanelShellIntegrationManifest(),
|
||||
compatibility: {
|
||||
@@ -210,7 +369,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), {
|
||||
counts: {
|
||||
pages: 2,
|
||||
launcherLinks: 2,
|
||||
launchMethods: 9,
|
||||
launchMethods: 14,
|
||||
controlPageMethods: 11,
|
||||
persistenceCapabilities: 3,
|
||||
},
|
||||
@@ -239,6 +398,22 @@ assert.deepEqual(
|
||||
}).blockingReasons,
|
||||
["launchCompatibility"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellSessionHandoffSummary({
|
||||
manifest: blockedManifest,
|
||||
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
|
||||
workflowPlan: blockedWorkflowPlan,
|
||||
})).blockingReasons,
|
||||
["launchCompatibility"],
|
||||
);
|
||||
assert.equal(
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellSessionHandoffSummary({
|
||||
manifest: blockedManifest,
|
||||
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
|
||||
workflowPlan: blockedWorkflowPlan,
|
||||
})).compatible,
|
||||
false,
|
||||
);
|
||||
const missingTargetPlan = createIniPanelShellIntegrationWorkflowPlan({
|
||||
manifest,
|
||||
controlEntryId: "missing-entry",
|
||||
@@ -337,7 +512,12 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationSchema\
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSnapshot\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
|
||||
@@ -345,7 +525,12 @@ assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.doesNotMatch(shellText, /\bparseGcode\b|\bcanonicalEvents\b|\btoolTable\b|\bplanner\b/);
|
||||
|
||||
|
||||
@@ -14,7 +14,11 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummarySchema,
|
||||
createIniPanelShellViewModel,
|
||||
createMachineSessionReadonlyStatus,
|
||||
createMachineSessionReadonlyStatusApiManifest,
|
||||
@@ -27,6 +31,7 @@ import {
|
||||
isSupportedIniPanelControlPageApiManifest,
|
||||
isSupportedIniPanelLaunchApiManifest,
|
||||
isSupportedIniPanelShellIntegrationManifest,
|
||||
isSupportedIniPanelShellSessionHandoffSummary,
|
||||
loadMachineSessionForControlPageWorkflow,
|
||||
readMachineSessionReadonlyStatus,
|
||||
refreshMachineSessionControlPage,
|
||||
@@ -67,7 +72,11 @@ assert.equal(typeof createIniPanelShellIntegrationManifest, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationReadiness, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationSchema, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationWorkflowPlan, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffCompatibilityReport, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffDisplayViewModel, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffSnapshot, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffSummary, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffSummarySchema, "function");
|
||||
assert.equal(typeof loadMachineSessionForControlPageWorkflow, "function");
|
||||
assert.equal(typeof readMachineSessionReadonlyStatus, "function");
|
||||
assert.equal(typeof refreshMachineSessionControlPage, "function");
|
||||
@@ -75,6 +84,7 @@ assert.equal(typeof renderMachineSessionControlView, "function");
|
||||
assert.equal(typeof isSupportedIniPanelControlPageApiManifest, "function");
|
||||
assert.equal(typeof isSupportedIniPanelLaunchApiManifest, "function");
|
||||
assert.equal(typeof isSupportedIniPanelShellIntegrationManifest, "function");
|
||||
assert.equal(typeof isSupportedIniPanelShellSessionHandoffSummary, "function");
|
||||
|
||||
const shellManifest = getIniPanelEntryManifest();
|
||||
shellManifest[0].title = "changed";
|
||||
@@ -132,6 +142,58 @@ assert.deepEqual(
|
||||
workflowPlan: shellViewModel.shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(shellViewModel.shellSessionHandoffSummarySchema, createIniPanelShellSessionHandoffSummarySchema());
|
||||
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(shellViewModel.shellSessionHandoffSummary), true);
|
||||
assert.deepEqual(
|
||||
shellViewModel.shellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport(shellViewModel.shellSessionHandoffSummary),
|
||||
);
|
||||
assert.deepEqual(
|
||||
shellViewModel.shellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel(shellViewModel.shellSessionHandoffCompatibilityReport),
|
||||
);
|
||||
assert.deepEqual(
|
||||
shellViewModel.shellSessionHandoffSnapshot,
|
||||
createIniPanelShellSessionHandoffSnapshot({
|
||||
readiness: shellViewModel.shellIntegrationReadiness,
|
||||
summary: shellViewModel.shellSessionHandoffSummary,
|
||||
compatibilityReport: shellViewModel.shellSessionHandoffCompatibilityReport,
|
||||
displayViewModel: shellViewModel.shellSessionHandoffDisplayViewModel,
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(shellViewModel.shellSessionHandoffDisplayViewModel, {
|
||||
phase: "ready",
|
||||
title: "Shell handoff compatibility",
|
||||
statusText: "Ready",
|
||||
detailText: "No blocking reasons",
|
||||
rows: [
|
||||
{
|
||||
id: "summary-supported",
|
||||
label: "Summary schema",
|
||||
value: "supported",
|
||||
},
|
||||
{
|
||||
id: "handoff-ready",
|
||||
label: "Handoff readiness",
|
||||
value: "ready",
|
||||
},
|
||||
{
|
||||
id: "missing-fields",
|
||||
label: "Missing fields",
|
||||
value: "none",
|
||||
},
|
||||
{
|
||||
id: "mismatch-fields",
|
||||
label: "Mismatched fields",
|
||||
value: "none",
|
||||
},
|
||||
{
|
||||
id: "blocking-reasons",
|
||||
label: "Blocking reasons",
|
||||
value: "none",
|
||||
},
|
||||
],
|
||||
});
|
||||
assert.equal(
|
||||
isSupportedIniPanelShellIntegrationManifest(shellViewModel.shellIntegrationManifest),
|
||||
true,
|
||||
@@ -164,7 +226,18 @@ assert.equal(shellViewModel.controlPage.createController, createMachineSessionCo
|
||||
assert.equal(shellViewModel.isSupportedShellIntegrationManifest, isSupportedIniPanelShellIntegrationManifest);
|
||||
assert.equal(shellViewModel.createShellIntegrationReadiness, createIniPanelShellIntegrationReadiness);
|
||||
assert.equal(shellViewModel.createShellIntegrationWorkflowPlan, createIniPanelShellIntegrationWorkflowPlan);
|
||||
assert.equal(shellViewModel.isSupportedShellSessionHandoffSummary, isSupportedIniPanelShellSessionHandoffSummary);
|
||||
assert.equal(shellViewModel.createShellSessionHandoffSummarySchema, createIniPanelShellSessionHandoffSummarySchema);
|
||||
assert.equal(shellViewModel.createShellSessionHandoffSummary, createIniPanelShellSessionHandoffSummary);
|
||||
assert.equal(
|
||||
shellViewModel.createShellSessionHandoffCompatibilityReport,
|
||||
createIniPanelShellSessionHandoffCompatibilityReport,
|
||||
);
|
||||
assert.equal(
|
||||
shellViewModel.createShellSessionHandoffDisplayViewModel,
|
||||
createIniPanelShellSessionHandoffDisplayViewModel,
|
||||
);
|
||||
assert.equal(shellViewModel.createShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSnapshot);
|
||||
assert.deepEqual(shellViewModel.controlPage.contract, createIniPanelShellControlPageContract());
|
||||
assert.equal(shellViewModel.controlPage.isSupportedBrowserApiManifest, isSupportedIniPanelControlPageApiManifest);
|
||||
assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);
|
||||
|
||||
Reference in New Issue
Block a user