推进 INI 面板 shell session handoff summary
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellViewModel,
|
||||
getIniPanelEntryByHref,
|
||||
getVisibleIniPanelEntries,
|
||||
@@ -129,6 +130,9 @@ Use `createIniPanelShellIntegrationWorkflowPlan()` when the outer shell needs a
|
||||
Node-testable read-only plan for the control-page target, required launch and
|
||||
control-page API methods, readiness gate, and readonly status handoff fields
|
||||
before opening a browser frame.
|
||||
Use `createIniPanelShellSessionHandoffSummary()` when the outer shell needs one
|
||||
read-only display summary of readiness, target page, persistence capabilities,
|
||||
readonly status fields, handoff methods, and blocking reasons.
|
||||
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,
|
||||
|
||||
@@ -380,9 +380,44 @@ export function createIniPanelShellIntegrationWorkflowPlan({
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellSessionHandoffSummary({
|
||||
manifest = createIniPanelShellIntegrationManifest(),
|
||||
readiness = createIniPanelShellIntegrationReadiness(manifest),
|
||||
workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness }),
|
||||
} = {}) {
|
||||
const persistenceCapabilities = Array.isArray(manifest?.persistenceCapabilities)
|
||||
? manifest.persistenceCapabilities.map(({ id, label, scope }) => ({ id, label, scope }))
|
||||
: [];
|
||||
const readonlyStatusFields = Array.isArray(workflowPlan?.readonlyStatusHandoff?.expectedStatusFields)
|
||||
? [...workflowPlan.readonlyStatusHandoff.expectedStatusFields]
|
||||
: [];
|
||||
return {
|
||||
phase: workflowPlan.ready ? "ready" : "blocked",
|
||||
ready: Boolean(workflowPlan.ready),
|
||||
targetPage: workflowPlan.targetPage,
|
||||
readiness: {
|
||||
phase: readiness.phase,
|
||||
missing: [...readiness.missing],
|
||||
counts: { ...readiness.counts },
|
||||
apiNames: { ...readiness.apiNames },
|
||||
},
|
||||
persistenceCapabilities,
|
||||
readonlyStatusFields,
|
||||
handoffMethods: {
|
||||
loadSessionState: workflowPlan.readonlyStatusHandoff.loadSessionStateMethod,
|
||||
readStatus: workflowPlan.readonlyStatusHandoff.readStatusMethod,
|
||||
},
|
||||
blockingReasons: [...workflowPlan.missing],
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) {
|
||||
const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries);
|
||||
const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest);
|
||||
const shellIntegrationWorkflowPlan = createIniPanelShellIntegrationWorkflowPlan({
|
||||
manifest: shellIntegrationManifest,
|
||||
readiness: shellIntegrationReadiness,
|
||||
});
|
||||
return {
|
||||
pages: entries.map(({ id, href, title }) => ({
|
||||
id,
|
||||
@@ -393,15 +428,18 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
|
||||
shellIntegrationSchema: createIniPanelShellIntegrationSchema(),
|
||||
shellIntegrationManifest,
|
||||
shellIntegrationReadiness,
|
||||
shellIntegrationWorkflowPlan: createIniPanelShellIntegrationWorkflowPlan({
|
||||
shellIntegrationWorkflowPlan,
|
||||
shellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary({
|
||||
manifest: shellIntegrationManifest,
|
||||
readiness: shellIntegrationReadiness,
|
||||
workflowPlan: shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
launchApiSchema: createIniPanelLaunchApiSchema(),
|
||||
launchApiManifest: createIniPanelLaunchApiManifest(entries),
|
||||
isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest,
|
||||
createShellIntegrationReadiness: createIniPanelShellIntegrationReadiness,
|
||||
createShellIntegrationWorkflowPlan: createIniPanelShellIntegrationWorkflowPlan,
|
||||
createShellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary,
|
||||
controlPage: {
|
||||
browserApiSchema: createControlPageBrowserApiSchema(),
|
||||
browserApiManifest: createControlPageBrowserApiManifest(),
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellViewModel,
|
||||
createMachineSessionReadonlyStatus,
|
||||
createMachineSessionReadonlyStatusApiManifest,
|
||||
@@ -65,6 +66,7 @@ const requiredShellExports = [
|
||||
"createIniPanelShellIntegrationReadiness",
|
||||
"createIniPanelShellIntegrationSchema",
|
||||
"createIniPanelShellIntegrationWorkflowPlan",
|
||||
"createIniPanelShellSessionHandoffSummary",
|
||||
"createIniPanelShellViewModel",
|
||||
"getIniPanelEntryByHref",
|
||||
"getVisibleIniPanelEntries",
|
||||
@@ -142,6 +144,14 @@ assert.deepEqual(
|
||||
readiness: createIniPanelShellViewModel().shellIntegrationReadiness,
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(
|
||||
createIniPanelShellViewModel().shellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummary({
|
||||
manifest: createIniPanelShellViewModel().shellIntegrationManifest,
|
||||
readiness: createIniPanelShellViewModel().shellIntegrationReadiness,
|
||||
workflowPlan: createIniPanelShellViewModel().shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
);
|
||||
assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true);
|
||||
assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema());
|
||||
assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, createIniPanelLaunchApiManifest());
|
||||
@@ -196,6 +206,7 @@ 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 createIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelControlPageApiManifest\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelLaunchApiManifest\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
|
||||
@@ -228,6 +239,7 @@ assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationSchema\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelControlPageApiManifest\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelLaunchApiManifest\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
getVisibleIniPanelEntries,
|
||||
isSupportedIniPanelShellIntegrationManifest,
|
||||
} from "../../../runtime/ui/ini-panel/ui-shell.js";
|
||||
@@ -28,6 +29,7 @@ const schema = createIniPanelShellIntegrationSchema();
|
||||
const manifest = createIniPanelShellIntegrationManifest();
|
||||
const readiness = createIniPanelShellIntegrationReadiness(manifest);
|
||||
const workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness });
|
||||
const handoffSummary = createIniPanelShellSessionHandoffSummary({ manifest, readiness, workflowPlan });
|
||||
|
||||
assert.deepEqual(schema, {
|
||||
apiName: "ini-panel-shell-integration",
|
||||
@@ -130,6 +132,63 @@ assert.deepEqual(workflowPlan, {
|
||||
],
|
||||
},
|
||||
});
|
||||
assert.deepEqual(handoffSummary, {
|
||||
phase: "ready",
|
||||
ready: true,
|
||||
targetPage: {
|
||||
entryId: "control-view",
|
||||
href: "./control-page.html",
|
||||
},
|
||||
readiness: {
|
||||
phase: "ready",
|
||||
missing: [],
|
||||
counts: {
|
||||
pages: 2,
|
||||
launcherLinks: 2,
|
||||
launchMethods: 8,
|
||||
controlPageMethods: 11,
|
||||
persistenceCapabilities: 3,
|
||||
},
|
||||
apiNames: {
|
||||
integration: "ini-panel-shell-integration",
|
||||
launch: "ini-panel-launch",
|
||||
controlPage: "ini-panel-control-page",
|
||||
},
|
||||
},
|
||||
persistenceCapabilities: [
|
||||
{
|
||||
id: "machine-files",
|
||||
label: "Machine text files",
|
||||
scope: "opfs",
|
||||
},
|
||||
{
|
||||
id: "session-snapshot",
|
||||
label: "Machine session snapshot",
|
||||
scope: "opfs",
|
||||
},
|
||||
{
|
||||
id: "readonly-status",
|
||||
label: "Read-only machine session status",
|
||||
scope: "control-page",
|
||||
},
|
||||
],
|
||||
readonlyStatusFields: [
|
||||
"stateBundle",
|
||||
"workflowStatus",
|
||||
"overview",
|
||||
"controlView",
|
||||
"report",
|
||||
"runReadiness",
|
||||
"run",
|
||||
"session",
|
||||
"status",
|
||||
],
|
||||
handoffMethods: {
|
||||
loadSessionState: "loadControlPageSessionState",
|
||||
readStatus: "readControlPageStatus",
|
||||
},
|
||||
blockingReasons: [],
|
||||
});
|
||||
const blockedManifest = {
|
||||
...createIniPanelShellIntegrationManifest(),
|
||||
compatibility: {
|
||||
@@ -168,6 +227,18 @@ assert.deepEqual(
|
||||
}).missing,
|
||||
["launchCompatibility"],
|
||||
);
|
||||
const blockedWorkflowPlan = createIniPanelShellIntegrationWorkflowPlan({
|
||||
manifest: blockedManifest,
|
||||
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
|
||||
});
|
||||
assert.deepEqual(
|
||||
createIniPanelShellSessionHandoffSummary({
|
||||
manifest: blockedManifest,
|
||||
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
|
||||
workflowPlan: blockedWorkflowPlan,
|
||||
}).blockingReasons,
|
||||
["launchCompatibility"],
|
||||
);
|
||||
const missingTargetPlan = createIniPanelShellIntegrationWorkflowPlan({
|
||||
manifest,
|
||||
controlEntryId: "missing-entry",
|
||||
@@ -189,6 +260,10 @@ assert.equal(missingControlMethodPlan.ready, false);
|
||||
assert.deepEqual(missingControlMethodPlan.missing, [
|
||||
"controlPageApi.loadControlPageSessionState",
|
||||
]);
|
||||
handoffSummary.persistenceCapabilities[0].label = "changed";
|
||||
handoffSummary.readonlyStatusFields.push("changedField");
|
||||
assert.equal(createIniPanelShellSessionHandoffSummary().persistenceCapabilities[0].label, "Machine text files");
|
||||
assert.equal(createIniPanelShellSessionHandoffSummary().readonlyStatusFields.includes("changedField"), false);
|
||||
const malformedReadiness = createIniPanelShellIntegrationReadiness({
|
||||
apiName: "other",
|
||||
});
|
||||
@@ -262,6 +337,7 @@ 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 createIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
|
||||
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
|
||||
@@ -269,6 +345,7 @@ assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
|
||||
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
|
||||
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
|
||||
assert.doesNotMatch(shellText, /\bparseGcode\b|\bcanonicalEvents\b|\btoolTable\b|\bplanner\b/);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
createIniPanelShellIntegrationReadiness,
|
||||
createIniPanelShellIntegrationSchema,
|
||||
createIniPanelShellIntegrationWorkflowPlan,
|
||||
createIniPanelShellSessionHandoffSummary,
|
||||
createIniPanelShellViewModel,
|
||||
createMachineSessionReadonlyStatus,
|
||||
createMachineSessionReadonlyStatusApiManifest,
|
||||
@@ -66,6 +67,7 @@ assert.equal(typeof createIniPanelShellIntegrationManifest, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationReadiness, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationSchema, "function");
|
||||
assert.equal(typeof createIniPanelShellIntegrationWorkflowPlan, "function");
|
||||
assert.equal(typeof createIniPanelShellSessionHandoffSummary, "function");
|
||||
assert.equal(typeof loadMachineSessionForControlPageWorkflow, "function");
|
||||
assert.equal(typeof readMachineSessionReadonlyStatus, "function");
|
||||
assert.equal(typeof refreshMachineSessionControlPage, "function");
|
||||
@@ -122,6 +124,14 @@ assert.deepEqual(
|
||||
readiness: shellViewModel.shellIntegrationReadiness,
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(
|
||||
shellViewModel.shellSessionHandoffSummary,
|
||||
createIniPanelShellSessionHandoffSummary({
|
||||
manifest: shellViewModel.shellIntegrationManifest,
|
||||
readiness: shellViewModel.shellIntegrationReadiness,
|
||||
workflowPlan: shellViewModel.shellIntegrationWorkflowPlan,
|
||||
}),
|
||||
);
|
||||
assert.equal(
|
||||
isSupportedIniPanelShellIntegrationManifest(shellViewModel.shellIntegrationManifest),
|
||||
true,
|
||||
@@ -154,6 +164,7 @@ assert.equal(shellViewModel.controlPage.createController, createMachineSessionCo
|
||||
assert.equal(shellViewModel.isSupportedShellIntegrationManifest, isSupportedIniPanelShellIntegrationManifest);
|
||||
assert.equal(shellViewModel.createShellIntegrationReadiness, createIniPanelShellIntegrationReadiness);
|
||||
assert.equal(shellViewModel.createShellIntegrationWorkflowPlan, createIniPanelShellIntegrationWorkflowPlan);
|
||||
assert.equal(shellViewModel.createShellSessionHandoffSummary, createIniPanelShellSessionHandoffSummary);
|
||||
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