diff --git a/text12.txt b/text12.txt index 3a0c70d..dcec0eb 100644 --- a/text12.txt +++ b/text12.txt @@ -3172,3 +3172,77 @@ host_wasm_opfs_browser_smokes=ok `createIniPanelShellSessionHandoffWorkflowRenderState()`),把 workflow display-model 压缩成稳定 dataset/statusLine/rows,方便外部 shell 直接渲染 end-to-end handoff 总览 DOM;仍保持只读,不新增控制按钮, 不解析 G-code。 + +四十、2026-06-15 继续执行记录:INI panel shell handoff workflow render-state helper + +本轮按“第一原则:加快实质性推进”继续推进 SDK/API surface 与 browser/UI workflow,为 shell +handoff 增加 workflow render-state helper,把 workflow display-model 压缩成稳定的 +dataset/statusLine/rows,方便外部 shell 直接渲染 end-to-end handoff 总览 DOM。 + +完成内容: + +- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffWorkflowRenderState()`; +- 新 helper 读取 workflow display-model,返回 `apiName`、`renderStateVersion`、`phase`、`ready`、 + `title`、`statusText`、`detailText`、`statusLine`、rows 与 dataset; +- `createIniPanelShellViewModel()` 暴露 `shellSessionHandoffWorkflowRenderState` 与 + `createShellSessionHandoffWorkflowRenderState`; +- `createIniPanelLaunchApiManifest().methods` 新增 `getShellSessionHandoffWorkflowRenderState`, + launch method count 更新为 35; +- `launch.html` 的 `window.linuxCncIniPanelLaunchApi.getShellSessionHandoffWorkflowRenderState()` 暴露 + 真实 browser API; +- `ini_panel_shell_integration_workflow_smoke.html` 在真实 browser workflow 中通过 shared render-state + helper 校验 ready、statusLine 与 dataset scope; +- Node smoke 覆盖 render-state helper 的 blocked/ready 路径; +- 文档同步记录 render-state helper 用法; +- 未新增控制按钮; +- 未解析 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_launch_api_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_shell_integration_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_launch_api_manifest_node_smoke=ok +ini_panel_shell_integration_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 +``` + +下一步建议: + +继续推进 SDK/API surface。下一批建议增加 shell handoff workflow DOM mount helper(例如 +`renderIniPanelShellSessionHandoffWorkflowState()` 或 `mountIniPanelShellSessionHandoffWorkflow()`),把 +workflow render-state 渲染进稳定 DOM contract,方便外部 shell 直接挂载 end-to-end handoff 总览;仍保持只读, +不新增控制按钮,不解析 G-code。 diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index ad600ca..faa5564 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -36,6 +36,7 @@ import { mountIniPanelShellSessionHandoffFromControlPage, createIniPanelShellSessionHandoffWorkflowSummary, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createIniPanelShellSessionHandoffWorkflowRenderState, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -261,6 +262,10 @@ reasons into display rows. Use `linuxCncIniPanelLaunchApi.getShellSessionHandoffWorkflowDisplayViewModel()` when an outer shell needs that end-to-end summary compressed into stable `title`, `statusText`, `detailText`, and rows for direct display. Use +`createIniPanelShellSessionHandoffWorkflowRenderState()` or +`linuxCncIniPanelLaunchApi.getShellSessionHandoffWorkflowRenderState()` when an +outer shell needs that workflow display-model compressed into stable +`dataset`, `statusLine`, and rows for direct DOM rendering. Use `renderIniPanelShellSessionHandoffMountState()` or `linuxCncIniPanelLaunchApi.renderShellSessionHandoffMountState()` when an outer shell needs the shared read-only DOM renderer for those rows. The launch page diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index df6fa46..5c30265 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -113,6 +113,7 @@ readIniPanelShellSessionHandoffStatusFromControlPage, createIniPanelShellSessionHandoffWorkflowSummary, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createIniPanelShellSessionHandoffWorkflowRenderState, renderIniPanelShellSessionHandoffMountState, } from "./ui-shell.js"; @@ -238,6 +239,11 @@ options ?? shellViewModel.shellSessionHandoffWorkflowSummary, ) ), + getShellSessionHandoffWorkflowRenderState: (options) => ( + createIniPanelShellSessionHandoffWorkflowRenderState( + options ?? shellViewModel.shellSessionHandoffWorkflowDisplayViewModel, + ) + ), 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 ab78e6c..8ab766e 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -151,6 +151,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "readShellSessionHandoffStatusFromControlPage", "getShellSessionHandoffWorkflowSummary", "getShellSessionHandoffWorkflowDisplayViewModel", + "getShellSessionHandoffWorkflowRenderState", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -1496,6 +1497,38 @@ export function createIniPanelShellSessionHandoffWorkflowDisplayViewModel( }; } +export function createIniPanelShellSessionHandoffWorkflowRenderState( + displayViewModel = createIniPanelShellSessionHandoffWorkflowDisplayViewModel(), +) { + const rows = Array.isArray(displayViewModel?.rows) + ? displayViewModel.rows.map(({ id, label, value }) => ({ + id, + label, + value: value == null ? "" : String(value), + })) + : []; + const ready = displayViewModel?.phase === "ready" && displayViewModel?.statusText === "Ready"; + const statusText = displayViewModel?.statusText ?? (ready ? "Ready" : "Blocked"); + const detailText = displayViewModel?.detailText ?? "No blocking reasons"; + + return { + apiName: "ini-panel-shell-session-handoff-workflow-render-state", + renderStateVersion: 1, + phase: ready ? "ready" : "blocked", + ready, + title: displayViewModel?.title ?? "Shell handoff workflow", + statusText, + detailText, + statusLine: `${statusText}: ${detailText}`, + rows, + dataset: { + handoffPhase: ready ? "ready" : "blocked", + handoffReady: ready ? "true" : "false", + handoffScope: "workflow", + }, + }; +} + export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries); const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest); @@ -1578,6 +1611,9 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries const shellSessionHandoffWorkflowDisplayViewModel = createIniPanelShellSessionHandoffWorkflowDisplayViewModel( shellSessionHandoffWorkflowSummary, ); + const shellSessionHandoffWorkflowRenderState = createIniPanelShellSessionHandoffWorkflowRenderState( + shellSessionHandoffWorkflowDisplayViewModel, + ); return { pages: entries.map(({ id, href, title }) => ({ id, @@ -1608,6 +1644,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries shellSessionHandoffMountDomContract, shellSessionHandoffWorkflowSummary, shellSessionHandoffWorkflowDisplayViewModel, + shellSessionHandoffWorkflowRenderState, launchApiSchema: createIniPanelLaunchApiSchema(), launchApiManifest: createIniPanelLaunchApiManifest(entries), isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest, @@ -1638,6 +1675,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries readShellSessionHandoffStatusFromControlPage: readIniPanelShellSessionHandoffStatusFromControlPage, createShellSessionHandoffWorkflowSummary: createIniPanelShellSessionHandoffWorkflowSummary, createShellSessionHandoffWorkflowDisplayViewModel: createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createShellSessionHandoffWorkflowRenderState: createIniPanelShellSessionHandoffWorkflowRenderState, isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), 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 f2130c8..e605173 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 @@ -93,6 +93,7 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.readShellSessionHandoffStatusFromControlPage || !launchApi?.getShellSessionHandoffWorkflowSummary || !launchApi?.getShellSessionHandoffWorkflowDisplayViewModel || + !launchApi?.getShellSessionHandoffWorkflowRenderState || !launchApi?.isSupportedShellSessionHandoffPackage ) { throw new Error("launch API namespace did not expose shell integration helpers"); @@ -367,6 +368,9 @@ TOOL_TABLE = browser-shell-tool.tbl const workflowDisplayResult = launchApi.getShellSessionHandoffWorkflowDisplayViewModel( workflowSummaryResult, ); + const workflowRenderState = launchApi.getShellSessionHandoffWorkflowRenderState( + workflowDisplayResult, + ); assertEqual(readonlyStatusResult.phase, "ready", "shell handoff readonly status result phase"); assertEqual(readonlyStatusResult.ready, true, "shell handoff readonly status result readiness"); assertEqual( @@ -380,6 +384,9 @@ TOOL_TABLE = browser-shell-tool.tbl assertEqual(workflowDisplayResult.phase, "ready", "shell handoff workflow display phase"); assertEqual(workflowDisplayResult.statusText, "Ready", "shell handoff workflow display status"); assertEqual(workflowDisplayResult.detailText, "No blocking reasons", "shell handoff workflow display detail"); + assertEqual(workflowRenderState.phase, "ready", "shell handoff workflow render-state phase"); + assertEqual(workflowRenderState.statusLine, "Ready: No blocking reasons", "shell handoff workflow render-state status"); + assertEqual(workflowRenderState.dataset.handoffScope, "workflow", "shell handoff workflow render-state scope"); assertEqual( readonlyStatus.workflowStatus.lastAction, "load-session", 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 af42f74..796defa 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 @@ -34,6 +34,7 @@ import { readIniPanelShellSessionHandoffStatusFromControlPage, createIniPanelShellSessionHandoffWorkflowSummary, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createIniPanelShellSessionHandoffWorkflowRenderState, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -107,6 +108,7 @@ const requiredShellExports = [ "readIniPanelShellSessionHandoffStatusFromControlPage", "createIniPanelShellSessionHandoffWorkflowSummary", "createIniPanelShellSessionHandoffWorkflowDisplayViewModel", + "createIniPanelShellSessionHandoffWorkflowRenderState", "renderIniPanelShellSessionHandoffMountState", "createIniPanelShellSessionHandoffPackageReport", "createIniPanelShellSessionHandoffPackageRenderState", @@ -321,6 +323,10 @@ assert.equal( createIniPanelShellSessionHandoffWorkflowDisplayViewModel().phase, "blocked", ); +assert.equal( + createIniPanelShellSessionHandoffWorkflowRenderState().phase, + "blocked", +); assert.equal(isSupportedIniPanelShellSessionHandoffPackage(createIniPanelShellViewModel().shellSessionHandoffPackage), true); assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true); assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema()); @@ -485,6 +491,7 @@ assert.match(docText, /\blinuxCncIniPanelLaunchApi\.mountShellSessionHandoffFrom assert.match(docText, /\blinuxCncIniPanelLaunchApi\.readShellSessionHandoffStatusFromControlPage\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffWorkflowSummary\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffWorkflowDisplayViewModel\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffWorkflowRenderState\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/); @@ -508,6 +515,7 @@ assert.match(shellIntegrationWorkflowSmokeText, /\bmountShellSessionHandoffFromC assert.match(shellIntegrationWorkflowSmokeText, /\breadShellSessionHandoffStatusFromControlPage\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffWorkflowSummary\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffWorkflowDisplayViewModel\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffWorkflowRenderState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\brenderShellSessionHandoffMountState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-shell-mount\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-mount-value\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 fcfacd5..d720d00 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 @@ -71,6 +71,7 @@ assert.deepEqual(manifest, { "readShellSessionHandoffStatusFromControlPage", "getShellSessionHandoffWorkflowSummary", "getShellSessionHandoffWorkflowDisplayViewModel", + "getShellSessionHandoffWorkflowRenderState", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -197,6 +198,7 @@ assert.match(launchText, /\bmountShellSessionHandoffFromControlPage\b/); assert.match(launchText, /\breadShellSessionHandoffStatusFromControlPage\b/); assert.match(launchText, /\bgetShellSessionHandoffWorkflowSummary\b/); assert.match(launchText, /\bgetShellSessionHandoffWorkflowDisplayViewModel\b/); +assert.match(launchText, /\bgetShellSessionHandoffWorkflowRenderState\b/); assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/); assert.match(launchText, /\bdata-handoff-mount\b/); assert.match(launchText, /\bdata-handoff-mount-status\b/); 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 3210945..47f1826 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 @@ -30,6 +30,7 @@ import { readIniPanelShellSessionHandoffStatusFromControlPage, createIniPanelShellSessionHandoffWorkflowSummary, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createIniPanelShellSessionHandoffWorkflowRenderState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, createIniPanelShellSessionHandoffPackageSchema, @@ -156,7 +157,7 @@ assert.deepEqual(readiness, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 34, + launchMethods: 35, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -218,7 +219,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 34, + launchMethods: 35, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -726,6 +727,10 @@ assert.equal( createIniPanelShellSessionHandoffWorkflowDisplayViewModel().phase, "blocked", ); +assert.equal( + createIniPanelShellSessionHandoffWorkflowRenderState().phase, + "blocked", +); assert.deepEqual( createIniPanelShellSessionHandoffPackageMountState({ handoffPackage, @@ -1137,7 +1142,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 2, launcherLinks: 2, - launchMethods: 34, + launchMethods: 35, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -1313,6 +1318,7 @@ assert.match(shellText, /\bexport function mountIniPanelShellSessionHandoffFromC assert.match(shellText, /\bexport function readIniPanelShellSessionHandoffStatusFromControlPage\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffWorkflowSummary\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffWorkflowDisplayViewModel\b/); +assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffWorkflowRenderState\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageRenderState\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageSchema\b/); @@ -1345,6 +1351,7 @@ assert.match(docText, /\bmountIniPanelShellSessionHandoffFromControlPage\b/); assert.match(docText, /\breadIniPanelShellSessionHandoffStatusFromControlPage\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffWorkflowSummary\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffWorkflowDisplayViewModel\b/); +assert.match(docText, /\bcreateIniPanelShellSessionHandoffWorkflowRenderState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageRenderState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageSchema\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 0405b3d..c0a77dc 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 @@ -30,6 +30,7 @@ import { readIniPanelShellSessionHandoffStatusFromControlPage, createIniPanelShellSessionHandoffWorkflowSummary, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, + createIniPanelShellSessionHandoffWorkflowRenderState, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -108,6 +109,7 @@ assert.equal(typeof mountIniPanelShellSessionHandoffFromControlPage, "function") assert.equal(typeof readIniPanelShellSessionHandoffStatusFromControlPage, "function"); assert.equal(typeof createIniPanelShellSessionHandoffWorkflowSummary, "function"); assert.equal(typeof createIniPanelShellSessionHandoffWorkflowDisplayViewModel, "function"); +assert.equal(typeof createIniPanelShellSessionHandoffWorkflowRenderState, "function"); assert.equal(typeof renderIniPanelShellSessionHandoffMountState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageReport, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageRenderState, "function"); @@ -726,6 +728,10 @@ assert.equal( shellViewModel.createShellSessionHandoffWorkflowDisplayViewModel, createIniPanelShellSessionHandoffWorkflowDisplayViewModel, ); +assert.equal( + shellViewModel.createShellSessionHandoffWorkflowRenderState, + createIniPanelShellSessionHandoffWorkflowRenderState, +); assert.equal(shellViewModel.createShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageReport); assert.equal(shellViewModel.createShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema); assert.equal(shellViewModel.isSupportedShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffPackage); @@ -986,6 +992,20 @@ const readyWorkflowDisplayViewModel = createIniPanelShellSessionHandoffWorkflowD assert.equal(readyWorkflowDisplayViewModel.phase, "ready"); assert.equal(readyWorkflowDisplayViewModel.statusText, "Ready"); assert.equal(readyWorkflowDisplayViewModel.detailText, "No blocking reasons"); +const workflowRenderState = createIniPanelShellSessionHandoffWorkflowRenderState( + workflowDisplayViewModel, +); +assert.equal(workflowRenderState.apiName, "ini-panel-shell-session-handoff-workflow-render-state"); +assert.equal(workflowRenderState.renderStateVersion, 1); +assert.equal(workflowRenderState.phase, "blocked"); +assert.equal(workflowRenderState.statusLine, "Blocked: mount:blocked"); +assert.equal(workflowRenderState.dataset.handoffScope, "workflow"); +assert.equal(workflowRenderState.rows.length, 5); +const readyWorkflowRenderState = createIniPanelShellSessionHandoffWorkflowRenderState( + readyWorkflowDisplayViewModel, +); +assert.equal(readyWorkflowRenderState.phase, "ready"); +assert.equal(readyWorkflowRenderState.statusLine, "Ready: No blocking reasons"); assert.deepEqual( mountIniPanelShellSessionHandoff({ documentRef: mountDocument }).renderResult, null,