Files
cnc_wams/wasm-port/runtime/ui/ini-panel/ui-shell.js
wangdequan 24e1fc18b1 上传真实浏览器仿真推进
结论:新增 LinuxCNC WASM 驱动的真实浏览器仿真页面,接入 browser smoke、release gate、SDK 与项目交付文档,并完成当前推进批次的验收记录。
2026-06-16 20:59:21 +08:00

4873 lines
180 KiB
JavaScript

import {
INI_PANEL_ENTRIES,
getIniPanelEntryByHref,
getIniPanelEntryManifest,
} from "./entry-manifest.js";
import {
createMachineSessionControlPageController,
} from "./control-page-controller.js";
import {
renderMachineSessionControlView,
} from "./control-view-renderer.js";
import {
controlPageStatusText,
createControlPageRefreshState,
refreshMachineSessionControlPage,
} from "./control-page-refresh-workflow.js";
import {
createControlPageSessionLoadState,
loadMachineSessionForControlPageWorkflow,
} from "./control-page-session-workflow.js";
import {
createMachineSessionReadinessFieldState,
machineSessionReadinessLogLines,
readMachineSessionReadinessWorkflow,
} from "./session-workflow.js";
import {
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
readMachineSessionReadonlyStatus,
} from "./readonly-status-api.js";
import {
createMachineSessionPersistenceSummary,
} from "./panel-state-summary.js";
import {
createProjectReleaseGateExecutionSummaryViewModel,
createProjectReleaseReadinessArtifactJsonWorkflow,
createProjectReleaseReadinessArtifactUrlWorkflowActionPlan,
createProjectReleaseReadinessArtifactValidation,
createProjectReleaseReadinessArtifactValidationActionPlan,
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
parseProjectReleaseReadinessArtifactJson,
} from "../../sdk/src/project-release-readiness.js";
export {
controlPageStatusText,
createControlPageRefreshState,
refreshMachineSessionControlPage,
} from "./control-page-refresh-workflow.js";
export {
createControlPageSessionLoadState,
loadMachineSessionForControlPageWorkflow,
} from "./control-page-session-workflow.js";
export {
createMachineSessionReadinessFieldState,
machineSessionReadinessLogLines,
readMachineSessionReadinessWorkflow,
} from "./session-workflow.js";
export {
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
readMachineSessionReadonlyStatus,
} from "./readonly-status-api.js";
export {
INI_PANEL_ENTRIES,
getIniPanelEntryByHref,
getIniPanelEntryManifest,
} from "./entry-manifest.js";
export {
createMachineSessionControlPageController,
} from "./control-page-controller.js";
export {
renderMachineSessionControlView,
} from "./control-view-renderer.js";
export {
createMachineSessionControlView,
createMachineSessionPersistenceDisplayViewModel,
createMachineSessionPersistenceRenderState,
createMachineSessionPersistenceSummary,
createMachineSessionStateBundle,
createMachineSessionStateReport,
createMachineSessionStateReportExport,
createMachineSessionWorkflowOverview,
createMachineSessionWorkflowStatus,
} from "./panel-state-summary.js";
export {
createProjectReleaseGateExecutionSummaryViewModel,
createProjectReleaseReadinessArtifactJsonWorkflow,
createProjectReleaseReadinessArtifactUrlWorkflowActionPlan,
createProjectReleaseReadinessArtifactValidation,
createProjectReleaseReadinessArtifactValidationActionPlan,
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
parseProjectReleaseReadinessArtifactJson,
} from "../../sdk/src/project-release-readiness.js";
export function getVisibleIniPanelEntries() {
return getIniPanelEntryManifest();
}
export function createIniPanelLauncherLinkViewModel(entries = getVisibleIniPanelEntries()) {
return entries.map(({ id, href, title }) => ({
entryId: id,
href,
label: title,
}));
}
export function createIniPanelLaunchApiSchema() {
return {
apiName: "ini-panel-launch",
manifestVersion: 1,
fields: [
"apiName",
"manifestVersion",
"methods",
"visibleEntries",
"targetPages",
"controlPageApiMethods",
"persistenceCapabilities",
],
};
}
export function isSupportedIniPanelLaunchApiManifest(manifest, schema = createIniPanelLaunchApiSchema()) {
if (!manifest || typeof manifest !== "object") {
return false;
}
if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) {
return false;
}
return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName));
}
export function createControlPageBrowserApiSchema() {
return {
apiName: "ini-panel-control-page",
manifestVersion: 1,
fields: [
"apiName",
"manifestVersion",
"methods",
"contract",
"readonlyStatusApiManifest",
],
};
}
export function isSupportedIniPanelControlPageApiManifest(
manifest,
schema = createControlPageBrowserApiSchema(),
) {
if (!manifest || typeof manifest !== "object") {
return false;
}
if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) {
return false;
}
return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName));
}
export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntries()) {
const schema = createIniPanelLaunchApiSchema();
return {
apiName: schema.apiName,
manifestVersion: schema.manifestVersion,
methods: [
"isSupportedLaunchApiManifest",
"getLaunchApiSchema",
"getLaunchApiManifest",
"getShellIntegrationSchema",
"getShellIntegrationManifest",
"getShellIntegrationReadiness",
"getShellSessionHandoffSummarySchema",
"getShellSessionHandoffSummary",
"isSupportedShellSessionHandoffSummary",
"getShellSessionHandoffCompatibilityReport",
"getShellSessionHandoffDisplayViewModel",
"getShellSessionHandoffSnapshot",
"getShellSessionHandoffRenderState",
"getShellSessionHandoffActionPlan",
"getShellSessionHandoffChecklist",
"getShellSessionHandoffPackageSchema",
"getShellSessionHandoffPackage",
"getShellSessionHandoffPackageReport",
"getShellSessionHandoffPackageDisplayViewModel",
"getShellSessionHandoffPackageRenderState",
"getShellSessionHandoffPackageMountState",
"getShellSessionHandoffPackageMountDisplayViewModel",
"getShellSessionHandoffPackageMountRenderState",
"getShellSessionHandoffMountDomContract",
"getShellSessionHandoffMountDomReadiness",
"renderShellSessionHandoffMountState",
"mountShellSessionHandoff",
"mountShellSessionHandoffFromControlPage",
"readShellSessionHandoffStatusFromControlPage",
"getMachineSessionPersistenceSummary",
"getShellSessionHandoffWorkflowSummary",
"getShellSessionReadinessWorkflowReport",
"getShellApiSurfaceInventory",
"getShellSessionHandoffWorkflowDisplayViewModel",
"getShellSessionHandoffWorkflowRenderState",
"getShellSessionHandoffWorkflowDomContract",
"getShellSessionHandoffWorkflowDomReadiness",
"renderShellSessionHandoffWorkflowState",
"mountShellSessionHandoffWorkflow",
"getWorkflowOverviewContract",
"getWorkflowOverviewReadiness",
"mountWorkflowOverviewEmbedding",
"runWorkflowOverviewReleaseReadinessArtifactJsonWorkflow",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
"mountWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
"loadWorkflowOverviewReleaseReadinessArtifactUrl",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
"mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
"getWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
"mountWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
"mountWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
"getWorkflowOverviewEmbeddingReport",
"getWorkflowOverviewEmbeddingDisplayViewModel",
"getWorkflowOverviewEmbeddingRenderState",
"getWorkflowOverviewEmbeddingDomContract",
"getWorkflowOverviewEmbeddingDomReadiness",
"renderWorkflowOverviewEmbeddingState",
"mountWorkflowOverviewEmbeddingState",
"getWorkflowOverviewEmbeddingMountDisplayViewModel",
"getWorkflowOverviewEmbeddingMountRenderState",
"getWorkflowOverviewEmbeddingMountDomContract",
"getWorkflowOverviewEmbeddingMountDomReadiness",
"renderWorkflowOverviewEmbeddingMountState",
"mountWorkflowOverviewEmbeddingMountState",
"isSupportedShellSessionHandoffPackage",
"getLauncherLinks",
"getControlPageApiMethods",
],
visibleEntries: entries.map(({ id, href, title }) => ({
id,
href,
title,
})),
targetPages: entries.map(({ id, href }) => ({
entryId: id,
href,
})),
controlPageApiMethods: createControlPageBrowserApiMethods(),
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",
},
],
};
}
export function createIniPanelShellControlPageContract() {
const readonlyStatusApiManifest = createMachineSessionReadonlyStatusApiManifest();
return {
methodNames: [
"createController",
"loadSessionState",
"readStatus",
"refresh",
"renderView",
],
readonlyStatusApiManifest,
readonlyStatusApiMethodNames: Object.keys(readonlyStatusApiManifest.methods),
readonlyStatusApiStatusFields: readonlyStatusApiManifest.statusFields,
relatedControlPageMethods: readonlyStatusApiManifest.relatedControlPageMethods,
};
}
export function createControlPageBrowserApiMethods() {
return [
"isSupportedControlPageApiManifest",
"getControlPageApiSchema",
"getControlPageApiManifest",
"getControlPageApiMethods",
"getControlPageContract",
"getControlView",
"getPanelApi",
"loadControlPageSessionState",
"readControlPageStatus",
"refreshControlPage",
"renderControlPage",
];
}
export function createControlPageBrowserApiManifest() {
const schema = createControlPageBrowserApiSchema();
const contract = createIniPanelShellControlPageContract();
return {
apiName: schema.apiName,
manifestVersion: schema.manifestVersion,
methods: createControlPageBrowserApiMethods(),
contract,
readonlyStatusApiManifest: contract.readonlyStatusApiManifest,
};
}
export function createIniPanelShellIntegrationSchema() {
return {
apiName: "ini-panel-shell-integration",
manifestVersion: 1,
fields: [
"apiName",
"manifestVersion",
"pages",
"launcherLinks",
"launchApiSchema",
"launchApiManifest",
"controlPageApiSchema",
"controlPageApiManifest",
"compatibility",
"persistenceCapabilities",
],
};
}
export function isSupportedIniPanelShellIntegrationManifest(
manifest,
schema = createIniPanelShellIntegrationSchema(),
) {
if (!manifest || typeof manifest !== "object") {
return false;
}
if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) {
return false;
}
return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName));
}
export function createIniPanelShellIntegrationManifest(entries = getVisibleIniPanelEntries()) {
const schema = createIniPanelShellIntegrationSchema();
const launchApiSchema = createIniPanelLaunchApiSchema();
const launchApiManifest = createIniPanelLaunchApiManifest(entries);
const controlPageApiSchema = createControlPageBrowserApiSchema();
const controlPageApiManifest = createControlPageBrowserApiManifest();
return {
apiName: schema.apiName,
manifestVersion: schema.manifestVersion,
pages: entries.map(({ id, href, title }) => ({
id,
href,
title,
})),
launcherLinks: createIniPanelLauncherLinkViewModel(entries),
launchApiSchema,
launchApiManifest,
controlPageApiSchema,
controlPageApiManifest,
compatibility: {
launchApiManifest: isSupportedIniPanelLaunchApiManifest(launchApiManifest, launchApiSchema),
controlPageApiManifest: isSupportedIniPanelControlPageApiManifest(
controlPageApiManifest,
controlPageApiSchema,
),
},
persistenceCapabilities: launchApiManifest.persistenceCapabilities,
};
}
export function createIniPanelShellIntegrationReadiness(
manifest = createIniPanelShellIntegrationManifest(),
) {
const integrationManifestSupported = isSupportedIniPanelShellIntegrationManifest(manifest);
const launchApiManifestSupported = integrationManifestSupported
&& isSupportedIniPanelLaunchApiManifest(manifest.launchApiManifest, manifest.launchApiSchema);
const controlPageApiManifestSupported = integrationManifestSupported
&& isSupportedIniPanelControlPageApiManifest(
manifest.controlPageApiManifest,
manifest.controlPageApiSchema,
);
const compatibility = integrationManifestSupported && manifest.compatibility
? {
launchApiManifest: Boolean(manifest.compatibility.launchApiManifest),
controlPageApiManifest: Boolean(manifest.compatibility.controlPageApiManifest),
}
: {
launchApiManifest: false,
controlPageApiManifest: false,
};
const checks = {
integrationManifestSupported,
launchApiManifestSupported,
controlPageApiManifestSupported,
launchCompatibility: compatibility.launchApiManifest,
controlPageCompatibility: compatibility.controlPageApiManifest,
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
phase: ready ? "ready" : "blocked",
ready,
checks,
missing,
counts: {
pages: Array.isArray(manifest?.pages) ? manifest.pages.length : 0,
launcherLinks: Array.isArray(manifest?.launcherLinks) ? manifest.launcherLinks.length : 0,
launchMethods: Array.isArray(manifest?.launchApiManifest?.methods)
? manifest.launchApiManifest.methods.length
: 0,
controlPageMethods: Array.isArray(manifest?.controlPageApiManifest?.methods)
? manifest.controlPageApiManifest.methods.length
: 0,
persistenceCapabilities: Array.isArray(manifest?.persistenceCapabilities)
? manifest.persistenceCapabilities.length
: 0,
},
apiNames: {
integration: manifest?.apiName ?? null,
launch: manifest?.launchApiManifest?.apiName ?? null,
controlPage: manifest?.controlPageApiManifest?.apiName ?? null,
},
};
}
export function createIniPanelShellIntegrationWorkflowPlan({
manifest = createIniPanelShellIntegrationManifest(),
readiness = createIniPanelShellIntegrationReadiness(manifest),
controlEntryId = "control-view",
} = {}) {
const targetPage = manifest?.launchApiManifest?.targetPages?.find(
(page) => page.entryId === controlEntryId,
) ?? null;
const requiredLaunchApiMethods = [
"getShellIntegrationManifest",
"getShellIntegrationReadiness",
];
const requiredControlPageApiMethods = [
"getControlPageApiManifest",
"loadControlPageSessionState",
"readControlPageStatus",
];
const launchMethods = Array.isArray(manifest?.launchApiManifest?.methods)
? manifest.launchApiManifest.methods
: [];
const controlPageMethods = Array.isArray(manifest?.controlPageApiManifest?.methods)
? manifest.controlPageApiManifest.methods
: [];
const missingLaunchApiMethods = requiredLaunchApiMethods.filter(
(methodName) => !launchMethods.includes(methodName),
);
const missingControlPageApiMethods = requiredControlPageApiMethods.filter(
(methodName) => !controlPageMethods.includes(methodName),
);
const missing = [
...readiness.missing,
...(targetPage ? [] : ["controlTargetPage"]),
...missingLaunchApiMethods.map((methodName) => `launchApi.${methodName}`),
...missingControlPageApiMethods.map((methodName) => `controlPageApi.${methodName}`),
];
const ready = readiness.ready && missing.length === 0;
return {
phase: ready ? "ready" : "blocked",
ready,
controlEntryId,
targetPage,
readiness,
requiredLaunchApiMethods,
requiredControlPageApiMethods,
missingLaunchApiMethods,
missingControlPageApiMethods,
missing,
readonlyStatusHandoff: {
loadSessionStateMethod: "loadControlPageSessionState",
readStatusMethod: "readControlPageStatus",
expectedStatusFields: manifest?.controlPageApiManifest?.readonlyStatusApiManifest?.statusFields ?? [],
},
};
}
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 }))
: [];
const readonlyStatusFields = Array.isArray(workflowPlan?.readonlyStatusHandoff?.expectedStatusFields)
? [...workflowPlan.readonlyStatusHandoff.expectedStatusFields]
: [];
return {
apiName: schema.apiName,
summaryVersion: schema.summaryVersion,
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 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 createIniPanelShellSessionHandoffRenderState(
snapshot = createIniPanelShellSessionHandoffSnapshot(),
) {
const displayViewModel = snapshot?.displayViewModel && typeof snapshot.displayViewModel === "object"
? snapshot.displayViewModel
: createIniPanelShellSessionHandoffDisplayViewModel(snapshot?.compatibilityReport);
const rows = Array.isArray(displayViewModel.rows)
? displayViewModel.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const ready = snapshot?.ready === true && displayViewModel.phase === "ready";
const statusText = displayViewModel.statusText ?? (ready ? "Ready" : "Blocked");
const detailText = displayViewModel.detailText ?? "No blocking reasons";
return {
apiName: "ini-panel-shell-session-handoff-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel.title ?? "Shell handoff compatibility",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
},
};
}
export function createIniPanelShellSessionHandoffActionPlan({
snapshot = createIniPanelShellSessionHandoffSnapshot(),
renderState = createIniPanelShellSessionHandoffRenderState(snapshot),
} = {}) {
const summary = snapshot?.summary && typeof snapshot.summary === "object" ? snapshot.summary : {};
const handoffMethods = summary.handoffMethods && typeof summary.handoffMethods === "object"
? summary.handoffMethods
: {};
const blockingReasons = Array.isArray(summary.blockingReasons)
? [...summary.blockingReasons]
: [];
const displayRows = Array.isArray(renderState?.rows) ? renderState.rows.map(({ id, label, value }) => ({
id,
label,
value,
})) : [];
const ready = snapshot?.ready === true && renderState?.ready === true && blockingReasons.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-action-plan",
planVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
statusLine: renderState?.statusLine ?? "Blocked: No handoff render state",
targetPage: summary.targetPage ?? null,
requiredMethods: {
loadSessionState: handoffMethods.loadSessionState ?? null,
readStatus: handoffMethods.readStatus ?? null,
},
blockingReasons,
displayRows,
nextSteps: ready
? [
{
id: "open-control-page",
label: "Open control page target",
targetPage: summary.targetPage ?? null,
},
{
id: "read-readonly-status",
label: "Read readonly status",
methods: {
loadSessionState: handoffMethods.loadSessionState ?? null,
readStatus: handoffMethods.readStatus ?? null,
},
},
]
: [
{
id: "resolve-blockers",
label: "Resolve handoff blockers",
blockingReasons,
displayRows,
},
],
};
}
export function createIniPanelShellSessionHandoffChecklist({
actionPlan = createIniPanelShellSessionHandoffActionPlan(),
renderState = createIniPanelShellSessionHandoffRenderState(),
} = {}) {
const displayRows = Array.isArray(actionPlan?.displayRows)
? actionPlan.displayRows.map(({ id, label, value }) => ({ id, label, value }))
: [];
const blockingReasons = Array.isArray(actionPlan?.blockingReasons)
? [...actionPlan.blockingReasons]
: [];
const targetPageReady = Boolean(actionPlan?.targetPage?.href);
const loadMethodReady = Boolean(actionPlan?.requiredMethods?.loadSessionState);
const readMethodReady = Boolean(actionPlan?.requiredMethods?.readStatus);
const ready = actionPlan?.ready === true
&& renderState?.ready === true
&& targetPageReady
&& loadMethodReady
&& readMethodReady
&& blockingReasons.length === 0;
const checks = [
{
id: "render-state",
label: "Render state",
status: renderState?.ready ? "pass" : "blocked",
value: renderState?.statusLine ?? "missing",
},
{
id: "target-page",
label: "Control target",
status: targetPageReady ? "pass" : "blocked",
value: actionPlan?.targetPage?.href ?? "missing",
},
{
id: "load-session-method",
label: "Load session method",
status: loadMethodReady ? "pass" : "blocked",
value: actionPlan?.requiredMethods?.loadSessionState ?? "missing",
},
{
id: "read-status-method",
label: "Read status method",
status: readMethodReady ? "pass" : "blocked",
value: actionPlan?.requiredMethods?.readStatus ?? "missing",
},
{
id: "blocking-reasons",
label: "Blocking reasons",
status: blockingReasons.length === 0 ? "pass" : "blocked",
value: blockingReasons.length === 0 ? "none" : blockingReasons.join(", "),
},
];
return {
apiName: "ini-panel-shell-session-handoff-checklist",
checklistVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
statusLine: actionPlan?.statusLine ?? renderState?.statusLine ?? "Blocked: No handoff action plan",
checks,
displayRows,
nextStepIds: Array.isArray(actionPlan?.nextSteps)
? actionPlan.nextSteps.map(({ id }) => id)
: [],
blockingReasons,
};
}
export function createIniPanelShellSessionHandoffPackage({
shellIntegrationManifest = createIniPanelShellIntegrationManifest(),
launchApiManifest = shellIntegrationManifest.launchApiManifest ?? createIniPanelLaunchApiManifest(),
controlPageApiManifest = shellIntegrationManifest.controlPageApiManifest ?? createControlPageBrowserApiManifest(),
snapshot = createIniPanelShellSessionHandoffSnapshot(),
renderState = createIniPanelShellSessionHandoffRenderState(snapshot),
actionPlan = createIniPanelShellSessionHandoffActionPlan({ snapshot, renderState }),
checklist = createIniPanelShellSessionHandoffChecklist({ actionPlan, renderState }),
} = {}) {
return {
apiName: "ini-panel-shell-session-handoff-package",
packageVersion: 1,
phase: checklist.phase,
ready: Boolean(checklist.ready),
statusLine: checklist.statusLine,
manifests: {
shellIntegration: shellIntegrationManifest,
launchApi: launchApiManifest,
controlPageApi: controlPageApiManifest,
launchMethods: Array.isArray(launchApiManifest?.methods) ? [...launchApiManifest.methods] : [],
controlPageMethods: Array.isArray(controlPageApiManifest?.methods) ? [...controlPageApiManifest.methods] : [],
},
snapshot,
renderState,
actionPlan,
checklist,
};
}
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 createIniPanelShellSessionHandoffPackageReport(
handoffPackage = createIniPanelShellSessionHandoffPackage(),
schema = createIniPanelShellSessionHandoffPackageSchema(),
) {
const packageObject = handoffPackage && typeof handoffPackage === "object" ? handoffPackage : {};
const manifests = packageObject.manifests && typeof packageObject.manifests === "object"
? packageObject.manifests
: {};
const missingPackageFields = schema.fields.filter((fieldName) => !Object.hasOwn(packageObject, fieldName));
const missingManifestFields = schema.manifestFields.filter((fieldName) => !Object.hasOwn(manifests, fieldName));
const mismatchFields = [
...(packageObject.apiName === schema.apiName ? [] : ["apiName"]),
...(packageObject.packageVersion === schema.packageVersion ? [] : ["packageVersion"]),
];
const blockingReasons = Array.isArray(packageObject?.checklist?.blockingReasons)
? [...packageObject.checklist.blockingReasons]
: [];
const packageSupported = missingPackageFields.length === 0
&& missingManifestFields.length === 0
&& mismatchFields.length === 0;
const ready = packageSupported && packageObject.ready === true && blockingReasons.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-package-report",
reportVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
packageSupported,
packageReady: ready,
statusLine: packageObject.statusLine ?? (ready ? "Ready: No blocking reasons" : "Blocked: Package unsupported"),
schema: {
apiName: schema.apiName,
packageVersion: schema.packageVersion,
fields: [...schema.fields],
manifestFields: [...schema.manifestFields],
},
package: {
apiName: packageObject.apiName ?? null,
packageVersion: packageObject.packageVersion ?? null,
phase: packageObject.phase ?? null,
ready: packageObject.ready ?? false,
},
missingPackageFields,
missingManifestFields,
mismatchFields,
blockingReasons,
rows: [
{
id: "package-supported",
label: "Package schema",
value: packageSupported ? "supported" : "blocked",
},
{
id: "package-ready",
label: "Package readiness",
value: ready ? "ready" : "blocked",
},
{
id: "missing-package-fields",
label: "Missing package fields",
value: missingPackageFields.length === 0 ? "none" : missingPackageFields.join(", "),
},
{
id: "missing-manifest-fields",
label: "Missing manifest fields",
value: missingManifestFields.length === 0 ? "none" : missingManifestFields.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 createIniPanelShellSessionHandoffPackageDisplayViewModel(
report = createIniPanelShellSessionHandoffPackageReport(),
) {
const missingPackageFields = Array.isArray(report?.missingPackageFields) ? report.missingPackageFields : [];
const missingManifestFields = Array.isArray(report?.missingManifestFields) ? report.missingManifestFields : [];
const mismatchFields = Array.isArray(report?.mismatchFields) ? report.mismatchFields : [];
const blockingReasons = Array.isArray(report?.blockingReasons) ? report.blockingReasons : [];
const problems = [
...missingPackageFields,
...missingManifestFields,
...mismatchFields,
...blockingReasons,
];
return {
phase: report?.phase === "ready" ? "ready" : "blocked",
title: "Shell handoff package",
statusText: report?.ready ? "Ready" : "Blocked",
detailText: problems.length === 0 ? "No blocking reasons" : problems.join(", "),
rows: Array.isArray(report?.rows)
? report.rows.map(({ id, label, value }) => ({
id,
label,
value,
}))
: [],
};
}
export function createIniPanelShellSessionHandoffPackageRenderState(
displayViewModel = createIniPanelShellSessionHandoffPackageDisplayViewModel(),
) {
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-package-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Shell handoff package",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "package",
},
};
}
export function createIniPanelShellSessionHandoffPackageMountState({
handoffPackage = createIniPanelShellSessionHandoffPackage(),
packageRenderState = createIniPanelShellSessionHandoffPackageRenderState(),
sessionLoadState = createControlPageSessionLoadState({ phase: "waiting-panel" }),
} = {}) {
const actionPlan = handoffPackage?.actionPlan && typeof handoffPackage.actionPlan === "object"
? handoffPackage.actionPlan
: {};
const requiredMethods = actionPlan.requiredMethods && typeof actionPlan.requiredMethods === "object"
? actionPlan.requiredMethods
: {};
const targetPage = actionPlan.targetPage ?? null;
const blockingReasons = [
...(Array.isArray(actionPlan.blockingReasons) ? actionPlan.blockingReasons : []),
...(sessionLoadState?.phase === "error" ? ["controlPageSessionError"] : []),
];
const packageReady = handoffPackage?.ready === true && packageRenderState?.ready === true;
const targetReady = Boolean(targetPage?.href);
const methodsReady = Boolean(requiredMethods.loadSessionState && requiredMethods.readStatus);
const sessionReady = sessionLoadState?.phase === "ready";
const ready = packageReady && targetReady && methodsReady && sessionReady && blockingReasons.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-package-mount-state",
mountStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
packageReady,
targetReady,
methodsReady,
sessionReady,
statusLine: ready
? "Ready: Control page session mounted"
: `Blocked: ${blockingReasons.length === 0 ? sessionLoadState?.phase ?? "waiting-panel" : blockingReasons.join(", ")}`,
packageRenderState,
targetPage,
requiredMethods: {
loadSessionState: requiredMethods.loadSessionState ?? null,
readStatus: requiredMethods.readStatus ?? null,
},
sessionLoadState,
blockingReasons,
checks: [
{
id: "package-render-state",
label: "Package render state",
status: packageReady ? "pass" : "blocked",
value: packageRenderState?.statusLine ?? "missing",
},
{
id: "target-page",
label: "Control target",
status: targetReady ? "pass" : "blocked",
value: targetPage?.href ?? "missing",
},
{
id: "required-methods",
label: "Readonly methods",
status: methodsReady ? "pass" : "blocked",
value: methodsReady
? `${requiredMethods.loadSessionState}, ${requiredMethods.readStatus}`
: "missing",
},
{
id: "session-load-state",
label: "Session load state",
status: sessionReady ? "pass" : "blocked",
value: sessionLoadState?.phase ?? "missing",
},
{
id: "blocking-reasons",
label: "Blocking reasons",
status: blockingReasons.length === 0 ? "pass" : "blocked",
value: blockingReasons.length === 0 ? "none" : blockingReasons.join(", "),
},
],
};
}
export function createIniPanelShellSessionHandoffPackageMountDisplayViewModel(
mountState = createIniPanelShellSessionHandoffPackageMountState(),
) {
const checks = Array.isArray(mountState?.checks) ? mountState.checks : [];
const blockingChecks = checks.filter(({ status }) => status !== "pass");
const blockingReasons = Array.isArray(mountState?.blockingReasons) ? mountState.blockingReasons : [];
const problems = [
...blockingReasons,
...blockingChecks.map(({ id }) => id),
];
return {
phase: mountState?.phase === "ready" ? "ready" : "blocked",
title: "Shell handoff mount",
statusText: mountState?.ready ? "Ready" : "Blocked",
detailText: problems.length === 0 ? "No blocking reasons" : problems.join(", "),
rows: checks.map(({ id, label, status, value }) => ({
id,
label,
value,
status,
})),
};
}
export function createIniPanelShellSessionHandoffPackageMountRenderState(
displayViewModel = createIniPanelShellSessionHandoffPackageMountDisplayViewModel(),
) {
const rows = Array.isArray(displayViewModel?.rows)
? displayViewModel.rows.map(({ id, label, value, status }) => ({
id,
label,
value: value == null ? "" : String(value),
status: status ?? "blocked",
}))
: [];
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-package-mount-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Shell handoff mount",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "mount",
},
};
}
export function createIniPanelShellSessionHandoffMountDomContract({
rowDatasetPrefix = "handoffMount",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-handoff-mount]";
const statusSelector = selectors.status ?? "[data-handoff-mount-status]";
const rowsSelector = selectors.rows ?? "[data-handoff-mount-rows]";
return {
apiName: "ini-panel-shell-session-handoff-mount-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellSessionHandoffMountDomReadiness({
rowDatasetPrefix = "handoffMount",
contract = createIniPanelShellSessionHandoffMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-mount-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellSessionHandoffMountState(
renderState = createIniPanelShellSessionHandoffPackageMountRenderState(),
{
rowDatasetPrefix = "handoffMount",
contract = createIniPanelShellSessionHandoffMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellSessionHandoffMountDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Shell handoff mount DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope ?? "mount";
statusNode.textContent = renderState?.statusLine ?? "Blocked: No mount render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = row.status;
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = row.status;
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellSessionHandoff({
renderState = createIniPanelShellSessionHandoffPackageMountRenderState(),
rowDatasetPrefix = "handoffMount",
contract = createIniPanelShellSessionHandoffMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellSessionHandoffMountDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-session-handoff-mount-workflow",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellSessionHandoffMountState(renderState, {
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-session-handoff-mount-workflow",
workflowVersion: 1,
phase: renderState?.ready ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-session-handoff-mount-workflow",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "mount workflow error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function mountIniPanelShellSessionHandoffFromControlPage({
controlPageApi = null,
sessionLoadState = null,
loadSessionStateMethod = "loadControlPageSessionState",
handoffPackage = createIniPanelShellSessionHandoffPackage(),
packageRenderState = createIniPanelShellSessionHandoffPackageRenderState(),
rowDatasetPrefix = "handoffMount",
contract = createIniPanelShellSessionHandoffMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
let observedSessionLoadState = sessionLoadState;
let sessionLoadError = null;
if (!observedSessionLoadState) {
const loadSessionState = controlPageApi?.[loadSessionStateMethod];
if (typeof loadSessionState === "function") {
try {
observedSessionLoadState = loadSessionState.call(controlPageApi);
} catch (error) {
sessionLoadError = error?.message ?? String(error);
observedSessionLoadState = createControlPageSessionLoadState({
phase: "error",
error: sessionLoadError,
});
}
} else {
observedSessionLoadState = createControlPageSessionLoadState({ phase: "waiting-api" });
}
}
const mountState = createIniPanelShellSessionHandoffPackageMountState({
handoffPackage,
packageRenderState,
sessionLoadState: observedSessionLoadState,
});
const mountDisplayViewModel = createIniPanelShellSessionHandoffPackageMountDisplayViewModel(mountState);
const mountRenderState = createIniPanelShellSessionHandoffPackageMountRenderState(mountDisplayViewModel);
const mountWorkflow = mountIniPanelShellSessionHandoff({
renderState: mountRenderState,
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-session-handoff-control-page-mount-workflow",
workflowVersion: 1,
phase: mountWorkflow.phase,
ready: mountWorkflow.ready,
statusLine: mountWorkflow.statusLine,
loadSessionStateMethod,
sessionLoadState: observedSessionLoadState,
sessionLoadError,
mountState,
mountDisplayViewModel,
mountRenderState,
mountWorkflow,
};
}
export function readIniPanelShellSessionHandoffStatusFromControlPage({
controlPageApi = null,
readonlyStatus = null,
readStatusMethod = "readControlPageStatus",
handoffSummary = createIniPanelShellSessionHandoffSummary(),
expectedStatusFields = handoffSummary?.readonlyStatusFields ?? [],
} = {}) {
let observedStatus = readonlyStatus;
let readError = null;
if (!observedStatus) {
const readStatus = controlPageApi?.[readStatusMethod];
if (typeof readStatus === "function") {
try {
observedStatus = readStatus.call(controlPageApi);
} catch (error) {
readError = error?.message ?? String(error);
observedStatus = null;
}
} else {
readError = `Missing ${readStatusMethod}`;
observedStatus = null;
}
}
const statusObject = observedStatus && typeof observedStatus === "object" ? observedStatus : {};
const expectedFields = Array.isArray(expectedStatusFields) ? [...expectedStatusFields] : [];
const presentStatusFields = expectedFields.filter((fieldName) => Object.hasOwn(statusObject, fieldName));
const missingStatusFields = expectedFields.filter((fieldName) => !Object.hasOwn(statusObject, fieldName));
const ready = !readError && missingStatusFields.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-readonly-status-result",
resultVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
statusLine: ready
? "Ready: readonly status fields available"
: `Blocked: ${readError ?? missingStatusFields.join(", ")}`,
readStatusMethod,
expectedStatusFields: expectedFields,
presentStatusFields,
missingStatusFields,
readonlyStatus: observedStatus,
readError,
};
}
export function createIniPanelShellSessionHandoffWorkflowSummary({
mountWorkflow = {
phase: "blocked",
ready: false,
statusLine: "Blocked: mount workflow unavailable",
},
controlPageMountWorkflow = {
phase: "blocked",
ready: false,
statusLine: "Blocked: control-page mount workflow unavailable",
},
readonlyStatusResult = {
phase: "blocked",
ready: false,
statusLine: "Blocked: readonly status unavailable",
missingStatusFields: [],
},
persistenceSummary = null,
apiSurfaceInventory = null,
} = {}) {
const sessionReadiness = readonlyStatusResult?.readonlyStatus?.sessionReadiness ?? null;
const sessionReadinessMissing = Array.isArray(sessionReadiness?.missing)
? [...sessionReadiness.missing]
: [];
const sessionReadinessValue = sessionReadiness
? `${sessionReadiness.ready ? "ready" : "blocked"}${
sessionReadinessMissing.length > 0 ? `: ${sessionReadinessMissing.join(", ")}` : ""
}`
: "missing";
const blockingReasons = [];
if (mountWorkflow?.ready !== true) {
blockingReasons.push(`mount:${mountWorkflow?.phase ?? "blocked"}`);
}
if (controlPageMountWorkflow?.ready !== true) {
blockingReasons.push(`control-page-mount:${controlPageMountWorkflow?.phase ?? "blocked"}`);
}
if (readonlyStatusResult?.ready !== true) {
const readonlyDetail = readonlyStatusResult?.readError
?? (
Array.isArray(readonlyStatusResult?.missingStatusFields)
&& readonlyStatusResult.missingStatusFields.length > 0
? readonlyStatusResult.missingStatusFields.join(", ")
: readonlyStatusResult?.phase ?? "blocked"
);
blockingReasons.push(`readonly-status:${readonlyDetail}`);
}
const ready = blockingReasons.length === 0;
const apiSurfaceRows = Array.isArray(apiSurfaceInventory?.rows)
? apiSurfaceInventory.rows
: [];
const apiSurfaceValue = apiSurfaceInventory
? (
apiSurfaceInventory.ready
? `ready: ${apiSurfaceRows.length} rows`
: `blocked: ${apiSurfaceInventory.phase ?? "unknown"}`
)
: "missing";
const apiSurfaceCounts = apiSurfaceInventory?.counts && typeof apiSurfaceInventory.counts === "object"
? { ...apiSurfaceInventory.counts }
: null;
const persistenceRows = Array.isArray(persistenceSummary?.rows)
? persistenceSummary.rows
: [];
const persistenceMissing = Array.isArray(persistenceSummary?.missing)
? persistenceSummary.missing
: [];
const persistenceValue = persistenceSummary
? (
persistenceSummary.ready
? `ready: ${persistenceRows.length} rows`
: `${persistenceSummary.phase ?? "waiting"}: ${persistenceMissing.length} missing`
)
: "missing";
return {
apiName: "ini-panel-shell-session-handoff-workflow-summary",
summaryVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
statusLine: ready
? "Ready: shell handoff end-to-end workflow available"
: `Blocked: ${blockingReasons.join("; ")}`,
mountWorkflow: {
phase: mountWorkflow?.phase ?? "blocked",
ready: mountWorkflow?.ready === true,
statusLine: mountWorkflow?.statusLine ?? null,
},
controlPageMountWorkflow: {
phase: controlPageMountWorkflow?.phase ?? "blocked",
ready: controlPageMountWorkflow?.ready === true,
statusLine: controlPageMountWorkflow?.statusLine ?? null,
},
readonlyStatusResult: {
phase: readonlyStatusResult?.phase ?? "blocked",
ready: readonlyStatusResult?.ready === true,
statusLine: readonlyStatusResult?.statusLine ?? null,
missingStatusFields: Array.isArray(readonlyStatusResult?.missingStatusFields)
? [...readonlyStatusResult.missingStatusFields]
: [],
},
sessionReadiness: sessionReadiness
? {
phase: sessionReadiness.phase ?? (sessionReadiness.ready ? "ready" : "blocked"),
ready: sessionReadiness.ready === true,
missing: sessionReadinessMissing,
}
: null,
apiSurfaceInventory: apiSurfaceInventory
? {
phase: apiSurfaceInventory.phase ?? (apiSurfaceInventory.ready ? "ready" : "blocked"),
ready: apiSurfaceInventory.ready === true,
counts: apiSurfaceCounts,
apiNames: apiSurfaceInventory.apiNames ? { ...apiSurfaceInventory.apiNames } : null,
}
: null,
persistenceSummary: persistenceSummary
? {
phase: persistenceSummary.phase ?? (persistenceSummary.ready ? "ready" : "waiting"),
ready: persistenceSummary.ready === true,
counts: persistenceSummary.counts ? { ...persistenceSummary.counts } : null,
missing: persistenceMissing,
}
: null,
blockingReasons,
rows: [
{
id: "mount-workflow",
label: "Mount workflow",
value: mountWorkflow?.statusLine ?? "missing",
},
{
id: "control-page-mount-workflow",
label: "Control-page mount workflow",
value: controlPageMountWorkflow?.statusLine ?? "missing",
},
{
id: "readonly-status-workflow",
label: "Readonly status workflow",
value: readonlyStatusResult?.statusLine ?? "missing",
},
{
id: "session-readiness",
label: "Session readiness",
value: sessionReadinessValue,
},
{
id: "readonly-status-missing-fields",
label: "Readonly missing fields",
value: Array.isArray(readonlyStatusResult?.missingStatusFields)
&& readonlyStatusResult.missingStatusFields.length > 0
? readonlyStatusResult.missingStatusFields.join(", ")
: "none",
},
{
id: "persistence-summary",
label: "Persistence summary",
value: persistenceValue,
},
{
id: "api-surface-inventory",
label: "API surface inventory",
value: apiSurfaceValue,
},
{
id: "blocking-reasons",
label: "Blocking reasons",
value: blockingReasons.length > 0 ? blockingReasons.join("; ") : "none",
},
],
};
}
export function createIniPanelShellSessionHandoffWorkflowDisplayViewModel(
workflowSummary = createIniPanelShellSessionHandoffWorkflowSummary(),
) {
const blockingReasons = Array.isArray(workflowSummary?.blockingReasons)
? workflowSummary.blockingReasons
: [];
return {
phase: workflowSummary?.phase === "ready" ? "ready" : "blocked",
title: "Shell handoff workflow",
statusText: workflowSummary?.ready ? "Ready" : "Blocked",
detailText: blockingReasons.length > 0 ? blockingReasons.join(", ") : "No blocking reasons",
rows: Array.isArray(workflowSummary?.rows)
? workflowSummary.rows.map(({ id, label, value }) => ({
id,
label,
value,
}))
: [],
};
}
export function createIniPanelShellSessionReadinessWorkflowReport({
workflowSummary = null,
readonlyStatusResult = null,
} = {}) {
const sessionReadiness = workflowSummary?.sessionReadiness
?? readonlyStatusResult?.readonlyStatus?.sessionReadiness
?? null;
const missing = Array.isArray(sessionReadiness?.missing)
? [...sessionReadiness.missing]
: [];
const ready = sessionReadiness?.ready === true;
const phase = sessionReadiness ? (ready ? "ready" : "blocked") : "blocked";
const statusLine = sessionReadiness
? (
ready
? "Ready: session readiness available"
: `Blocked: ${missing.length > 0 ? missing.join(", ") : "session readiness blocked"}`
)
: "Blocked: session readiness unavailable";
return {
apiName: "ini-panel-shell-session-readiness-workflow-report",
reportVersion: 1,
phase,
ready,
statusLine,
sessionReadiness: sessionReadiness
? {
phase: sessionReadiness.phase ?? phase,
ready,
missing,
}
: null,
missing,
rows: [
{
id: "session-readiness",
label: "Session readiness",
value: sessionReadiness ? (ready ? "ready" : "blocked") : "missing",
},
{
id: "session-readiness-phase",
label: "Session readiness phase",
value: sessionReadiness?.phase ?? "missing",
},
{
id: "session-readiness-missing",
label: "Session readiness missing",
value: missing.length > 0 ? missing.join(", ") : "none",
},
],
};
}
export function createIniPanelShellApiSurfaceInventory({
launchApiManifest = createIniPanelLaunchApiManifest(),
controlPageApiManifest = createControlPageBrowserApiManifest(),
workflowOverviewContract = createIniPanelShellWorkflowOverviewContract(),
sessionReadinessWorkflowReport = createIniPanelShellSessionReadinessWorkflowReport(),
persistenceSummary = createMachineSessionPersistenceSummary(),
} = {}) {
const launchMethods = Array.isArray(launchApiManifest?.methods) ? launchApiManifest.methods : [];
const controlPageMethods = Array.isArray(controlPageApiManifest?.methods) ? controlPageApiManifest.methods : [];
const workflowOverviewMethods = Array.isArray(workflowOverviewContract?.methodNames)
? workflowOverviewContract.methodNames
: [];
const persistenceCapabilities = Array.isArray(launchApiManifest?.persistenceCapabilities)
? launchApiManifest.persistenceCapabilities
: [];
const sessionReadinessRows = Array.isArray(sessionReadinessWorkflowReport?.rows)
? sessionReadinessWorkflowReport.rows
: [];
const persistenceSummaryRows = Array.isArray(persistenceSummary?.rows)
? persistenceSummary.rows
: [];
const ready = Boolean(
launchApiManifest?.apiName
&& controlPageApiManifest?.apiName
&& workflowOverviewContract?.apiName
&& sessionReadinessWorkflowReport?.apiName
&& persistenceSummary?.apiName,
);
return {
apiName: "ini-panel-shell-api-surface-inventory",
inventoryVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
counts: {
launchMethods: launchMethods.length,
controlPageMethods: controlPageMethods.length,
workflowOverviewMethods: workflowOverviewMethods.length,
persistenceCapabilities: persistenceCapabilities.length,
sessionReadinessRows: sessionReadinessRows.length,
persistenceSummaryRows: persistenceSummaryRows.length,
},
apiNames: {
launch: launchApiManifest?.apiName ?? null,
controlPage: controlPageApiManifest?.apiName ?? null,
workflowOverview: workflowOverviewContract?.apiName ?? null,
sessionReadinessReport: sessionReadinessWorkflowReport?.apiName ?? null,
persistenceSummary: persistenceSummary?.apiName ?? null,
},
entries: [
{
id: "launch-api",
label: "Launch API",
apiName: launchApiManifest?.apiName ?? null,
count: launchMethods.length,
},
{
id: "control-page-api",
label: "Control-page API",
apiName: controlPageApiManifest?.apiName ?? null,
count: controlPageMethods.length,
},
{
id: "workflow-overview-api",
label: "Workflow overview API",
apiName: workflowOverviewContract?.apiName ?? null,
count: workflowOverviewMethods.length,
},
{
id: "session-readiness-report",
label: "Session readiness report",
apiName: sessionReadinessWorkflowReport?.apiName ?? null,
count: sessionReadinessRows.length,
},
{
id: "persistence-summary",
label: "Persistence summary",
apiName: persistenceSummary?.apiName ?? null,
count: persistenceSummaryRows.length,
},
{
id: "persistence-capabilities",
label: "Persistence capabilities",
apiName: launchApiManifest?.apiName ?? null,
count: persistenceCapabilities.length,
},
],
rows: [
{
id: "launch-methods",
label: "Launch methods",
value: String(launchMethods.length),
},
{
id: "control-page-methods",
label: "Control-page methods",
value: String(controlPageMethods.length),
},
{
id: "workflow-overview-methods",
label: "Workflow overview methods",
value: String(workflowOverviewMethods.length),
},
{
id: "session-readiness-report",
label: "Session readiness report",
value: sessionReadinessWorkflowReport?.apiName ?? "missing",
},
{
id: "persistence-summary",
label: "Persistence summary",
value: persistenceSummary?.apiName ?? "missing",
},
{
id: "persistence-capabilities",
label: "Persistence capabilities",
value: String(persistenceCapabilities.length),
},
],
};
}
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 createIniPanelShellSessionHandoffWorkflowDomContract({
rowDatasetPrefix = "handoffWorkflow",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-handoff-workflow]";
const statusSelector = selectors.status ?? "[data-handoff-workflow-status]";
const rowsSelector = selectors.rows ?? "[data-handoff-workflow-rows]";
return {
apiName: "ini-panel-shell-session-handoff-workflow-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewContract() {
return {
pageHref: "./workflow-overview.html",
entryId: "workflow-overview",
apiName: "linuxCncIniPanelWorkflowOverviewApi",
methodNames: [
"getWorkflowOverviewRenderState",
"getWorkflowOverviewDisplayViewModel",
"getWorkflowOverviewSummary",
"getWorkflowOverviewSessionReadinessReport",
"getWorkflowOverviewApiSurfaceInventory",
"getWorkflowOverviewPersistenceSummary",
"validateWorkflowOverviewReleaseReadinessArtifactJson",
"runWorkflowOverviewReleaseReadinessArtifactJsonWorkflow",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract",
"getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
"mountWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
"loadWorkflowOverviewReleaseReadinessArtifactUrl",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
"mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
"getWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract",
"getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
"mountWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract",
"getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
"mountWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
"getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel",
"getWorkflowOverviewReleaseReadinessArtifactRenderState",
"getWorkflowOverviewReleaseReadinessArtifactDomContract",
"getWorkflowOverviewReleaseReadinessArtifactDomReadiness",
"renderWorkflowOverviewReleaseReadinessArtifactState",
"mountWorkflowOverviewReleaseReadinessArtifactState",
"getWorkflowOverviewDomContract",
"getWorkflowOverviewDomReadiness",
"renderWorkflowOverview",
"mountWorkflowOverview",
"createWorkflowOverviewRenderState",
],
};
}
export function validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(artifactJson) {
try {
const artifact = parseProjectReleaseReadinessArtifactJson(artifactJson);
const validation = createProjectReleaseReadinessArtifactValidation(artifact);
const actionPlan = createProjectReleaseReadinessArtifactValidationActionPlan(validation);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation",
validationVersion: 1,
phase: validation.ready ? "ready" : "blocked",
ready: validation.ready,
missing: [...validation.missing],
error: null,
artifactApiName: validation.artifactApiName,
artifactVersion: validation.artifactVersion,
gateCount: validation.gateCount,
validation,
gateExecutionSummaryViewModel: artifact.gateExecutionSummaryViewModel
?? createProjectReleaseGateExecutionSummaryViewModel(artifact.gateExecutionManifest),
actionPlan,
rows: [...validation.rows],
};
} catch (error) {
const actionPlan = createProjectReleaseReadinessArtifactValidationActionPlan(
createProjectReleaseReadinessArtifactValidation({}),
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation",
validationVersion: 1,
phase: "blocked",
ready: false,
missing: ["artifact-json"],
error: error?.message ?? "Unable to parse release readiness artifact JSON",
artifactApiName: null,
artifactVersion: null,
gateCount: 0,
validation: null,
gateExecutionSummaryViewModel: null,
actionPlan,
rows: [
{
id: "artifact-json",
label: "Readiness artifact JSON",
value: "blocked",
},
],
};
}
}
export function runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow({
artifactJson = "",
} = {}) {
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson });
const validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(artifactJson);
const validationSummaryViewModel =
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel(validation);
const gateExecutionSummaryViewModel =
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel(validation);
const actionPlan =
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan(validation);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow",
workflowVersion: 1,
phase: jsonWorkflow.ready ? "ready" : "blocked",
ready: jsonWorkflow.ready,
parsed: jsonWorkflow.parsed,
parseError: jsonWorkflow.parseError,
artifactApiName: jsonWorkflow.artifactApiName,
missing: [...jsonWorkflow.missing],
jsonWorkflow,
validation,
validationSummaryViewModel,
gateExecutionSummaryViewModel,
actionPlan,
rows: [
{
id: "parse",
label: "Artifact JSON parse",
value: jsonWorkflow.parsed ? "ready" : "blocked",
},
{
id: "validation-summary",
label: "Validation summary",
value: validationSummaryViewModel.statusLine,
},
{
id: "gate-execution-summary",
label: "Gate execution summary",
value: gateExecutionSummaryViewModel.statusLine,
},
{
id: "next-command",
label: "Next command",
value: actionPlan.nextCommand ?? "none",
},
],
statusLine: jsonWorkflow.ready
? "Ready: Artifact JSON workflow complete"
: `Blocked: ${jsonWorkflow.missing.join(", ")}`,
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel(
workflow = {},
) {
const missing = Array.isArray(workflow?.missing) ? workflow.missing : [];
const ready = workflow?.ready === true;
const statusText = ready ? "Ready" : "Blocked";
const detailText = ready
? "Artifact JSON workflow complete"
: (missing.length > 0 ? missing.join(", ") : workflow?.parseError ?? "artifact JSON workflow blocked");
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-summary-view-model",
viewModelVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Release artifact JSON workflow",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows: [
{
id: "parse",
label: "Artifact JSON parse",
value: workflow?.parsed === true ? "ready" : "blocked",
},
{
id: "validation-summary",
label: "Validation summary",
value: workflow?.validationSummaryViewModel?.statusLine ?? "missing",
},
{
id: "gate-execution-summary",
label: "Gate execution summary",
value: workflow?.gateExecutionSummaryViewModel?.statusLine ?? "missing",
},
{
id: "action-plan",
label: "Action plan",
value: workflow?.actionPlan?.ready === true
? "ready"
: (workflow?.actionPlan?.nextActionId ?? "missing"),
},
{
id: "missing",
label: "Missing workflow evidence",
value: missing.length > 0 ? missing.join(", ") : "none",
},
],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan(
workflow = {},
) {
return workflow?.actionPlan
?? createProjectReleaseReadinessArtifactValidationActionPlan(workflow?.validation?.validation);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState(
summaryViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel(),
) {
const rows = Array.isArray(summaryViewModel?.rows)
? summaryViewModel.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const ready = summaryViewModel?.phase === "ready" && summaryViewModel?.statusText === "Ready";
const statusText = summaryViewModel?.statusText ?? (ready ? "Ready" : "Blocked");
const detailText = summaryViewModel?.detailText ?? "artifact JSON workflow blocked";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: summaryViewModel?.title ?? "Release artifact JSON workflow",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact-json-workflow",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactJsonWorkflow",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-workflow-overview-release-readiness-artifact-json-workflow]";
const statusSelector = selectors.status
?? "[data-workflow-overview-release-readiness-artifact-json-workflow-status]";
const rowsSelector = selectors.rows
?? "[data-workflow-overview-release-readiness-artifact-json-workflow-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactJsonWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactJsonWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact JSON workflow DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact-json-workflow";
statusNode.textContent = renderState?.statusLine
?? "Blocked: No release readiness artifact JSON workflow render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactJsonWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState(
renderState,
{
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
},
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-json-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release readiness artifact JSON workflow DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export async function loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
artifactUrl = "",
fetchRef = globalThis.fetch,
mount = false,
mountOptions = {},
} = {}) {
const missing = [
...(artifactUrl ? [] : ["artifact-url"]),
...(typeof fetchRef === "function" ? [] : ["fetch"]),
];
if (missing.length > 0) {
const actionPlan = createProjectReleaseReadinessArtifactUrlWorkflowActionPlan({
ready: false,
missing,
});
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow",
workflowVersion: 1,
phase: "blocked",
ready: false,
artifactUrl,
httpStatus: null,
missing,
error: null,
validation: null,
validationSummaryViewModel: null,
gateExecutionSummaryViewModel: null,
actionPlan,
displayViewModel: null,
renderState: null,
mountResult: null,
statusLine: `Blocked: ${missing.join(", ")}`,
};
}
try {
const response = await fetchRef(artifactUrl);
const httpStatus = response?.status ?? null;
if (!response?.ok) {
const actionPlan = createProjectReleaseReadinessArtifactUrlWorkflowActionPlan({
ready: false,
missing: ["artifact-fetch"],
});
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow",
workflowVersion: 1,
phase: "blocked",
ready: false,
artifactUrl,
httpStatus,
missing: ["artifact-url"],
error: `HTTP ${httpStatus ?? "error"}`,
validation: null,
validationSummaryViewModel: null,
gateExecutionSummaryViewModel: null,
actionPlan,
displayViewModel: null,
renderState: null,
mountResult: null,
statusLine: `Blocked: HTTP ${httpStatus ?? "error"}`,
};
}
const artifactJson = await response.text();
const validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(artifactJson);
const gateExecutionSummaryViewModel =
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel(
validation,
);
const validationSummaryViewModel =
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel(
validation,
);
const displayViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(
validation,
);
const renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(
displayViewModel,
);
const mountResult = mount
? mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState({
renderState,
...mountOptions,
})
: null;
const mountMissing = mount && mountResult?.ready !== true
? (mountResult?.domReadiness?.missing ?? ["release-readiness-artifact-dom"])
: [];
const workflowMissing = [
...validation.missing,
...mountMissing,
];
const ready = validation.ready === true && (!mount || mountResult?.ready === true);
const validationActionPlan = createProjectReleaseReadinessArtifactValidationActionPlan(
validation.validation,
);
const actionPlan = createProjectReleaseReadinessArtifactUrlWorkflowActionPlan({
ready,
missing: workflowMissing,
actionPlan: validationActionPlan,
});
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow",
workflowVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
artifactUrl,
httpStatus,
missing: workflowMissing,
error: null,
validation,
validationSummaryViewModel,
gateExecutionSummaryViewModel,
actionPlan,
displayViewModel,
renderState,
mountResult,
statusLine: ready ? renderState.statusLine : `Blocked: ${workflowMissing.join(", ")}`,
};
} catch (error) {
const actionPlan = createProjectReleaseReadinessArtifactUrlWorkflowActionPlan({
ready: false,
missing: ["artifact-fetch"],
});
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow",
workflowVersion: 1,
phase: "blocked",
ready: false,
artifactUrl,
httpStatus: null,
missing: ["artifact-url"],
error: error?.message ?? String(error),
validation: null,
validationSummaryViewModel: null,
gateExecutionSummaryViewModel: null,
actionPlan,
displayViewModel: null,
renderState: null,
mountResult: null,
statusLine: `Blocked: ${error?.message ?? "release readiness artifact URL load error"}`,
};
}
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(
workflow = {},
) {
const missing = Array.isArray(workflow?.missing) ? workflow.missing : [];
const ready = workflow?.ready === true;
const statusText = ready ? "Ready" : "Blocked";
const detailText = ready
? "Artifact URL workflow complete"
: (missing.length > 0 ? missing.join(", ") : workflow?.error ?? "artifact URL workflow blocked");
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-summary-view-model",
viewModelVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Release artifact URL workflow",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows: [
{
id: "artifact-url",
label: "Artifact URL",
value: workflow?.artifactUrl || "missing",
},
{
id: "http-status",
label: "HTTP status",
value: workflow?.httpStatus == null ? "none" : String(workflow.httpStatus),
},
{
id: "validation-summary",
label: "Validation summary",
value: workflow?.validationSummaryViewModel?.statusLine ?? "missing",
},
{
id: "gate-execution-summary",
label: "Gate execution summary",
value: workflow?.gateExecutionSummaryViewModel?.statusLine ?? "missing",
},
{
id: "action-plan",
label: "Action plan",
value: workflow?.actionPlan?.ready === true
? "ready"
: (workflow?.actionPlan?.nextActionId ?? "missing"),
},
{
id: "render-state",
label: "Render state",
value: workflow?.renderState?.statusLine ?? "missing",
},
{
id: "mount-result",
label: "Mount result",
value: workflow?.mountResult
? (workflow.mountResult.ready ? "ready" : workflow.mountResult.statusLine)
: "not requested",
},
{
id: "missing",
label: "Missing workflow evidence",
value: missing.length > 0 ? missing.join(", ") : "none",
},
],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan(
workflow = {},
) {
return workflow?.actionPlan
?? createProjectReleaseReadinessArtifactUrlWorkflowActionPlan(workflow);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanRenderState(
actionPlan = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan(),
) {
const actionRows = Array.isArray(actionPlan?.rows)
? actionPlan.rows.map(({ id, label, value }) => ({
id: `action-${id}`,
label,
value: value == null ? "" : String(value),
}))
: [];
const ready = actionPlan?.ready === true;
const statusText = ready ? "Ready" : "Blocked";
const detailText = ready
? "Artifact URL workflow action plan complete"
: (actionPlan?.nextCommand ?? actionPlan?.nextActionId ?? "artifact URL workflow action required");
const rows = [
{
id: "action-count",
label: "Action count",
value: String(actionPlan?.actionCount ?? actionRows.length),
},
{
id: "next-action",
label: "Next action",
value: actionPlan?.nextActionId ?? "none",
},
{
id: "next-command",
label: "Next command",
value: actionPlan?.nextCommand ?? "none",
},
...actionRows,
];
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Release artifact URL workflow action plan",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
actionRows,
nextActionId: actionPlan?.nextActionId ?? null,
nextCommand: actionPlan?.nextCommand ?? null,
shellScript: actionPlan?.shellScript ?? "",
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact-url-workflow-action-plan",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
selectors = {},
} = {}) {
const mountSelector = selectors.mount
?? "[data-workflow-overview-release-readiness-artifact-url-workflow-action-plan]";
const statusSelector = selectors.status
?? "[data-workflow-overview-release-readiness-artifact-url-workflow-action-plan-status]";
const rowsSelector = selectors.rows
?? "[data-workflow-overview-release-readiness-artifact-url-workflow-action-plan-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact URL workflow action plan DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact-url-workflow-action-plan";
statusNode.textContent = renderState?.statusLine
?? "Blocked: No release artifact URL workflow action-plan render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlanState(
renderState,
{
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
},
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-action-plan-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release artifact URL workflow action-plan DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState(
summaryViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(),
) {
const rows = Array.isArray(summaryViewModel?.rows)
? summaryViewModel.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const ready = summaryViewModel?.phase === "ready" && summaryViewModel?.statusText === "Ready";
const statusText = summaryViewModel?.statusText ?? (ready ? "Ready" : "Blocked");
const detailText = summaryViewModel?.detailText ?? "artifact URL workflow blocked";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: summaryViewModel?.title ?? "Release artifact URL workflow",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact-url-workflow",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflow",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-workflow-overview-release-readiness-artifact-url-workflow]";
const statusSelector = selectors.status
?? "[data-workflow-overview-release-readiness-artifact-url-workflow-status]";
const rowsSelector = selectors.rows
?? "[data-workflow-overview-release-readiness-artifact-url-workflow-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact URL workflow DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact-url-workflow";
statusNode.textContent = renderState?.statusLine
?? "Blocked: No release readiness artifact URL workflow render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflow",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState(
renderState,
{
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
},
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release readiness artifact URL workflow DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan(
validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{}"),
) {
return validation?.actionPlan
?? createProjectReleaseReadinessArtifactValidationActionPlan(validation?.validation);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState(
actionPlan = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan(),
) {
const rows = Array.isArray(actionPlan?.rows)
? actionPlan.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const commandRows = Array.isArray(actionPlan?.commands)
? actionPlan.commands.map((command) => ({
id: `command-${command.id}`,
label: command.label ?? command.id,
value: command.command ?? "",
}))
: [];
const ready = actionPlan?.ready === true;
const statusText = ready ? "Ready" : "Blocked";
const detailText = ready
? "Artifact validation action plan complete"
: (actionPlan?.nextCommand ?? "artifact validation action required");
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Release artifact validation action plan",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows: [...rows, ...commandRows],
commandRows,
nextActionId: actionPlan?.nextActionId ?? null,
nextCommand: actionPlan?.nextCommand ?? null,
shellScript: actionPlan?.shellScript ?? "",
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact-validation-action-plan",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactValidationActionPlan",
selectors = {},
} = {}) {
const mountSelector = selectors.mount
?? "[data-workflow-overview-release-readiness-artifact-validation-action-plan]";
const statusSelector = selectors.status
?? "[data-workflow-overview-release-readiness-artifact-validation-action-plan-status]";
const rowsSelector = selectors.rows
?? "[data-workflow-overview-release-readiness-artifact-validation-action-plan-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactValidationActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactValidationActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact validation action plan DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact-validation-action-plan";
statusNode.textContent = renderState?.statusLine
?? "Blocked: No release artifact validation action-plan render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactValidationActionPlan",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState(
renderState,
{
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
},
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-validation-action-plan-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release artifact validation action-plan DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel(
validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{}"),
) {
if (validation?.gateExecutionSummaryViewModel) {
return validation.gateExecutionSummaryViewModel;
}
return createProjectReleaseGateExecutionSummaryViewModel(
validation?.validation?.artifact?.gateExecutionManifest,
);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel(
workflow = {},
) {
return workflow?.gateExecutionSummaryViewModel
?? createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel(
workflow?.validation,
);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState(
summaryViewModel = createProjectReleaseGateExecutionSummaryViewModel(),
) {
const summaryRows = Array.isArray(summaryViewModel?.rows)
? summaryViewModel.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const gateRows = Array.isArray(summaryViewModel?.gateRows)
? summaryViewModel.gateRows.map((row) => ({
id: `gate-${row.id}`,
label: row.label ?? row.id,
value: `${row.status ?? (row.passed ? "passed" : "unknown")}: ${row.evidence ?? "missing"}`,
}))
: [];
const ready = summaryViewModel?.phase === "ready" && summaryViewModel?.ready === true;
const statusText = summaryViewModel?.statusText ?? (ready ? "Ready" : "Waiting");
const detailText = summaryViewModel?.detailText ?? "release gate evidence missing";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "waiting",
ready,
title: summaryViewModel?.title ?? "Project release gate execution",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows: [...summaryRows, ...gateRows],
gateRows,
dataset: {
handoffPhase: ready ? "ready" : "waiting",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact-gate-execution-summary",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactGateExecutionSummary",
selectors = {},
} = {}) {
const mountSelector = selectors.mount
?? "[data-workflow-overview-release-readiness-artifact-gate-execution-summary]";
const statusSelector = selectors.status
?? "[data-workflow-overview-release-readiness-artifact-gate-execution-summary-status]";
const rowsSelector = selectors.rows
?? "[data-workflow-overview-release-readiness-artifact-gate-execution-summary-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactGateExecutionSummary",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactGateExecutionSummary",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact gate execution summary DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "waiting";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact-gate-execution-summary";
statusNode.textContent = renderState?.statusLine
?? "Waiting: No release gate execution summary render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "waiting";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "waiting";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactGateExecutionSummary",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract({
rowDatasetPrefix,
}),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState(
renderState,
{
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
},
);
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "waiting",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-gate-execution-summary-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release gate execution summary DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(
validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{}"),
) {
const missing = Array.isArray(validation?.missing) ? validation.missing : [];
const rows = Array.isArray(validation?.rows)
? validation.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
return {
phase: validation?.phase === "ready" ? "ready" : "blocked",
title: "Release readiness artifact",
statusText: validation?.ready ? "Ready" : "Blocked",
detailText: validation?.ready
? "No blocking reasons"
: (missing.length > 0 ? missing.join(", ") : validation?.error ?? "artifact validation blocked"),
rows,
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel(
validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{}"),
) {
return createProjectReleaseReadinessArtifactValidationSummaryViewModel(
validation?.validation ?? validation,
);
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(
displayViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(),
) {
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-workflow-overview-release-readiness-artifact-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Release readiness artifact",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-release-readiness-artifact",
},
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifact",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-workflow-overview-release-readiness-artifact]";
const statusSelector = selectors.status ?? "[data-workflow-overview-release-readiness-artifact-status]";
const rowsSelector = selectors.rows ?? "[data-workflow-overview-release-readiness-artifact-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness({
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifact",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState(
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(),
{
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifact",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview release readiness artifact DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
?? "workflow-overview-release-readiness-artifact";
statusNode.textContent = renderState?.statusLine ?? "Blocked: No release readiness artifact render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState({
renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(),
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifact",
contract = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState(renderState, {
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "release readiness artifact DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewReadiness({
overviewApi = null,
contract = createIniPanelShellWorkflowOverviewContract(),
} = {}) {
const methodNames = Array.isArray(contract?.methodNames) ? contract.methodNames : [];
const missing = methodNames.filter((methodName) => typeof overviewApi?.[methodName] !== "function");
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
contract,
};
}
export function createIniPanelShellSessionHandoffWorkflowDomReadiness({
rowDatasetPrefix = "handoffWorkflow",
contract = createIniPanelShellSessionHandoffWorkflowDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-workflow-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellSessionHandoffWorkflowState(
renderState = createIniPanelShellSessionHandoffWorkflowRenderState(),
{
rowDatasetPrefix = "handoffWorkflow",
contract = createIniPanelShellSessionHandoffWorkflowDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellSessionHandoffWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Shell handoff workflow DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope ?? "workflow";
statusNode.textContent = renderState?.statusLine ?? "Blocked: No workflow render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellSessionHandoffWorkflow({
renderState = createIniPanelShellSessionHandoffWorkflowRenderState(),
rowDatasetPrefix = "handoffWorkflow",
contract = createIniPanelShellSessionHandoffWorkflowDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellSessionHandoffWorkflowDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-session-handoff-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellSessionHandoffWorkflowState(renderState, {
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-session-handoff-workflow-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-session-handoff-workflow-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "workflow DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function mountIniPanelShellWorkflowOverviewEmbedding({
overviewApi = null,
contract = createIniPanelShellWorkflowOverviewContract(),
mountOptions = {},
} = {}) {
const readiness = createIniPanelShellWorkflowOverviewReadiness({
overviewApi,
contract,
});
if (!readiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding",
embeddingVersion: 1,
phase: "blocked",
ready: false,
pageHref: contract.pageHref,
contract,
readiness,
renderState: null,
mountResult: null,
error: null,
};
}
try {
const renderState = overviewApi.getWorkflowOverviewRenderState();
const mountResult = overviewApi.mountWorkflowOverview(mountOptions);
return {
apiName: "ini-panel-shell-workflow-overview-embedding",
embeddingVersion: 1,
phase: mountResult?.phase ?? "blocked",
ready: mountResult?.ready === true,
pageHref: contract.pageHref,
contract,
readiness,
renderState,
mountResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding",
embeddingVersion: 1,
phase: "blocked",
ready: false,
pageHref: contract.pageHref,
contract,
readiness,
renderState: null,
mountResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewEmbeddingReport(
embeddingResult = mountIniPanelShellWorkflowOverviewEmbedding(),
contract = createIniPanelShellWorkflowOverviewContract(),
) {
const result = embeddingResult && typeof embeddingResult === "object" ? embeddingResult : {};
const readiness = result.readiness && typeof result.readiness === "object" ? result.readiness : {};
const resultContract = result.contract && typeof result.contract === "object" ? result.contract : contract;
const mountResult = result.mountResult && typeof result.mountResult === "object" ? result.mountResult : {};
const renderResult = mountResult.renderResult && typeof mountResult.renderResult === "object"
? mountResult.renderResult
: {};
const missingMethods = Array.isArray(readiness.missing) ? [...readiness.missing] : [];
const error = result.error ?? mountResult.error ?? null;
const overviewReady = readiness.ready === true;
const embeddingReady = result.ready === true;
const mountPhase = mountResult.phase ?? null;
const mountReady = mountResult.ready === true;
const renderRowCount = Number.isFinite(renderResult.rowCount) ? renderResult.rowCount : 0;
const blockingReasons = [
...missingMethods.map((methodName) => `missing:${methodName}`),
...(embeddingReady ? [] : [`embedding:${result.phase ?? "blocked"}`]),
...(mountPhase && !mountReady ? [`mount:${mountPhase}`] : []),
...(error ? [`error:${error}`] : []),
];
const ready = overviewReady && embeddingReady && mountReady && !error && blockingReasons.length === 0;
const statusLine = ready
? "Ready: No blocking reasons"
: `Blocked: ${blockingReasons.length > 0 ? blockingReasons.join(", ") : "workflow overview embedding unavailable"}`;
return {
apiName: "ini-panel-shell-workflow-overview-embedding-report",
reportVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
overviewReady,
embeddingReady,
mountReady,
statusLine,
pageHref: result.pageHref ?? resultContract.pageHref ?? null,
contract: resultContract,
missingMethods,
mountPhase,
renderRowCount,
error,
blockingReasons,
rows: [
{
id: "overview-api",
label: "Overview API",
value: overviewReady ? "ready" : "blocked",
},
{
id: "missing-methods",
label: "Missing methods",
value: missingMethods.length === 0 ? "none" : missingMethods.join(", "),
},
{
id: "embedding-ready",
label: "Embedding readiness",
value: embeddingReady ? "ready" : "blocked",
},
{
id: "mount-phase",
label: "Mount phase",
value: mountPhase ?? "missing",
},
{
id: "render-row-count",
label: "Render row count",
value: String(renderRowCount),
},
{
id: "error",
label: "Error",
value: error ?? "none",
},
],
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingDisplayViewModel(
report = createIniPanelShellWorkflowOverviewEmbeddingReport(),
) {
const blockingReasons = Array.isArray(report?.blockingReasons) ? report.blockingReasons : [];
const rows = Array.isArray(report?.rows)
? report.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
return {
phase: report?.phase === "ready" ? "ready" : "blocked",
title: "Workflow overview embedding",
statusText: report?.ready ? "Ready" : "Blocked",
detailText: blockingReasons.length === 0 ? "No blocking reasons" : blockingReasons.join(", "),
rows,
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingRenderState(
displayViewModel = createIniPanelShellWorkflowOverviewEmbeddingDisplayViewModel(),
) {
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-workflow-overview-embedding-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Workflow overview embedding",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-embedding",
},
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingDomContract({
rowDatasetPrefix = "workflowOverviewEmbedding",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-workflow-overview-embedding]";
const statusSelector = selectors.status ?? "[data-workflow-overview-embedding-status]";
const rowsSelector = selectors.rows ?? "[data-workflow-overview-embedding-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-embedding-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingDomReadiness({
rowDatasetPrefix = "workflowOverviewEmbedding",
contract = createIniPanelShellWorkflowOverviewEmbeddingDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-embedding-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewEmbeddingState(
renderState = createIniPanelShellWorkflowOverviewEmbeddingRenderState(),
{
rowDatasetPrefix = "workflowOverviewEmbedding",
contract = createIniPanelShellWorkflowOverviewEmbeddingDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewEmbeddingDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview embedding DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope ?? "workflow-overview-embedding";
statusNode.textContent = renderState?.statusLine ?? "Blocked: No workflow overview embedding render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewEmbeddingState({
renderState = createIniPanelShellWorkflowOverviewEmbeddingRenderState(),
rowDatasetPrefix = "workflowOverviewEmbedding",
contract = createIniPanelShellWorkflowOverviewEmbeddingDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEmbeddingDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewEmbeddingState(renderState, {
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-workflow-overview-embedding-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "workflow overview embedding DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel(
mountResult = mountIniPanelShellWorkflowOverviewEmbeddingState(),
) {
const domMissing = Array.isArray(mountResult?.domReadiness?.missing)
? mountResult.domReadiness.missing
: [];
const renderResult = mountResult?.renderResult && typeof mountResult.renderResult === "object"
? mountResult.renderResult
: {};
const renderState = mountResult?.renderState && typeof mountResult.renderState === "object"
? mountResult.renderState
: {};
const error = mountResult?.error ?? null;
const ready = mountResult?.ready === true;
const problems = [
...(ready ? [] : [`mount:${mountResult?.phase ?? "blocked"}`]),
...domMissing.map((name) => `dom:${name}`),
...(error ? [`error:${error}`] : []),
];
return {
phase: ready ? "ready" : "blocked",
title: "Workflow overview embedding mount",
statusText: ready ? "Ready" : "Blocked",
detailText: problems.length === 0 ? "No blocking reasons" : problems.join(", "),
rows: [
{
id: "mount-ready",
label: "Mount readiness",
value: ready ? "ready" : "blocked",
},
{
id: "dom-readiness",
label: "DOM readiness",
value: mountResult?.domReadiness?.ready ? "ready" : "blocked",
},
{
id: "missing-dom",
label: "Missing DOM",
value: domMissing.length === 0 ? "none" : domMissing.join(", "),
},
{
id: "render-state",
label: "Render state",
value: renderState.statusLine ?? "missing",
},
{
id: "render-result",
label: "Render result",
value: renderResult.rendered ? "rendered" : "missing",
},
{
id: "render-row-count",
label: "Render row count",
value: Number.isFinite(renderResult.rowCount) ? String(renderResult.rowCount) : "0",
},
{
id: "error",
label: "Error",
value: error ?? "none",
},
],
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(
displayViewModel = createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel(),
) {
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-workflow-overview-embedding-mount-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Workflow overview embedding mount",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-embedding-mount",
},
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingMountDomContract({
rowDatasetPrefix = "workflowOverviewEmbeddingMount",
selectors = {},
} = {}) {
const mountSelector = selectors.mount ?? "[data-workflow-overview-embedding-mount]";
const statusSelector = selectors.status ?? "[data-workflow-overview-embedding-mount-status]";
const rowsSelector = selectors.rows ?? "[data-workflow-overview-embedding-mount-rows]";
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-dom-contract",
contractVersion: 1,
requiredNodeIds: ["mount", "status", "rows"],
selectors: {
mount: mountSelector,
status: statusSelector,
rows: rowsSelector,
},
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
rowDatasetPrefix,
rowDatasetKeys: {
term: [`${rowDatasetPrefix}Row`, `${rowDatasetPrefix}Status`],
detail: [`${rowDatasetPrefix}Value`, `${rowDatasetPrefix}Status`],
},
renderResultFields: ["rendered", "statusLine", "rowCount", "rowIds", "dataset"],
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness({
rowDatasetPrefix = "workflowOverviewEmbeddingMount",
contract = createIniPanelShellWorkflowOverviewEmbeddingMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const checks = {
document: Boolean(documentRef?.createElement),
mount: Boolean(mountNode),
status: Boolean(statusNode),
rows: Boolean(rowsNode),
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
};
const missing = Object.entries(checks)
.filter(([, passed]) => !passed)
.map(([name]) => name);
const ready = missing.length === 0;
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-dom-readiness",
readinessVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
missing,
checks,
contract,
};
}
export function renderIniPanelShellWorkflowOverviewEmbeddingMountState(
renderState = createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(),
{
rowDatasetPrefix = "workflowOverviewEmbeddingMount",
contract = createIniPanelShellWorkflowOverviewEmbeddingMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const readiness = createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!readiness.ready) {
throw new Error(
`Workflow overview embedding mount DOM is not ready: ${readiness.missing.join(", ")}`,
);
}
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope ?? "workflow-overview-embedding-mount";
statusNode.textContent = renderState?.statusLine ?? "Blocked: No workflow overview embedding mount render state";
rowsNode.replaceChildren();
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
for (const row of rows) {
const term = documentRef.createElement("dt");
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
detail.textContent = row.value;
rowsNode.append(term, detail);
}
return {
rendered: true,
statusLine: statusNode.textContent,
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,
handoffScope: mountNode.dataset.handoffScope,
},
};
}
export function mountIniPanelShellWorkflowOverviewEmbeddingMountState({
renderState = createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(),
rowDatasetPrefix = "workflowOverviewEmbeddingMount",
contract = createIniPanelShellWorkflowOverviewEmbeddingMountDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewEmbeddingMountState(renderState, {
contract,
documentRef,
mountNode,
statusNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-dom-mount",
workflowVersion: 1,
phase: renderState?.phase === "ready" ? "ready" : "blocked",
ready: renderState?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
renderState,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "workflow overview embedding mount DOM mount error"}`,
contract,
domReadiness,
renderState,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) {
const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries);
const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest);
const shellIntegrationWorkflowPlan = createIniPanelShellIntegrationWorkflowPlan({
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,
});
const shellSessionHandoffRenderState = createIniPanelShellSessionHandoffRenderState(
shellSessionHandoffSnapshot,
);
const shellSessionHandoffActionPlan = createIniPanelShellSessionHandoffActionPlan({
snapshot: shellSessionHandoffSnapshot,
renderState: shellSessionHandoffRenderState,
});
const shellSessionHandoffChecklist = createIniPanelShellSessionHandoffChecklist({
actionPlan: shellSessionHandoffActionPlan,
renderState: shellSessionHandoffRenderState,
});
const shellSessionHandoffPackage = createIniPanelShellSessionHandoffPackage({
shellIntegrationManifest,
launchApiManifest: shellIntegrationManifest.launchApiManifest,
controlPageApiManifest: shellIntegrationManifest.controlPageApiManifest,
snapshot: shellSessionHandoffSnapshot,
renderState: shellSessionHandoffRenderState,
actionPlan: shellSessionHandoffActionPlan,
checklist: shellSessionHandoffChecklist,
});
const shellSessionHandoffPackageReport = createIniPanelShellSessionHandoffPackageReport(
shellSessionHandoffPackage,
);
const shellSessionHandoffPackageDisplayViewModel = createIniPanelShellSessionHandoffPackageDisplayViewModel(
shellSessionHandoffPackageReport,
);
const shellSessionHandoffPackageRenderState = createIniPanelShellSessionHandoffPackageRenderState(
shellSessionHandoffPackageDisplayViewModel,
);
const shellSessionHandoffPackageMountState = createIniPanelShellSessionHandoffPackageMountState({
handoffPackage: shellSessionHandoffPackage,
packageRenderState: shellSessionHandoffPackageRenderState,
});
const shellSessionHandoffPackageMountDisplayViewModel = createIniPanelShellSessionHandoffPackageMountDisplayViewModel(
shellSessionHandoffPackageMountState,
);
const shellSessionHandoffPackageMountRenderState = createIniPanelShellSessionHandoffPackageMountRenderState(
shellSessionHandoffPackageMountDisplayViewModel,
);
const shellSessionHandoffMountDomContract = createIniPanelShellSessionHandoffMountDomContract();
const shellSessionHandoffReadonlyStatusResult = readIniPanelShellSessionHandoffStatusFromControlPage({
handoffSummary: shellSessionHandoffSummary,
});
const baseShellSessionHandoffWorkflowSummary = createIniPanelShellSessionHandoffWorkflowSummary({
mountWorkflow: {
phase: shellSessionHandoffPackageMountRenderState.phase,
ready: shellSessionHandoffPackageMountRenderState.ready,
statusLine: shellSessionHandoffPackageMountRenderState.statusLine,
},
controlPageMountWorkflow: {
phase: shellSessionHandoffPackageMountState.phase,
ready: shellSessionHandoffPackageMountState.ready,
statusLine: shellSessionHandoffPackageMountState.statusLine,
},
readonlyStatusResult: shellSessionHandoffReadonlyStatusResult,
});
const shellSessionHandoffWorkflowDomContract = createIniPanelShellSessionHandoffWorkflowDomContract();
const shellWorkflowOverviewContract = createIniPanelShellWorkflowOverviewContract();
const shellSessionReadinessWorkflowReport = createIniPanelShellSessionReadinessWorkflowReport({
workflowSummary: baseShellSessionHandoffWorkflowSummary,
});
const shellPersistenceSummary = createMachineSessionPersistenceSummary();
const shellApiSurfaceInventory = createIniPanelShellApiSurfaceInventory({
launchApiManifest: shellIntegrationManifest.launchApiManifest,
controlPageApiManifest: shellIntegrationManifest.controlPageApiManifest,
workflowOverviewContract: shellWorkflowOverviewContract,
sessionReadinessWorkflowReport: shellSessionReadinessWorkflowReport,
persistenceSummary: shellPersistenceSummary,
});
const shellSessionHandoffWorkflowSummary = createIniPanelShellSessionHandoffWorkflowSummary({
mountWorkflow: baseShellSessionHandoffWorkflowSummary.mountWorkflow,
controlPageMountWorkflow: baseShellSessionHandoffWorkflowSummary.controlPageMountWorkflow,
readonlyStatusResult: shellSessionHandoffReadonlyStatusResult,
persistenceSummary: shellPersistenceSummary,
apiSurfaceInventory: shellApiSurfaceInventory,
});
const shellSessionHandoffWorkflowDisplayViewModel = createIniPanelShellSessionHandoffWorkflowDisplayViewModel(
shellSessionHandoffWorkflowSummary,
);
const shellSessionHandoffWorkflowRenderState = createIniPanelShellSessionHandoffWorkflowRenderState(
shellSessionHandoffWorkflowDisplayViewModel,
);
return {
pages: entries.map(({ id, href, title }) => ({
id,
href,
title,
})),
launcherLinks: createIniPanelLauncherLinkViewModel(entries),
shellIntegrationSchema: createIniPanelShellIntegrationSchema(),
shellIntegrationManifest,
shellIntegrationReadiness,
shellIntegrationWorkflowPlan,
shellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema(),
shellSessionHandoffSummary,
shellSessionHandoffCompatibilityReport,
shellSessionHandoffDisplayViewModel,
shellSessionHandoffSnapshot,
shellSessionHandoffRenderState,
shellSessionHandoffActionPlan,
shellSessionHandoffChecklist,
shellSessionHandoffPackage,
shellSessionHandoffPackageSchema: createIniPanelShellSessionHandoffPackageSchema(),
shellSessionHandoffPackageReport,
shellSessionHandoffPackageDisplayViewModel,
shellSessionHandoffPackageRenderState,
shellSessionHandoffPackageMountState,
shellSessionHandoffPackageMountDisplayViewModel,
shellSessionHandoffPackageMountRenderState,
shellSessionHandoffMountDomContract,
shellSessionHandoffWorkflowSummary,
shellSessionReadinessWorkflowReport,
shellSessionHandoffWorkflowDisplayViewModel,
shellSessionHandoffWorkflowRenderState,
shellSessionHandoffWorkflowDomContract,
shellWorkflowOverviewContract,
shellPersistenceSummary,
shellApiSurfaceInventory,
launchApiSchema: createIniPanelLaunchApiSchema(),
launchApiManifest: createIniPanelLaunchApiManifest(entries),
isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest,
createShellIntegrationReadiness: createIniPanelShellIntegrationReadiness,
createShellIntegrationWorkflowPlan: createIniPanelShellIntegrationWorkflowPlan,
isSupportedShellSessionHandoffSummary: isSupportedIniPanelShellSessionHandoffSummary,
createShellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema,
createShellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary,
createShellSessionHandoffCompatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport,
createShellSessionHandoffDisplayViewModel: createIniPanelShellSessionHandoffDisplayViewModel,
createShellSessionHandoffSnapshot: createIniPanelShellSessionHandoffSnapshot,
createShellSessionHandoffRenderState: createIniPanelShellSessionHandoffRenderState,
createShellSessionHandoffActionPlan: createIniPanelShellSessionHandoffActionPlan,
createShellSessionHandoffChecklist: createIniPanelShellSessionHandoffChecklist,
createShellSessionHandoffPackage: createIniPanelShellSessionHandoffPackage,
createShellSessionHandoffPackageSchema: createIniPanelShellSessionHandoffPackageSchema,
createShellSessionHandoffPackageReport: createIniPanelShellSessionHandoffPackageReport,
createShellSessionHandoffPackageDisplayViewModel: createIniPanelShellSessionHandoffPackageDisplayViewModel,
createShellSessionHandoffPackageRenderState: createIniPanelShellSessionHandoffPackageRenderState,
createShellSessionHandoffPackageMountState: createIniPanelShellSessionHandoffPackageMountState,
createShellSessionHandoffPackageMountDisplayViewModel: createIniPanelShellSessionHandoffPackageMountDisplayViewModel,
createShellSessionHandoffPackageMountRenderState: createIniPanelShellSessionHandoffPackageMountRenderState,
createShellSessionHandoffMountDomContract: createIniPanelShellSessionHandoffMountDomContract,
createShellSessionHandoffMountDomReadiness: createIniPanelShellSessionHandoffMountDomReadiness,
renderShellSessionHandoffMountState: renderIniPanelShellSessionHandoffMountState,
mountShellSessionHandoff: mountIniPanelShellSessionHandoff,
mountShellSessionHandoffFromControlPage: mountIniPanelShellSessionHandoffFromControlPage,
readShellSessionHandoffStatusFromControlPage: readIniPanelShellSessionHandoffStatusFromControlPage,
createShellSessionHandoffWorkflowSummary: createIniPanelShellSessionHandoffWorkflowSummary,
createMachineSessionPersistenceSummary,
createShellSessionReadinessWorkflowReport: createIniPanelShellSessionReadinessWorkflowReport,
createShellApiSurfaceInventory: createIniPanelShellApiSurfaceInventory,
createShellSessionHandoffWorkflowDisplayViewModel: createIniPanelShellSessionHandoffWorkflowDisplayViewModel,
createShellSessionHandoffWorkflowRenderState: createIniPanelShellSessionHandoffWorkflowRenderState,
createShellSessionHandoffWorkflowDomContract: createIniPanelShellSessionHandoffWorkflowDomContract,
createShellSessionHandoffWorkflowDomReadiness: createIniPanelShellSessionHandoffWorkflowDomReadiness,
renderShellSessionHandoffWorkflowState: renderIniPanelShellSessionHandoffWorkflowState,
mountShellSessionHandoffWorkflow: mountIniPanelShellSessionHandoffWorkflow,
createWorkflowOverviewContract: createIniPanelShellWorkflowOverviewContract,
createWorkflowOverviewReadiness: createIniPanelShellWorkflowOverviewReadiness,
runWorkflowOverviewReleaseReadinessArtifactJsonWorkflow:
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow,
createWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel,
createWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan,
createWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState,
createWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract,
createWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness,
renderWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState:
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
mountWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState:
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
createWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
createWorkflowOverviewReleaseReadinessArtifactValidationActionPlan:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan,
createWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState,
createWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract,
createWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness,
renderWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState:
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
mountWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState:
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState:
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState:
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
createWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel,
createWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel,
createWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState,
createWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract,
createWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness,
renderWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState:
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
mountWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState:
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
loadWorkflowOverviewReleaseReadinessArtifactUrl:
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
mountWorkflowOverviewEmbedding: mountIniPanelShellWorkflowOverviewEmbedding,
createWorkflowOverviewEmbeddingReport: createIniPanelShellWorkflowOverviewEmbeddingReport,
createWorkflowOverviewEmbeddingDisplayViewModel: createIniPanelShellWorkflowOverviewEmbeddingDisplayViewModel,
createWorkflowOverviewEmbeddingRenderState: createIniPanelShellWorkflowOverviewEmbeddingRenderState,
createWorkflowOverviewEmbeddingDomContract: createIniPanelShellWorkflowOverviewEmbeddingDomContract,
createWorkflowOverviewEmbeddingDomReadiness: createIniPanelShellWorkflowOverviewEmbeddingDomReadiness,
renderWorkflowOverviewEmbeddingState: renderIniPanelShellWorkflowOverviewEmbeddingState,
mountWorkflowOverviewEmbeddingState: mountIniPanelShellWorkflowOverviewEmbeddingState,
createWorkflowOverviewEmbeddingMountDisplayViewModel:
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createWorkflowOverviewEmbeddingMountRenderState:
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
createWorkflowOverviewEmbeddingMountDomContract:
createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
createWorkflowOverviewEmbeddingMountDomReadiness:
createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
renderWorkflowOverviewEmbeddingMountState:
renderIniPanelShellWorkflowOverviewEmbeddingMountState,
mountWorkflowOverviewEmbeddingMountState:
mountIniPanelShellWorkflowOverviewEmbeddingMountState,
isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage,
controlPage: {
browserApiSchema: createControlPageBrowserApiSchema(),
browserApiManifest: createControlPageBrowserApiManifest(),
browserApiMethods: createControlPageBrowserApiMethods(),
contract: createIniPanelShellControlPageContract(),
createController: createMachineSessionControlPageController,
isSupportedBrowserApiManifest: isSupportedIniPanelControlPageApiManifest,
loadSessionState: loadMachineSessionForControlPageWorkflow,
readonlyStatusApiManifest: createMachineSessionReadonlyStatusApiManifest(),
readStatus: readMachineSessionReadonlyStatus,
refresh: refreshMachineSessionControlPage,
renderView: renderMachineSessionControlView,
},
};
}