结论:新增 LinuxCNC WASM 驱动的真实浏览器仿真页面,接入 browser smoke、release gate、SDK 与项目交付文档,并完成当前推进批次的验收记录。
4873 lines
180 KiB
JavaScript
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,
|
|
},
|
|
};
|
|
}
|