diff --git a/text13.txt b/text13.txt index 48971ce..efb486e 100644 --- a/text13.txt +++ b/text13.txt @@ -907,3 +907,103 @@ host_wasm_opfs_browser_smokes=ok `isSupportedIniPanelShellSessionHandoffPackage()`,为 package 增加 versioned schema 与 focused compatibility predicate,便于外部 shell 在消费 package 前做单点兼容性检查;仍保持只读,不新增 控制按钮,不解析 G-code。 + +八、2026-06-15 继续执行记录:INI panel shell handoff package schema gate + +本轮按“第一原则:加快实质性推进”继续推进 browser/UI workflow,为 shell handoff package +新增 versioned schema 与 focused compatibility predicate,让外部 shell 能在消费 package 前做 +单点 shape 兼容性检查。 + +完成内容: + +- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffPackageSchema()`; +- package schema 输出: + - `apiName: "ini-panel-shell-session-handoff-package"`; + - `packageVersion: 1`; + - `fields`; + - `manifestFields`; +- `ui-shell.js` 新增 `isSupportedIniPanelShellSessionHandoffPackage()`; +- predicate 检查: + - package 对象存在; + - `apiName` 匹配; + - `packageVersion` 匹配; + - package 顶层 required fields 存在; + - `manifests` 对象存在; + - manifest required fields 存在; +- `createIniPanelShellViewModel()` 新增: + - `shellSessionHandoffPackageSchema`; + - `createShellSessionHandoffPackageSchema`; + - `isSupportedShellSessionHandoffPackage`; +- `createIniPanelLaunchApiManifest().methods` 新增: + - `getShellSessionHandoffPackageSchema`; + - `isSupportedShellSessionHandoffPackage`; +- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增真实 browser 入口: + - `getShellSessionHandoffPackageSchema()`; + - `isSupportedShellSessionHandoffPackage()`; +- `ini_panel_launch_smoke.html` 校验真实 launch iframe: + - package schema version 为 1; + - 当前 package 可支持; + - 错误 package version 被拒绝; +- `ini_panel_shell_integration_workflow_smoke.html` 校验外部 shell workflow 能读取 + package schema,并用 predicate 确认 package 可支持; +- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖: + - package schema 完整 shape; + - valid package 支持; + - 错误 version、错误 apiName、缺 package 字段、缺 manifest 字段、null 被拒绝; +- `verify_ini_panel_ui_shell.mjs` 覆盖 shell view-model 的 package schema 和 predicate; +- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_entry_docs.mjs` 与 + `docs/panel-entry.md` 同步记录和校验新 helper/API; +- 未新增控制按钮; +- 未执行 action-plan; +- 未解析 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 与文档化可执行工作流。下一批建议新增一个只读 +`createIniPanelShellSessionHandoffPackageReport()` 或等价 helper,把 package schema support、 +missing package fields、missing manifest fields、version/apiName mismatch 和 checklist blocking +reasons 合并成 display-ready report,便于外部 shell 在拒绝 package 时显示原因;仍保持只读, +不新增控制按钮,不解析 G-code。 diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index 549445e..f234f33 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -26,6 +26,7 @@ import { createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffPackage, + createIniPanelShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffRenderState, createIniPanelShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSummary, @@ -45,6 +46,7 @@ import { isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, + isSupportedIniPanelShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffSummary, } from "../runtime/ui/ini-panel/ui-shell.js"; ``` @@ -185,6 +187,11 @@ Use `createIniPanelShellSessionHandoffPackage()` or needs one browser API read containing the launch/control method manifests, snapshot, render-state, action-plan, and checklist. The package is a read-only handoff artifact and does not execute action-plan steps. +Use `createIniPanelShellSessionHandoffPackageSchema()` or +`linuxCncIniPanelLaunchApi.getShellSessionHandoffPackageSchema()` for the +versioned package shape, and `isSupportedIniPanelShellSessionHandoffPackage()` +or `linuxCncIniPanelLaunchApi.isSupportedShellSessionHandoffPackage()` before +consuming a package from a browser shell. 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, diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index 05c0578..67b496b 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -146,7 +146,9 @@ getShellSessionHandoffRenderState: () => shellViewModel.shellSessionHandoffRenderState, getShellSessionHandoffActionPlan: () => shellViewModel.shellSessionHandoffActionPlan, getShellSessionHandoffChecklist: () => shellViewModel.shellSessionHandoffChecklist, + getShellSessionHandoffPackageSchema: () => shellViewModel.shellSessionHandoffPackageSchema, getShellSessionHandoffPackage: () => shellViewModel.shellSessionHandoffPackage, + isSupportedShellSessionHandoffPackage: shellViewModel.isSupportedShellSessionHandoffPackage, getLauncherLinks: () => shellViewModel.launcherLinks, getControlPageApiMethods: () => shellViewModel.controlPage.browserApiMethods, }; diff --git a/wasm-port/runtime/ui/ini-panel/ui-shell.js b/wasm-port/runtime/ui/ini-panel/ui-shell.js index 6aa0fb0..0d65bac 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -135,7 +135,9 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "getShellSessionHandoffRenderState", "getShellSessionHandoffActionPlan", "getShellSessionHandoffChecklist", + "getShellSessionHandoffPackageSchema", "getShellSessionHandoffPackage", + "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", ], @@ -745,6 +747,52 @@ export function createIniPanelShellSessionHandoffPackage({ }; } +export function createIniPanelShellSessionHandoffPackageSchema() { + return { + apiName: "ini-panel-shell-session-handoff-package", + packageVersion: 1, + fields: [ + "apiName", + "packageVersion", + "phase", + "ready", + "statusLine", + "manifests", + "snapshot", + "renderState", + "actionPlan", + "checklist", + ], + manifestFields: [ + "shellIntegration", + "launchApi", + "controlPageApi", + "launchMethods", + "controlPageMethods", + ], + }; +} + +export function isSupportedIniPanelShellSessionHandoffPackage( + handoffPackage, + schema = createIniPanelShellSessionHandoffPackageSchema(), +) { + if (!handoffPackage || typeof handoffPackage !== "object") { + return false; + } + if (handoffPackage.apiName !== schema.apiName || handoffPackage.packageVersion !== schema.packageVersion) { + return false; + } + if (!schema.fields.every((fieldName) => Object.hasOwn(handoffPackage, fieldName))) { + return false; + } + const manifests = handoffPackage.manifests; + if (!manifests || typeof manifests !== "object") { + return false; + } + return schema.manifestFields.every((fieldName) => Object.hasOwn(manifests, fieldName)); +} + export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries); const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest); @@ -809,6 +857,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries shellSessionHandoffActionPlan, shellSessionHandoffChecklist, shellSessionHandoffPackage, + shellSessionHandoffPackageSchema: createIniPanelShellSessionHandoffPackageSchema(), launchApiSchema: createIniPanelLaunchApiSchema(), launchApiManifest: createIniPanelLaunchApiManifest(entries), isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest, @@ -824,6 +873,8 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries createShellSessionHandoffActionPlan: createIniPanelShellSessionHandoffActionPlan, createShellSessionHandoffChecklist: createIniPanelShellSessionHandoffChecklist, createShellSessionHandoffPackage: createIniPanelShellSessionHandoffPackage, + createShellSessionHandoffPackageSchema: createIniPanelShellSessionHandoffPackageSchema, + isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), browserApiManifest: createControlPageBrowserApiManifest(), diff --git a/wasm-port/tests/browser/ini_panel_launch_smoke.html b/wasm-port/tests/browser/ini_panel_launch_smoke.html index fa6cd58..3aadec7 100644 --- a/wasm-port/tests/browser/ini_panel_launch_smoke.html +++ b/wasm-port/tests/browser/ini_panel_launch_smoke.html @@ -82,7 +82,9 @@ !launchApi?.getShellSessionHandoffRenderState || !launchApi?.getShellSessionHandoffActionPlan || !launchApi?.getShellSessionHandoffChecklist || + !launchApi?.getShellSessionHandoffPackageSchema || !launchApi?.getShellSessionHandoffPackage || + !launchApi?.isSupportedShellSessionHandoffPackage || !launchApi?.getLauncherLinks || !launchApi?.getControlPageApiMethods ) { @@ -122,7 +124,7 @@ ); assertEqual( launchApiManifest.methods.join(","), - "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getShellSessionHandoffChecklist,getShellSessionHandoffPackage,getLauncherLinks,getControlPageApiMethods", + "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getShellSessionHandoffChecklist,getShellSessionHandoffPackageSchema,getShellSessionHandoffPackage,isSupportedShellSessionHandoffPackage,getLauncherLinks,getControlPageApiMethods", "launch API manifest methods", ); const shellIntegrationSchema = launchApi.getShellIntegrationSchema(); @@ -136,6 +138,7 @@ const shellSessionHandoffRenderState = launchApi.getShellSessionHandoffRenderState(); const shellSessionHandoffActionPlan = launchApi.getShellSessionHandoffActionPlan(); const shellSessionHandoffChecklist = launchApi.getShellSessionHandoffChecklist(); + const shellSessionHandoffPackageSchema = launchApi.getShellSessionHandoffPackageSchema(); const shellSessionHandoffPackage = launchApi.getShellSessionHandoffPackage(); assertEqual( shellIntegrationSchema.manifestVersion, @@ -292,6 +295,21 @@ 1, "shell session handoff package version", ); + assertEqual( + shellSessionHandoffPackageSchema.packageVersion, + 1, + "shell session handoff package schema version", + ); + assertEqual( + launchApi.isSupportedShellSessionHandoffPackage(shellSessionHandoffPackage), + true, + "shell session handoff package supported", + ); + assertEqual( + launchApi.isSupportedShellSessionHandoffPackage({ ...shellSessionHandoffPackage, packageVersion: 2 }), + false, + "shell session handoff package rejects version", + ); assertEqual( shellSessionHandoffPackage.ready, true, diff --git a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html index 5bd2275..b6c624e 100644 --- a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html +++ b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html @@ -73,7 +73,9 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.getShellSessionHandoffRenderState || !launchApi?.getShellSessionHandoffActionPlan || !launchApi?.getShellSessionHandoffChecklist || - !launchApi?.getShellSessionHandoffPackage + !launchApi?.getShellSessionHandoffPackageSchema || + !launchApi?.getShellSessionHandoffPackage || + !launchApi?.isSupportedShellSessionHandoffPackage ) { throw new Error("launch API namespace did not expose shell integration helpers"); } @@ -88,6 +90,7 @@ TOOL_TABLE = browser-shell-tool.tbl const handoffRenderState = launchApi.getShellSessionHandoffRenderState(); const handoffActionPlan = launchApi.getShellSessionHandoffActionPlan(); const handoffChecklist = launchApi.getShellSessionHandoffChecklist(); + const handoffPackageSchema = launchApi.getShellSessionHandoffPackageSchema(); const handoffPackage = launchApi.getShellSessionHandoffPackage(); assertEqual(handoffSummarySchema.summaryVersion, 1, "shell handoff summary schema version"); assertEqual( @@ -125,6 +128,12 @@ TOOL_TABLE = browser-shell-tool.tbl "shell handoff checklist next steps", ); assertEqual(handoffPackage.ready, true, "shell handoff package readiness"); + assertEqual(handoffPackageSchema.packageVersion, 1, "shell handoff package schema version"); + assertEqual( + launchApi.isSupportedShellSessionHandoffPackage(handoffPackage), + true, + "shell handoff package supported", + ); assertEqual(handoffPackage.checklist.ready, handoffChecklist.ready, "shell handoff package checklist"); assertEqual( handoffPackage.actionPlan.nextSteps.map(({ id }) => id).join(","), diff --git a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs index 92d7aa8..fb40674 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs @@ -23,6 +23,7 @@ import { createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffPackage, + createIniPanelShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffRenderState, createIniPanelShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSummary, @@ -37,6 +38,7 @@ import { isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, + isSupportedIniPanelShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffSummary, } from "../../../runtime/ui/ini-panel/ui-shell.js"; @@ -80,6 +82,7 @@ const requiredShellExports = [ "createIniPanelShellSessionHandoffCompatibilityReport", "createIniPanelShellSessionHandoffDisplayViewModel", "createIniPanelShellSessionHandoffPackage", + "createIniPanelShellSessionHandoffPackageSchema", "createIniPanelShellSessionHandoffRenderState", "createIniPanelShellSessionHandoffSnapshot", "createIniPanelShellSessionHandoffSummary", @@ -90,6 +93,7 @@ const requiredShellExports = [ "isSupportedIniPanelControlPageApiManifest", "isSupportedIniPanelLaunchApiManifest", "isSupportedIniPanelShellIntegrationManifest", + "isSupportedIniPanelShellSessionHandoffPackage", "isSupportedIniPanelShellSessionHandoffSummary", "createMachineSessionControlPageController", "createMachineSessionReadonlyStatus", @@ -222,6 +226,11 @@ assert.deepEqual( checklist: createIniPanelShellViewModel().shellSessionHandoffChecklist, }), ); +assert.deepEqual( + createIniPanelShellViewModel().shellSessionHandoffPackageSchema, + createIniPanelShellSessionHandoffPackageSchema(), +); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(createIniPanelShellViewModel().shellSessionHandoffPackage), true); assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true); assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema()); assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, createIniPanelLaunchApiManifest()); @@ -281,6 +290,7 @@ assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffChec assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackage\b/); +assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageSchema\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffRenderState\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSnapshot\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummary\b/); @@ -288,6 +298,7 @@ assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSumm 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 isSupportedIniPanelShellSessionHandoffPackage\b/); assert.match(shellText, /\bexport function isSupportedIniPanelShellSessionHandoffSummary\b/); assert.match(controlPageText, /\bisSupportedControlPageApiManifest\b/); assert.match(controlPageText, /\bgetControlPageApiSchema\b/); @@ -309,7 +320,9 @@ assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/); assert.match(launchText, /\bgetShellSessionHandoffRenderState\b/); assert.match(launchText, /\bgetShellSessionHandoffActionPlan\b/); assert.match(launchText, /\bgetShellSessionHandoffChecklist\b/); +assert.match(launchText, /\bgetShellSessionHandoffPackageSchema\b/); assert.match(launchText, /\bgetShellSessionHandoffPackage\b/); +assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/); assert.match(launchText, /\bdata-handoff-shell\b/); assert.match(launchText, /\bdata-handoff-status\b/); assert.match(launchText, /\bdata-handoff-rows\b/); @@ -336,6 +349,7 @@ assert.match(docText, /\bcreateIniPanelShellSessionHandoffChecklist\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackage\b/); +assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageSchema\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffRenderState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/); @@ -343,6 +357,7 @@ assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/); assert.match(docText, /\bisSupportedIniPanelControlPageApiManifest\b/); assert.match(docText, /\bisSupportedIniPanelLaunchApiManifest\b/); assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/); +assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffPackage\b/); assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedLaunchApiManifest\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getLaunchApiSchema\b/); @@ -359,7 +374,9 @@ assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSnapsh assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffRenderState\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffActionPlan\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffChecklist\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffPackageSchema\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffPackage\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedShellSessionHandoffPackage\b/); assert.match(docText, /\bdata-handoff-shell\b/); assert.match(docText, /\bdata-handoff-status\b/); assert.match(docText, /\bdata-handoff-rows\b/); @@ -375,7 +392,9 @@ assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSnapsho assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffRenderState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffActionPlan\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffChecklist\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackageSchema\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackage\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\bisSupportedShellSessionHandoffPackage\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bhandoffSummary\.handoffMethods\.readStatus\b/); assert.match(shellIntegrationWorkflowSmokeText, /\breadControlPageStatus\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bbrowser_ini_shell_integration_workflow_smoke=ok\b/); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs index 5198b85..e001828 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs @@ -55,7 +55,9 @@ assert.deepEqual(manifest, { "getShellSessionHandoffRenderState", "getShellSessionHandoffActionPlan", "getShellSessionHandoffChecklist", + "getShellSessionHandoffPackageSchema", "getShellSessionHandoffPackage", + "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", ], @@ -165,7 +167,9 @@ assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/); assert.match(launchText, /\bgetShellSessionHandoffRenderState\b/); assert.match(launchText, /\bgetShellSessionHandoffActionPlan\b/); assert.match(launchText, /\bgetShellSessionHandoffChecklist\b/); +assert.match(launchText, /\bgetShellSessionHandoffPackageSchema\b/); assert.match(launchText, /\bgetShellSessionHandoffPackage\b/); +assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/); assert.match(launchText, /\blinuxCncIniPanelLaunchApi\b/); console.log("ini_panel_launch_api_manifest_node_smoke=ok"); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs index 14f7047..88d643c 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs @@ -19,12 +19,14 @@ import { createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffPackage, + createIniPanelShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffRenderState, createIniPanelShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSummary, createIniPanelShellSessionHandoffSummarySchema, getVisibleIniPanelEntries, isSupportedIniPanelShellIntegrationManifest, + isSupportedIniPanelShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffSummary, } from "../../../runtime/ui/ini-panel/ui-shell.js"; @@ -66,6 +68,7 @@ const handoffPackage = createIniPanelShellSessionHandoffPackage({ actionPlan: handoffActionPlan, checklist: handoffChecklist, }); +const handoffPackageSchema = createIniPanelShellSessionHandoffPackageSchema(); assert.deepEqual(schema, { apiName: "ini-panel-shell-integration", @@ -121,7 +124,7 @@ assert.deepEqual(readiness, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 18, + launchMethods: 20, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -183,7 +186,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 18, + launchMethods: 20, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -442,11 +445,61 @@ assert.deepEqual(handoffPackage, { actionPlan: handoffActionPlan, checklist: handoffChecklist, }); +assert.deepEqual(handoffPackageSchema, { + apiName: "ini-panel-shell-session-handoff-package", + packageVersion: 1, + fields: [ + "apiName", + "packageVersion", + "phase", + "ready", + "statusLine", + "manifests", + "snapshot", + "renderState", + "actionPlan", + "checklist", + ], + manifestFields: [ + "shellIntegration", + "launchApi", + "controlPageApi", + "launchMethods", + "controlPageMethods", + ], +}); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(handoffPackage), true); +assert.equal( + isSupportedIniPanelShellSessionHandoffPackage({ ...handoffPackage, packageVersion: 2 }), + false, +); +assert.equal( + isSupportedIniPanelShellSessionHandoffPackage({ ...handoffPackage, apiName: "other" }), + false, +); +const missingPackageField = { ...handoffPackage }; +delete missingPackageField.checklist; +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(missingPackageField), false); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage({ + ...handoffPackage, + manifests: { + ...handoffPackage.manifests, + controlPageMethods: undefined, + }, +}), true); +const missingManifestField = { + ...handoffPackage, + manifests: { ...handoffPackage.manifests }, +}; +delete missingManifestField.manifests.controlPageMethods; +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(missingManifestField), false); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(null), false); assert.equal(createIniPanelShellSessionHandoffSnapshot().displayViewModel.rows.length, 5); assert.equal(createIniPanelShellSessionHandoffRenderState().statusLine, "Ready: No blocking reasons"); assert.equal(createIniPanelShellSessionHandoffActionPlan().nextSteps.length, 2); assert.equal(createIniPanelShellSessionHandoffChecklist().checks.length, 5); assert.equal(createIniPanelShellSessionHandoffPackage().manifests.launchMethods.includes("getShellSessionHandoffPackage"), true); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(createIniPanelShellSessionHandoffPackage()), true); assert.deepEqual( createIniPanelShellSessionHandoffDisplayViewModel( createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }), @@ -663,7 +716,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 2, launcherLinks: 2, - launchMethods: 18, + launchMethods: 20, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -828,11 +881,13 @@ assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffChec assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackage\b/); +assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageSchema\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffRenderState\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 isSupportedIniPanelShellSessionHandoffPackage\b/); assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/); assert.match(launchText, /\bgetShellIntegrationSchema\b/); assert.match(launchText, /\bgetShellIntegrationManifest\b/); @@ -845,11 +900,13 @@ assert.match(docText, /\bcreateIniPanelShellSessionHandoffChecklist\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackage\b/); +assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageSchema\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffRenderState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/); assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/); +assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffPackage\b/); assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/); assert.doesNotMatch(shellText, /\bparseGcode\b|\bcanonicalEvents\b|\btoolTable\b|\bplanner\b/); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs index 761b20b..3c191b7 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs @@ -19,6 +19,7 @@ import { createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffPackage, + createIniPanelShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffRenderState, createIniPanelShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSummary, @@ -35,6 +36,7 @@ import { isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, + isSupportedIniPanelShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffSummary, loadMachineSessionForControlPageWorkflow, readMachineSessionReadonlyStatus, @@ -81,6 +83,7 @@ assert.equal(typeof createIniPanelShellSessionHandoffChecklist, "function"); assert.equal(typeof createIniPanelShellSessionHandoffCompatibilityReport, "function"); assert.equal(typeof createIniPanelShellSessionHandoffDisplayViewModel, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackage, "function"); +assert.equal(typeof createIniPanelShellSessionHandoffPackageSchema, "function"); assert.equal(typeof createIniPanelShellSessionHandoffRenderState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffSnapshot, "function"); assert.equal(typeof createIniPanelShellSessionHandoffSummary, "function"); @@ -92,6 +95,7 @@ assert.equal(typeof renderMachineSessionControlView, "function"); assert.equal(typeof isSupportedIniPanelControlPageApiManifest, "function"); assert.equal(typeof isSupportedIniPanelLaunchApiManifest, "function"); assert.equal(typeof isSupportedIniPanelShellIntegrationManifest, "function"); +assert.equal(typeof isSupportedIniPanelShellSessionHandoffPackage, "function"); assert.equal(typeof isSupportedIniPanelShellSessionHandoffSummary, "function"); const shellManifest = getIniPanelEntryManifest(); @@ -199,6 +203,8 @@ assert.deepEqual( checklist: shellViewModel.shellSessionHandoffChecklist, }), ); +assert.deepEqual(shellViewModel.shellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema()); +assert.equal(isSupportedIniPanelShellSessionHandoffPackage(shellViewModel.shellSessionHandoffPackage), true); assert.deepEqual(shellViewModel.shellSessionHandoffDisplayViewModel, { phase: "ready", title: "Shell handoff compatibility", @@ -342,6 +348,29 @@ assert.deepEqual(shellViewModel.shellSessionHandoffPackage, { actionPlan: shellViewModel.shellSessionHandoffActionPlan, checklist: shellViewModel.shellSessionHandoffChecklist, }); +assert.deepEqual(shellViewModel.shellSessionHandoffPackageSchema, { + apiName: "ini-panel-shell-session-handoff-package", + packageVersion: 1, + fields: [ + "apiName", + "packageVersion", + "phase", + "ready", + "statusLine", + "manifests", + "snapshot", + "renderState", + "actionPlan", + "checklist", + ], + manifestFields: [ + "shellIntegration", + "launchApi", + "controlPageApi", + "launchMethods", + "controlPageMethods", + ], +}); assert.equal( isSupportedIniPanelShellIntegrationManifest(shellViewModel.shellIntegrationManifest), true, @@ -390,6 +419,8 @@ assert.equal(shellViewModel.createShellSessionHandoffRenderState, createIniPanel assert.equal(shellViewModel.createShellSessionHandoffActionPlan, createIniPanelShellSessionHandoffActionPlan); assert.equal(shellViewModel.createShellSessionHandoffChecklist, createIniPanelShellSessionHandoffChecklist); assert.equal(shellViewModel.createShellSessionHandoffPackage, createIniPanelShellSessionHandoffPackage); +assert.equal(shellViewModel.createShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema); +assert.equal(shellViewModel.isSupportedShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffPackage); assert.deepEqual(shellViewModel.controlPage.contract, createIniPanelShellControlPageContract()); assert.equal(shellViewModel.controlPage.isSupportedBrowserApiManifest, isSupportedIniPanelControlPageApiManifest); assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);