Files
control-plane-protocol/src/index.ts
T
2026-06-17 22:47:56 -07:00

1975 lines
50 KiB
TypeScript

export const CONTROL_PLANE_DEFAULT_HOST = "127.0.0.1";
export const CONTROL_PLANE_DEFAULT_PORT = 6246;
export const CONTROL_PLANE_DEFAULT_URL = `http://${CONTROL_PLANE_DEFAULT_HOST}:${CONTROL_PLANE_DEFAULT_PORT}`;
export const CONTROL_PLANE_ROUTES = {
run: "/run",
status: "/status",
check: "/check",
cutover: "/cutover",
clearState: "/clear-state",
describe: "/describe",
logs: "/logs",
errors: "/errors",
devices: "/devices",
deviceAssign: "/devices/assign",
deviceAssignLive: "/devices/assign-live",
deviceRename: "/devices/rename",
deviceIdentify: "/devices/identify",
deviceStopIdentify: "/devices/stop-identify",
deviceRemove: "/devices/remove",
deviceSession: "/device/session",
deviceSocket: "/device-ws",
replEval: "/repl/eval",
replClose: "/repl/close",
browserSocket: "/ws",
} as const;
export type ControlPlaneRunRequest = {
target: string;
};
export type ControlPlaneCheckRequest = {
packageName: string;
rev: string;
};
export type ControlPlaneCutoverRequest = {
targets: string[];
};
export type ControlPlaneClearStateRequest = {
packageName: string;
recursive?: boolean;
};
export type ControlPlaneDescribeRequest = {
packageName: string;
rev: string;
};
export type ControlPlaneLogsRequest = {
packageName: string;
tail?: number;
stream?: "stdout" | "stderr" | "all";
};
export type ControlPlaneErrorsRequest = {
packageName?: string;
stateContextId?: string;
tail?: number;
acknowledge?: boolean;
};
export type ControlPlaneReplEvalRequest = {
sessionId?: string;
code: string;
autoClose?: boolean;
defaultStateContextId?: string | null;
};
export type ControlPlaneReplCloseRequest = {
sessionId: string;
};
export type ControlPlaneDeviceTarget = {
packageName: string;
stateContextId: string;
surfaceId: string;
requestFullscreen?: boolean;
};
export type ControlPlaneDeviceViewport = {
width: number;
height: number;
pixelRatio: number | null;
};
export type ControlPlaneDevice = {
deviceId: string;
name: string | null;
createdAt: string;
lastSeenAt: string | null;
connected: boolean;
assignment: ControlPlaneDeviceTarget | null;
configuredAssignment: ControlPlaneDeviceTarget | null;
identifyUntil: string | null;
lastUserAgent: string | null;
viewport: ControlPlaneDeviceViewport | null;
};
export type ControlPlaneDevicesResponse = {
devices: ControlPlaneDevice[];
};
export type ControlPlaneDeviceAssignRequest = {
deviceId: string;
target: ControlPlaneDeviceTarget | null;
};
export type ControlPlaneDeviceRenameRequest = {
deviceId: string;
name: string | null;
};
export type ControlPlaneDeviceRemoveRequest = {
deviceId: string;
};
export type ControlPlaneDeviceIdentifyRequest = {
deviceId: string;
durationMs?: number;
};
export type ControlPlaneDeviceSessionRequest = {
deviceId: string;
requestedTarget?: ControlPlaneDeviceTarget | null;
userAgent?: string | null;
viewport?: ControlPlaneDeviceViewport | null;
};
export type ControlPlaneDeviceSessionResponse = {
device: ControlPlaneDevice;
};
export type ControlPlaneWorkspacePackage = {
packageName: string;
headCommit: string;
ignored: boolean;
};
export type ControlPlaneStateContext = {
id: string;
packageName: string;
packageRef: string;
createdAt: string;
parentStateContextId: string | null;
namespace: string | null;
kind: "root" | "derived";
};
export type ControlPlaneBrowserAuthMessage = {
type: "auth";
secret: string;
};
export type ControlPlaneBrowserOpenRootContextParams = {
target: string;
};
export type ControlPlaneBrowserOpenDerivedContextParams = {
target: string;
targetPackageName?: string;
callerStateContextId: string;
contextNamespace?: string | null;
};
export type ControlPlaneBrowserCloseStateContextParams = {
stateContextId: string;
};
export type ControlPlaneBrowserCallParams = {
target: string;
functionName: string;
params: unknown;
stateContextId: string;
};
export type ControlPlaneBrowserValueGetParams = {
target: string;
valueName: string;
params: unknown;
stateContextId: string;
};
export type ControlPlaneBrowserSubscribeParams = {
target: string;
resourceName: string;
params: unknown;
stateContextId: string;
subscriptionNamespace?: string | null;
};
export type ControlPlaneBrowserUnsubscribeParams = {
subscriptionId: string;
};
export type ControlPlaneBrowserSubscriptionReadyParams = {
subscriptionId: string;
};
export type ControlPlaneBrowserRequestMessage =
| {
type: "request";
requestId: string;
method: "open-root-context";
params: ControlPlaneBrowserOpenRootContextParams;
}
| {
type: "request";
requestId: string;
method: "open-derived-context";
params: ControlPlaneBrowserOpenDerivedContextParams;
}
| {
type: "request";
requestId: string;
method: "close-state-context";
params: ControlPlaneBrowserCloseStateContextParams;
}
| {
type: "request";
requestId: string;
method: "call";
params: ControlPlaneBrowserCallParams;
}
| {
type: "request";
requestId: string;
method: "value-get";
params: ControlPlaneBrowserValueGetParams;
}
| {
type: "request";
requestId: string;
method: "event-subscribe";
params: ControlPlaneBrowserSubscribeParams;
}
| {
type: "request";
requestId: string;
method: "value-watch";
params: ControlPlaneBrowserSubscribeParams;
}
| {
type: "request";
requestId: string;
method: "unsubscribe";
params: ControlPlaneBrowserUnsubscribeParams;
}
| {
type: "request";
requestId: string;
method: "subscription-ready";
params: ControlPlaneBrowserSubscriptionReadyParams;
};
export type ControlPlaneBrowserClientMessage =
| ControlPlaneBrowserAuthMessage
| ControlPlaneBrowserRequestMessage;
export type ControlPlaneBrowserResponseMessage = {
type: "response";
requestId: string;
ok: boolean;
result?: unknown;
error?: string;
};
export type ControlPlaneBrowserSubscriptionDataMessage = {
type: "subscription-data";
subscriptionId: string;
data: unknown;
};
export type ControlPlaneBrowserAuthAckMessage = {
type: "auth-ack";
};
export type ControlPlaneBrowserStatusInvalidatedMessage = {
type: "status-invalidated";
reason:
| "state-context-opened"
| "state-context-closed"
| "running-packages-changed"
| "repl-sessions-changed"
| "runtime-errors-changed"
| "devices-changed";
};
export type ControlPlaneDeviceSocketConnectMessage = {
type: "device-connect";
deviceId: string;
requestedTarget?: ControlPlaneDeviceTarget | null;
userAgent?: string | null;
viewport?: ControlPlaneDeviceViewport | null;
};
export type ControlPlaneDeviceSocketUpdateMessage = {
type: "device-update";
viewport?: ControlPlaneDeviceViewport | null;
};
export type ControlPlaneDeviceSocketClientMessage =
| ControlPlaneDeviceSocketConnectMessage
| ControlPlaneDeviceSocketUpdateMessage;
export type ControlPlaneDeviceSocketReadyMessage = {
type: "device-ready";
device: ControlPlaneDevice;
};
export type ControlPlaneDeviceSocketStateMessage = {
type: "device-state";
device: ControlPlaneDevice;
};
export type ControlPlaneDeviceSocketRemovedMessage = {
type: "device-removed";
deviceId: string;
};
export type ControlPlaneDeviceSocketServerMessage =
| ControlPlaneDeviceSocketReadyMessage
| ControlPlaneDeviceSocketStateMessage
| ControlPlaneDeviceSocketRemovedMessage;
export type ControlPlanePackageLogEntry = {
id: string;
createdAt: string;
packageName: string;
label: string;
processId: number | null;
stream: "stdout" | "stderr";
text: string;
};
export type ControlPlaneRuntimeErrorPhase =
| "on-create"
| "on-destroy"
| "on-context-open"
| "on-context-close"
| "browser-surface"
| "function"
| "event-subscribe"
| "event-cleanup"
| "value-get"
| "value-watch"
| "value-cleanup"
| "subscription-publish"
| "internal";
export type ControlPlanePackageErrorEntry = {
id: string;
createdAt: string;
packageName: string;
label: string | null;
processId: number | null;
stateContextId: string | null;
phase: ControlPlaneRuntimeErrorPhase;
functionName: string | null;
resourceKind: "event" | "value" | null;
resourceName: string | null;
surfaceId: string | null;
hostSessionId: string | null;
message: string;
stack: string | null;
acknowledgedAt: string | null;
};
export type ControlPlaneLogsResponse = {
packageName: string;
entries: ControlPlanePackageLogEntry[];
};
export type ControlPlaneErrorsResponse = {
entries: ControlPlanePackageErrorEntry[];
acknowledgedCount: number;
};
export type ControlPlaneReplSession = {
sessionId: string;
createdAt: string;
lastActivityAt: string;
ownedStateContextIds: string[];
borrowedStateContextIds: string[];
subscriptionCount: number;
tempDirectory: string;
};
export type ControlPlaneBrowserServerMessage =
| ControlPlaneBrowserAuthAckMessage
| ControlPlaneBrowserStatusInvalidatedMessage
| ControlPlaneBrowserResponseMessage
| ControlPlaneBrowserSubscriptionDataMessage;
export type ControlPlaneDependencyInput = {
inputName: string;
targetNodeId: string;
};
export type ControlPlaneDependencyNode = {
nodeId: string;
label: string;
originalRef: string | null;
lockedRef: string | null;
version: string | null;
inputs: ControlPlaneDependencyInput[];
};
export type ControlPlaneDependencyGraph = {
rootNodeId: string;
nodes: ControlPlaneDependencyNode[];
};
export type ControlPlaneRunningPackage = {
key: string;
label: string;
packageName: string;
flakeRef: string;
requestedRef: string | null;
connected: boolean;
processId: number | null;
openedStateContextIds: string[];
rootStateContextIds: string[];
resolvedRef: string | null;
version: string | null;
unreadErrorCount: number;
lastErrorAt: string | null;
dependencyGraph: ControlPlaneDependencyGraph | null;
dependencyGraphError: string | null;
};
export type ControlPlaneCheckStatus = "running" | "passed" | "failed";
export type ControlPlaneCheckResult = {
packageName: string;
rev: string;
status: ControlPlaneCheckStatus;
startedAt: string;
finishedAt: string | null;
summary: string | null;
logExcerpt: string | null;
};
export type ControlPlaneSchemaResourceDescription = {
name: string;
description: string | null;
annotations: Array<Record<string, unknown> & { type: string }>;
takesParams: boolean;
inputDescription: string | null;
inputJsonSchema: Record<string, unknown> | null;
outputDescription: string | null;
outputJsonSchema: Record<string, unknown> | null;
paramsDescription: string | null;
paramsJsonSchema: Record<string, unknown> | null;
dataDescription: string | null;
dataJsonSchema: Record<string, unknown> | null;
history?: boolean;
payloadMode: string | null;
};
export type ControlPlanePackageSchemaDescription = {
packageName: string;
schemaPackageName: string;
description: string | null;
annotations: Array<Record<string, unknown> & { type: string }>;
functions: ControlPlaneSchemaResourceDescription[];
events: ControlPlaneSchemaResourceDescription[];
values: ControlPlaneSchemaResourceDescription[];
};
export type ControlPlaneSchemaDescriptionResult = {
packageName: string;
rev: string;
generatedAt: string;
status: "available" | "unavailable";
data: ControlPlanePackageSchemaDescription | null;
error: string | null;
};
export type ControlPlaneRunResponse = {
stateContextId: string;
package: ControlPlaneRunningPackage;
};
export type ControlPlaneClearStateResponse = {
packageNames: string[];
clearedDirectories: string[];
packages: ControlPlaneRunningPackage[];
};
export type ControlPlaneReplLogEntry = {
level: "log" | "info" | "warn" | "error";
text: string;
};
export type ControlPlaneReplEvalResponse = {
session: ControlPlaneReplSession;
created: boolean;
closed: boolean;
ok: boolean;
result: string | null;
logs: ControlPlaneReplLogEntry[];
error: string | null;
};
export type ControlPlaneReplCloseResponse = {
sessionId: string;
closed: boolean;
};
export type ControlPlaneRemoteDomPayload = {
protocol: string;
revision: number;
baseRevision: number | null;
fromEmpty: boolean;
mutations: unknown[];
};
export type ControlPlaneStatusResponse = {
generatedAt: string;
workspacePackages: ControlPlaneWorkspacePackage[];
stateContexts: ControlPlaneStateContext[];
replSessions: ControlPlaneReplSession[];
devices: ControlPlaneDevice[];
packages: ControlPlaneRunningPackage[];
checks: ControlPlaneCheckResult[];
descriptions: ControlPlaneSchemaDescriptionResult[];
};
export type ControlPlaneCutoverResponse = {
packages: ControlPlaneRunningPackage[];
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
typeof value === "object" && value !== null;
const isString = (value: unknown): value is string => typeof value === "string";
const isNullableString = (value: unknown): value is string | null =>
value === null || typeof value === "string";
const isNullableRecord = (
value: unknown,
): value is Record<string, unknown> | null =>
value === null || isRecord(value);
const isPositiveInteger = (value: unknown): value is number =>
typeof value === "number" && Number.isInteger(value) && value > 0;
const isRuntimeErrorPhase = (
value: unknown,
): value is ControlPlaneRuntimeErrorPhase =>
value === "on-create" ||
value === "on-destroy" ||
value === "on-context-open" ||
value === "on-context-close" ||
value === "browser-surface" ||
value === "function" ||
value === "event-subscribe" ||
value === "event-cleanup" ||
value === "value-get" ||
value === "value-watch" ||
value === "value-cleanup" ||
value === "subscription-publish" ||
value === "internal";
const isSchemaAnnotation = (
value: unknown,
): value is Record<string, unknown> & { type: string } =>
isRecord(value) && isString(value.type);
const isSchemaAnnotationArray = (
value: unknown,
): value is Array<Record<string, unknown> & { type: string }> =>
Array.isArray(value) && value.every((item) => isSchemaAnnotation(item));
const isStringArray = (value: unknown): value is string[] =>
Array.isArray(value) && value.every((item) => typeof item === "string");
const isCheckStatus = (value: unknown): value is ControlPlaneCheckStatus =>
value === "running" || value === "passed" || value === "failed";
const isPositiveNumber = (value: unknown): value is number =>
typeof value === "number" && Number.isFinite(value) && value > 0;
const parseControlPlaneDeviceViewport = (
value: unknown,
): ControlPlaneDeviceViewport | null => {
if (
!isRecord(value) ||
!isPositiveNumber(value.width) ||
!isPositiveNumber(value.height) ||
!(
value.pixelRatio === undefined ||
value.pixelRatio === null ||
isPositiveNumber(value.pixelRatio)
)
) {
return null;
}
return {
width: value.width,
height: value.height,
pixelRatio: value.pixelRatio ?? null,
};
};
export const parseControlPlaneDeviceTarget = (
value: unknown,
): ControlPlaneDeviceTarget | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.packageName) ||
!isNonEmptyString(value.stateContextId) ||
!isNonEmptyString(value.surfaceId) ||
!(
value.requestFullscreen === undefined ||
typeof value.requestFullscreen === "boolean"
)
) {
return null;
}
return {
packageName: value.packageName,
stateContextId: value.stateContextId,
surfaceId: value.surfaceId,
requestFullscreen: value.requestFullscreen,
};
};
export const parseControlPlaneDevice = (
value: unknown,
): ControlPlaneDevice | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.deviceId) ||
!isNullableString(value.name) ||
!isString(value.createdAt) ||
!isNullableString(value.lastSeenAt) ||
typeof value.connected !== "boolean" ||
!isNullableString(value.identifyUntil) ||
!isNullableString(value.lastUserAgent)
) {
return null;
}
const assignment =
value.assignment === undefined || value.assignment === null
? null
: parseControlPlaneDeviceTarget(value.assignment);
if (value.assignment !== undefined && value.assignment !== null && !assignment) {
return null;
}
const configuredAssignment =
value.configuredAssignment === undefined || value.configuredAssignment === null
? null
: parseControlPlaneDeviceTarget(value.configuredAssignment);
if (
value.configuredAssignment !== undefined &&
value.configuredAssignment !== null &&
!configuredAssignment
) {
return null;
}
const viewport =
value.viewport === undefined || value.viewport === null
? null
: parseControlPlaneDeviceViewport(value.viewport);
if (value.viewport !== undefined && value.viewport !== null && !viewport) {
return null;
}
return {
deviceId: value.deviceId,
name: value.name,
createdAt: value.createdAt,
lastSeenAt: value.lastSeenAt,
connected: value.connected,
assignment,
configuredAssignment,
identifyUntil: value.identifyUntil,
lastUserAgent: value.lastUserAgent,
viewport,
};
};
export const parseControlPlaneRunRequest = (
value: unknown,
): ControlPlaneRunRequest | null => {
if (!isRecord(value) || !isString(value.target) || value.target.length === 0) {
return null;
}
return {
target: value.target,
};
};
export const parseControlPlaneCheckRequest = (
value: unknown,
): ControlPlaneCheckRequest | null => {
if (
!isRecord(value) ||
!isString(value.packageName) ||
value.packageName.length === 0 ||
!isString(value.rev) ||
value.rev.length === 0
) {
return null;
}
return {
packageName: value.packageName,
rev: value.rev,
};
};
export const parseControlPlaneCutoverRequest = (
value: unknown,
): ControlPlaneCutoverRequest | null => {
if (
!isRecord(value) ||
!Array.isArray(value.targets) ||
!value.targets.every(
(target) => typeof target === "string" && target.length > 0,
)
) {
return null;
}
return {
targets: value.targets,
};
};
export const parseControlPlaneClearStateRequest = (
value: unknown,
): ControlPlaneClearStateRequest | null => {
if (!isRecord(value) || !isString(value.packageName)) {
return null;
}
if (
value.recursive !== undefined &&
typeof value.recursive !== "boolean"
) {
return null;
}
return {
packageName: value.packageName,
recursive: value.recursive,
};
};
export const parseControlPlaneDescribeRequest = (
value: unknown,
): ControlPlaneDescribeRequest | null => {
if (
!isRecord(value) ||
!isString(value.packageName) ||
value.packageName.length === 0 ||
!isString(value.rev) ||
value.rev.length === 0
) {
return null;
}
return {
packageName: value.packageName,
rev: value.rev,
};
};
export const parseControlPlaneLogsRequest = (
value: unknown,
): ControlPlaneLogsRequest | null => {
if (!isRecord(value) || !isString(value.packageName)) {
return null;
}
if (
!(
value.tail === undefined ||
value.tail === null ||
isPositiveInteger(value.tail)
) ||
!(
value.stream === undefined ||
value.stream === "stdout" ||
value.stream === "stderr" ||
value.stream === "all"
)
) {
return null;
}
return {
packageName: value.packageName,
tail: value.tail ?? undefined,
stream: value.stream ?? undefined,
};
};
export const parseControlPlaneErrorsRequest = (
value: unknown,
): ControlPlaneErrorsRequest | null => {
if (!isRecord(value)) {
return null;
}
if (
!(
value.packageName === undefined ||
value.packageName === null ||
isString(value.packageName)
) ||
!(
value.stateContextId === undefined ||
value.stateContextId === null ||
isString(value.stateContextId)
) ||
!(
value.tail === undefined ||
value.tail === null ||
isPositiveInteger(value.tail)
) ||
!(
value.acknowledge === undefined ||
typeof value.acknowledge === "boolean"
)
) {
return null;
}
return {
packageName: value.packageName ?? undefined,
stateContextId: value.stateContextId ?? undefined,
tail: value.tail ?? undefined,
acknowledge: value.acknowledge ?? undefined,
};
};
export const parseControlPlaneDeviceAssignRequest = (
value: unknown,
): ControlPlaneDeviceAssignRequest | null => {
if (!isRecord(value) || !isNonEmptyString(value.deviceId)) {
return null;
}
const target =
value.target === undefined || value.target === null
? null
: parseControlPlaneDeviceTarget(value.target);
if (value.target !== undefined && value.target !== null && !target) {
return null;
}
return {
deviceId: value.deviceId,
target,
};
};
export const parseControlPlaneDeviceRenameRequest = (
value: unknown,
): ControlPlaneDeviceRenameRequest | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.deviceId) ||
!(
value.name === undefined ||
value.name === null ||
typeof value.name === "string"
)
) {
return null;
}
return {
deviceId: value.deviceId,
name: value.name ?? null,
};
};
export const parseControlPlaneDeviceRemoveRequest = (
value: unknown,
): ControlPlaneDeviceRemoveRequest | null => {
if (!isRecord(value) || !isNonEmptyString(value.deviceId)) {
return null;
}
return {
deviceId: value.deviceId,
};
};
export const parseControlPlaneDeviceIdentifyRequest = (
value: unknown,
): ControlPlaneDeviceIdentifyRequest | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.deviceId) ||
!(
value.durationMs === undefined ||
(typeof value.durationMs === "number" &&
Number.isInteger(value.durationMs) &&
value.durationMs > 0)
)
) {
return null;
}
return {
deviceId: value.deviceId,
durationMs: value.durationMs,
};
};
export const parseControlPlaneDeviceSessionRequest = (
value: unknown,
): ControlPlaneDeviceSessionRequest | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.deviceId) ||
!(
value.userAgent === undefined ||
value.userAgent === null ||
typeof value.userAgent === "string"
)
) {
return null;
}
const requestedTarget =
value.requestedTarget === undefined
? undefined
: value.requestedTarget === null
? null
: parseControlPlaneDeviceTarget(value.requestedTarget);
if (
value.requestedTarget !== undefined &&
value.requestedTarget !== null &&
!requestedTarget
) {
return null;
}
const viewport =
value.viewport === undefined || value.viewport === null
? null
: parseControlPlaneDeviceViewport(value.viewport);
if (value.viewport !== undefined && value.viewport !== null && !viewport) {
return null;
}
return {
deviceId: value.deviceId,
...(requestedTarget !== undefined ? { requestedTarget } : {}),
userAgent: value.userAgent ?? null,
viewport,
};
};
export const parseControlPlaneReplEvalRequest = (
value: unknown,
): ControlPlaneReplEvalRequest | null => {
if (!isRecord(value) || !isNonEmptyString(value.code)) {
return null;
}
if (
!(
value.sessionId === undefined ||
isNonEmptyString(value.sessionId)
) ||
!(
value.autoClose === undefined ||
typeof value.autoClose === "boolean"
) ||
!(
value.defaultStateContextId === undefined ||
value.defaultStateContextId === null ||
isNonEmptyString(value.defaultStateContextId)
)
) {
return null;
}
return {
sessionId: value.sessionId,
code: value.code,
autoClose: value.autoClose,
defaultStateContextId: value.defaultStateContextId ?? null,
};
};
export const parseControlPlaneReplCloseRequest = (
value: unknown,
): ControlPlaneReplCloseRequest | null => {
if (!isRecord(value) || !isNonEmptyString(value.sessionId)) {
return null;
}
return {
sessionId: value.sessionId,
};
};
const isNonEmptyString = (value: unknown): value is string =>
typeof value === "string" && value.length > 0;
const parseBrowserSubscribeParams = (
value: unknown,
): ControlPlaneBrowserSubscribeParams | null => {
if (
!isRecord(value) ||
!isNonEmptyString(value.target) ||
!isNonEmptyString(value.resourceName) ||
!isNonEmptyString(value.stateContextId) ||
!(
value.subscriptionNamespace === undefined ||
value.subscriptionNamespace === null ||
typeof value.subscriptionNamespace === "string"
)
) {
return null;
}
return {
target: value.target,
resourceName: value.resourceName,
params: value.params,
stateContextId: value.stateContextId,
subscriptionNamespace: value.subscriptionNamespace ?? null,
};
};
export const parseControlPlaneDeviceSocketClientMessage = (
value: unknown,
): ControlPlaneDeviceSocketClientMessage | null => {
if (!isRecord(value) || !isNonEmptyString(value.type)) {
return null;
}
if (value.type === "device-connect") {
const parsed = parseControlPlaneDeviceSessionRequest(value);
if (!parsed) {
return null;
}
return {
type: "device-connect",
deviceId: parsed.deviceId,
...(parsed.requestedTarget !== undefined
? { requestedTarget: parsed.requestedTarget }
: {}),
...(parsed.userAgent !== undefined ? { userAgent: parsed.userAgent } : {}),
...(parsed.viewport !== undefined ? { viewport: parsed.viewport } : {}),
};
}
if (value.type === "device-update") {
const viewport =
value.viewport === undefined || value.viewport === null
? value.viewport
: parseControlPlaneDeviceViewport(value.viewport);
if (value.viewport !== undefined && value.viewport !== null && !viewport) {
return null;
}
return {
type: "device-update",
...(value.viewport !== undefined ? { viewport: viewport ?? null } : {}),
};
}
return null;
};
export const parseControlPlaneDeviceSocketServerMessage = (
value: unknown,
): ControlPlaneDeviceSocketServerMessage | null => {
if (!isRecord(value) || !isNonEmptyString(value.type)) {
return null;
}
if (value.type === "device-removed") {
if (!isNonEmptyString(value.deviceId)) {
return null;
}
return {
type: "device-removed",
deviceId: value.deviceId,
};
}
if (value.type !== "device-ready" && value.type !== "device-state") {
return null;
}
const device = parseControlPlaneDevice(value.device);
if (!device) {
return null;
}
return {
type: value.type,
device,
};
};
export const parseControlPlaneBrowserClientMessage = (
value: unknown,
): ControlPlaneBrowserClientMessage | null => {
if (!isRecord(value) || !isNonEmptyString(value.type)) {
return null;
}
if (value.type === "auth") {
if (!isNonEmptyString(value.secret)) {
return null;
}
return {
type: "auth",
secret: value.secret,
};
}
if (value.type !== "request") {
return null;
}
if (!isNonEmptyString(value.requestId) || !isNonEmptyString(value.method)) {
return null;
}
switch (value.method) {
case "open-root-context":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.target)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "open-root-context",
params: {
target: value.params.target,
},
};
case "open-derived-context":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.target) ||
!isNonEmptyString(value.params.callerStateContextId) ||
!(
value.params.targetPackageName === undefined ||
isNonEmptyString(value.params.targetPackageName)
) ||
!(
value.params.contextNamespace === undefined ||
value.params.contextNamespace === null ||
isNonEmptyString(value.params.contextNamespace)
)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "open-derived-context",
params: {
target: value.params.target,
targetPackageName: value.params.targetPackageName,
callerStateContextId: value.params.callerStateContextId,
contextNamespace: value.params.contextNamespace ?? null,
},
};
case "close-state-context":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.stateContextId)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "close-state-context",
params: {
stateContextId: value.params.stateContextId,
},
};
case "call":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.target) ||
!isNonEmptyString(value.params.functionName) ||
!isNonEmptyString(value.params.stateContextId)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "call",
params: {
target: value.params.target,
functionName: value.params.functionName,
params: value.params.params,
stateContextId: value.params.stateContextId,
},
};
case "value-get":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.target) ||
!isNonEmptyString(value.params.valueName) ||
!isNonEmptyString(value.params.stateContextId)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "value-get",
params: {
target: value.params.target,
valueName: value.params.valueName,
params: value.params.params,
stateContextId: value.params.stateContextId,
},
};
case "event-subscribe": {
const params = parseBrowserSubscribeParams(value.params);
if (!params) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "event-subscribe",
params,
};
}
case "value-watch": {
const params = parseBrowserSubscribeParams(value.params);
if (!params) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "value-watch",
params,
};
}
case "unsubscribe":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.subscriptionId)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "unsubscribe",
params: {
subscriptionId: value.params.subscriptionId,
},
};
case "subscription-ready":
if (
!isRecord(value.params) ||
!isNonEmptyString(value.params.subscriptionId)
) {
return null;
}
return {
type: "request",
requestId: value.requestId,
method: "subscription-ready",
params: {
subscriptionId: value.params.subscriptionId,
},
};
default:
return null;
}
};
const parseDependencyInput = (
value: unknown,
): ControlPlaneDependencyInput | null => {
if (!isRecord(value)) {
return null;
}
if (!isString(value.inputName) || !isString(value.targetNodeId)) {
return null;
}
return {
inputName: value.inputName,
targetNodeId: value.targetNodeId,
};
};
const parseDependencyNode = (
value: unknown,
): ControlPlaneDependencyNode | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.nodeId) ||
!isString(value.label) ||
!isNullableString(value.originalRef) ||
!isNullableString(value.lockedRef) ||
!isNullableString(value.version) ||
!Array.isArray(value.inputs)
) {
return null;
}
const inputs = value.inputs
.map((input) => parseDependencyInput(input))
.filter((input): input is ControlPlaneDependencyInput => input !== null);
if (inputs.length !== value.inputs.length) {
return null;
}
return {
nodeId: value.nodeId,
label: value.label,
originalRef: value.originalRef,
lockedRef: value.lockedRef,
version: value.version,
inputs,
};
};
const parseControlPlaneWorkspacePackage = (
value: unknown,
): ControlPlaneWorkspacePackage | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.packageName) ||
!isString(value.headCommit) ||
typeof value.ignored !== "boolean"
) {
return null;
}
return {
packageName: value.packageName,
headCommit: value.headCommit,
ignored: value.ignored,
};
};
const parseControlPlaneReplLogEntry = (
value: unknown,
): ControlPlaneReplLogEntry | null => {
if (
!isRecord(value) ||
!(
value.level === "log" ||
value.level === "info" ||
value.level === "warn" ||
value.level === "error"
) ||
!isString(value.text)
) {
return null;
}
return {
level: value.level,
text: value.text,
};
};
export const parseControlPlaneReplSession = (
value: unknown,
): ControlPlaneReplSession | null => {
if (
!isRecord(value) ||
!isString(value.sessionId) ||
!isString(value.createdAt) ||
!isString(value.lastActivityAt) ||
!isStringArray(value.ownedStateContextIds) ||
!isStringArray(value.borrowedStateContextIds) ||
typeof value.subscriptionCount !== "number" ||
!isString(value.tempDirectory)
) {
return null;
}
return {
sessionId: value.sessionId,
createdAt: value.createdAt,
lastActivityAt: value.lastActivityAt,
ownedStateContextIds: value.ownedStateContextIds,
borrowedStateContextIds: value.borrowedStateContextIds,
subscriptionCount: value.subscriptionCount,
tempDirectory: value.tempDirectory,
};
};
const parseDependencyGraph = (
value: unknown,
): ControlPlaneDependencyGraph | null => {
if (!isRecord(value)) {
return null;
}
if (!isString(value.rootNodeId) || !Array.isArray(value.nodes)) {
return null;
}
const nodes = value.nodes
.map((node) => parseDependencyNode(node))
.filter((node): node is ControlPlaneDependencyNode => node !== null);
if (nodes.length !== value.nodes.length) {
return null;
}
return {
rootNodeId: value.rootNodeId,
nodes,
};
};
export const parseControlPlaneRunningPackage = (
value: unknown,
): ControlPlaneRunningPackage | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.key) ||
!isString(value.label) ||
!isString(value.packageName) ||
!isString(value.flakeRef) ||
!isNullableString(value.requestedRef) ||
typeof value.connected !== "boolean" ||
!(typeof value.processId === "number" || value.processId === null) ||
!isStringArray(value.openedStateContextIds) ||
!isStringArray(value.rootStateContextIds) ||
!isNullableString(value.resolvedRef) ||
!isNullableString(value.version) ||
!(
typeof value.unreadErrorCount === "number" &&
Number.isInteger(value.unreadErrorCount) &&
value.unreadErrorCount >= 0
) ||
!isNullableString(value.lastErrorAt) ||
!isNullableString(value.dependencyGraphError)
) {
return null;
}
const dependencyGraph =
value.dependencyGraph === null
? null
: parseDependencyGraph(value.dependencyGraph);
if (value.dependencyGraph !== null && !dependencyGraph) {
return null;
}
return {
key: value.key,
label: value.label,
packageName: value.packageName,
flakeRef: value.flakeRef,
requestedRef: value.requestedRef,
connected: value.connected,
processId: value.processId,
openedStateContextIds: value.openedStateContextIds,
rootStateContextIds: value.rootStateContextIds,
resolvedRef: value.resolvedRef,
version: value.version,
unreadErrorCount: value.unreadErrorCount,
lastErrorAt: value.lastErrorAt,
dependencyGraph,
dependencyGraphError: value.dependencyGraphError,
};
};
export const parseControlPlanePackageLogEntry = (
value: unknown,
): ControlPlanePackageLogEntry | null => {
if (
!isRecord(value) ||
!isString(value.id) ||
!isString(value.createdAt) ||
!isString(value.packageName) ||
!isString(value.label) ||
!(typeof value.processId === "number" || value.processId === null) ||
!(value.stream === "stdout" || value.stream === "stderr") ||
!isString(value.text)
) {
return null;
}
return {
id: value.id,
createdAt: value.createdAt,
packageName: value.packageName,
label: value.label,
processId: value.processId,
stream: value.stream,
text: value.text,
};
};
export const parseControlPlanePackageErrorEntry = (
value: unknown,
): ControlPlanePackageErrorEntry | null => {
if (
!isRecord(value) ||
!isString(value.id) ||
!isString(value.createdAt) ||
!isString(value.packageName) ||
!isNullableString(value.label) ||
!(typeof value.processId === "number" || value.processId === null) ||
!isNullableString(value.stateContextId) ||
!isRuntimeErrorPhase(value.phase) ||
!isNullableString(value.functionName) ||
!(
value.resourceKind === "event" ||
value.resourceKind === "value" ||
value.resourceKind === null
) ||
!isNullableString(value.resourceName) ||
!(
value.surfaceId === undefined ||
isNullableString(value.surfaceId)
) ||
!(
value.hostSessionId === undefined ||
isNullableString(value.hostSessionId)
) ||
!isString(value.message) ||
!isNullableString(value.stack) ||
!isNullableString(value.acknowledgedAt)
) {
return null;
}
return {
id: value.id,
createdAt: value.createdAt,
packageName: value.packageName,
label: value.label,
processId: value.processId,
stateContextId: value.stateContextId,
phase: value.phase,
functionName: value.functionName,
resourceKind: value.resourceKind,
resourceName: value.resourceName,
surfaceId: value.surfaceId ?? null,
hostSessionId: value.hostSessionId ?? null,
message: value.message,
stack: value.stack,
acknowledgedAt: value.acknowledgedAt,
};
};
export const parseControlPlaneStateContext = (
value: unknown,
): ControlPlaneStateContext | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.id) ||
!isString(value.packageName) ||
!isString(value.packageRef) ||
!isString(value.createdAt) ||
!isNullableString(value.parentStateContextId) ||
!isNullableString(value.namespace) ||
!(value.kind === "root" || value.kind === "derived")
) {
return null;
}
return {
id: value.id,
packageName: value.packageName,
packageRef: value.packageRef,
createdAt: value.createdAt,
parentStateContextId: value.parentStateContextId,
namespace: value.namespace,
kind: value.kind,
};
};
export const parseControlPlaneCheckResult = (
value: unknown,
): ControlPlaneCheckResult | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.packageName) ||
!isString(value.rev) ||
!isCheckStatus(value.status) ||
!isString(value.startedAt) ||
!isNullableString(value.finishedAt) ||
!isNullableString(value.summary) ||
!isNullableString(value.logExcerpt)
) {
return null;
}
return {
packageName: value.packageName,
rev: value.rev,
status: value.status,
startedAt: value.startedAt,
finishedAt: value.finishedAt,
summary: value.summary,
logExcerpt: value.logExcerpt,
};
};
const parseControlPlaneSchemaResourceDescription = (
value: unknown,
): ControlPlaneSchemaResourceDescription | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.name) ||
!isNullableString(value.description) ||
!(value.annotations === undefined || isSchemaAnnotationArray(value.annotations)) ||
typeof value.takesParams !== "boolean" ||
!isNullableString(value.inputDescription) ||
!(value.inputJsonSchema === undefined || isNullableRecord(value.inputJsonSchema)) ||
!isNullableString(value.outputDescription) ||
!(value.outputJsonSchema === undefined || isNullableRecord(value.outputJsonSchema)) ||
!isNullableString(value.paramsDescription) ||
!(value.paramsJsonSchema === undefined || isNullableRecord(value.paramsJsonSchema)) ||
!isNullableString(value.dataDescription) ||
!(value.dataJsonSchema === undefined || isNullableRecord(value.dataJsonSchema)) ||
!(typeof value.history === "boolean" || value.history === undefined) ||
!isNullableString(value.payloadMode)
) {
return null;
}
return {
name: value.name,
description: value.description,
annotations: value.annotations ?? [],
takesParams: value.takesParams,
inputDescription: value.inputDescription,
inputJsonSchema: value.inputJsonSchema ?? null,
outputDescription: value.outputDescription,
outputJsonSchema: value.outputJsonSchema ?? null,
paramsDescription: value.paramsDescription,
paramsJsonSchema: value.paramsJsonSchema ?? null,
dataDescription: value.dataDescription,
dataJsonSchema: value.dataJsonSchema ?? null,
history: value.history,
payloadMode: value.payloadMode,
};
};
const parseControlPlanePackageSchemaDescription = (
value: unknown,
): ControlPlanePackageSchemaDescription | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.packageName) ||
!isString(value.schemaPackageName) ||
!isNullableString(value.description) ||
!(value.annotations === undefined || isSchemaAnnotationArray(value.annotations)) ||
!Array.isArray(value.functions) ||
!Array.isArray(value.events) ||
!Array.isArray(value.values)
) {
return null;
}
const functions = value.functions
.map((entry) => parseControlPlaneSchemaResourceDescription(entry))
.filter(
(entry): entry is ControlPlaneSchemaResourceDescription => entry !== null,
);
const events = value.events
.map((entry) => parseControlPlaneSchemaResourceDescription(entry))
.filter(
(entry): entry is ControlPlaneSchemaResourceDescription => entry !== null,
);
const values = value.values
.map((entry) => parseControlPlaneSchemaResourceDescription(entry))
.filter(
(entry): entry is ControlPlaneSchemaResourceDescription => entry !== null,
);
if (
functions.length !== value.functions.length ||
events.length !== value.events.length ||
values.length !== value.values.length
) {
return null;
}
return {
packageName: value.packageName,
schemaPackageName: value.schemaPackageName,
description: value.description,
annotations: value.annotations ?? [],
functions,
events,
values,
};
};
export const parseControlPlaneSchemaDescriptionResult = (
value: unknown,
): ControlPlaneSchemaDescriptionResult | null => {
if (!isRecord(value)) {
return null;
}
if (
!isString(value.packageName) ||
!isString(value.rev) ||
!isString(value.generatedAt) ||
!(value.status === "available" || value.status === "unavailable") ||
!isNullableString(value.error)
) {
return null;
}
const data =
value.data === null ? null : parseControlPlanePackageSchemaDescription(value.data);
if (value.data !== null && !data) {
return null;
}
return {
packageName: value.packageName,
rev: value.rev,
generatedAt: value.generatedAt,
status: value.status,
data,
error: value.error,
};
};
export const parseControlPlaneRunResponse = (
value: unknown,
): ControlPlaneRunResponse | null => {
if (!isRecord(value) || !isString(value.stateContextId)) {
return null;
}
const parsedPackage = parseControlPlaneRunningPackage(value.package);
if (!parsedPackage) {
return null;
}
return {
stateContextId: value.stateContextId,
package: parsedPackage,
};
};
export const parseControlPlaneStatusResponse = (
value: unknown,
): ControlPlaneStatusResponse | null => {
if (
!isRecord(value) ||
!isString(value.generatedAt) ||
!(
value.workspacePackages === undefined ||
Array.isArray(value.workspacePackages)
) ||
!(
value.stateContexts === undefined ||
Array.isArray(value.stateContexts)
) ||
!(
value.replSessions === undefined ||
Array.isArray(value.replSessions)
) ||
!(
value.devices === undefined ||
Array.isArray(value.devices)
) ||
!Array.isArray(value.packages) ||
!Array.isArray(value.checks) ||
!Array.isArray(value.descriptions)
) {
return null;
}
const workspacePackages = (value.workspacePackages ?? [])
.map((pkg) => parseControlPlaneWorkspacePackage(pkg))
.filter((pkg): pkg is ControlPlaneWorkspacePackage => pkg !== null);
if (workspacePackages.length !== (value.workspacePackages ?? []).length) {
return null;
}
const stateContexts = (value.stateContexts ?? [])
.map((context) => parseControlPlaneStateContext(context))
.filter((context): context is ControlPlaneStateContext => context !== null);
if (stateContexts.length !== (value.stateContexts ?? []).length) {
return null;
}
const replSessions = (value.replSessions ?? [])
.map((session) => parseControlPlaneReplSession(session))
.filter((session): session is ControlPlaneReplSession => session !== null);
if (replSessions.length !== (value.replSessions ?? []).length) {
return null;
}
const devices = (value.devices ?? [])
.map((device) => parseControlPlaneDevice(device))
.filter((device): device is ControlPlaneDevice => device !== null);
if (devices.length !== (value.devices ?? []).length) {
return null;
}
const packages = value.packages
.map((pkg) => parseControlPlaneRunningPackage(pkg))
.filter((pkg): pkg is ControlPlaneRunningPackage => pkg !== null);
if (packages.length !== value.packages.length) {
return null;
}
const checks = value.checks
.map((result) => parseControlPlaneCheckResult(result))
.filter((result): result is ControlPlaneCheckResult => result !== null);
if (checks.length !== value.checks.length) {
return null;
}
const descriptions = value.descriptions
.map((entry) => parseControlPlaneSchemaDescriptionResult(entry))
.filter(
(entry): entry is ControlPlaneSchemaDescriptionResult => entry !== null,
);
if (descriptions.length !== value.descriptions.length) {
return null;
}
return {
generatedAt: value.generatedAt,
workspacePackages,
stateContexts,
replSessions,
devices,
packages,
checks,
descriptions,
};
};
export const parseControlPlaneCutoverResponse = (
value: unknown,
): ControlPlaneCutoverResponse | null => {
if (!isRecord(value) || !Array.isArray(value.packages)) {
return null;
}
const packages = value.packages
.map((pkg) => parseControlPlaneRunningPackage(pkg))
.filter((pkg): pkg is ControlPlaneRunningPackage => pkg !== null);
if (packages.length !== value.packages.length) {
return null;
}
return {
packages,
};
};
export const parseControlPlaneDevicesResponse = (
value: unknown,
): ControlPlaneDevicesResponse | null => {
if (!isRecord(value) || !Array.isArray(value.devices)) {
return null;
}
const devices = value.devices
.map((device) => parseControlPlaneDevice(device))
.filter((device): device is ControlPlaneDevice => device !== null);
if (devices.length !== value.devices.length) {
return null;
}
return { devices };
};
export const parseControlPlaneDeviceSessionResponse = (
value: unknown,
): ControlPlaneDeviceSessionResponse | null => {
if (!isRecord(value)) {
return null;
}
const device = parseControlPlaneDevice(value.device);
if (!device) {
return null;
}
return { device };
};
export const parseControlPlaneReplEvalResponse = (
value: unknown,
): ControlPlaneReplEvalResponse | null => {
if (
!isRecord(value) ||
typeof value.created !== "boolean" ||
typeof value.closed !== "boolean" ||
typeof value.ok !== "boolean" ||
!isNullableString(value.result) ||
!Array.isArray(value.logs) ||
!isNullableString(value.error)
) {
return null;
}
const session = parseControlPlaneReplSession(value.session);
if (!session) {
return null;
}
const logs = value.logs
.map((entry) => parseControlPlaneReplLogEntry(entry))
.filter((entry): entry is ControlPlaneReplLogEntry => entry !== null);
if (logs.length !== value.logs.length) {
return null;
}
return {
session,
created: value.created,
closed: value.closed,
ok: value.ok,
result: value.result,
logs,
error: value.error,
};
};
export const parseControlPlaneReplCloseResponse = (
value: unknown,
): ControlPlaneReplCloseResponse | null => {
if (
!isRecord(value) ||
!isString(value.sessionId) ||
typeof value.closed !== "boolean"
) {
return null;
}
return {
sessionId: value.sessionId,
closed: value.closed,
};
};
export const parseControlPlaneLogsResponse = (
value: unknown,
): ControlPlaneLogsResponse | null => {
if (!isRecord(value) || !isString(value.packageName) || !Array.isArray(value.entries)) {
return null;
}
const entries = value.entries
.map((entry) => parseControlPlanePackageLogEntry(entry))
.filter((entry): entry is ControlPlanePackageLogEntry => entry !== null);
if (entries.length !== value.entries.length) {
return null;
}
return {
packageName: value.packageName,
entries,
};
};
export const parseControlPlaneErrorsResponse = (
value: unknown,
): ControlPlaneErrorsResponse | null => {
if (
!isRecord(value) ||
!Array.isArray(value.entries) ||
!(
typeof value.acknowledgedCount === "number" &&
Number.isInteger(value.acknowledgedCount) &&
value.acknowledgedCount >= 0
)
) {
return null;
}
const entries = value.entries
.map((entry) => parseControlPlanePackageErrorEntry(entry))
.filter((entry): entry is ControlPlanePackageErrorEntry => entry !== null);
if (entries.length !== value.entries.length) {
return null;
}
return {
entries,
acknowledgedCount: value.acknowledgedCount,
};
};
export const parseControlPlaneClearStateResponse = (
value: unknown,
): ControlPlaneClearStateResponse | null => {
if (
!isRecord(value) ||
!isStringArray(value.packageNames) ||
!isStringArray(value.clearedDirectories) ||
!Array.isArray(value.packages)
) {
return null;
}
const packages = value.packages
.map((pkg) => parseControlPlaneRunningPackage(pkg))
.filter((pkg): pkg is ControlPlaneRunningPackage => pkg !== null);
if (packages.length !== value.packages.length) {
return null;
}
return {
packageNames: value.packageNames,
clearedDirectories: value.clearedDirectories,
packages,
};
};