export const PROTOCOL_SCHEMA = 1 as const; export const CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1" as const; export type MessageKind = | "HELLO" | "CAPABILITIES" | "SESSION_ATTACH" | "SESSION_READY" | "LOAD_WORKSPACE" | "COMMAND_RESULT" | "STATE_SNAPSHOT" | "EVENT" | "ALARM" | "RECOVERY_STATUS" | "ERROR"; export type MessageEnvelope = { schema_version: typeof PROTOCOL_SCHEMA; kind: MessageKind | string; context_id: string; session_id: string; seq: number; operation_id?: string; simulation_tick?: number; payload: TPayload; }; export type MotionSnapshot = { axes?: number[]; joints?: number[]; velocity?: number[]; homed?: boolean[]; limits?: number; }; export type SimSnapshotV1 = { snapshot_id?: string; base_snapshot_id?: string; full?: boolean; simulation_tick: number; state_hash: string; task?: { state: string; mode: string; interp_state?: string; current_line?: number | null }; motion?: MotionSnapshot; coordinates?: { machine?: number[]; relative?: number[]; g5x?: number; g92?: number[]; tool_offset?: number[] }; spindle?: Array<{ enabled?: boolean; direction?: number; commanded?: number; actual?: number; at_speed?: boolean }>; io?: { coolant?: number; lube?: boolean; digital?: number[]; analog?: number[]; probe?: boolean }; tool?: { current?: number; prepared?: number; pocket?: number; change_state?: string }; overrides?: { feed?: number; rapid?: number; spindle?: number[]; adaptive?: number; feed_hold?: boolean }; hal?: { graph_revision?: number; changed_values?: ArrayBuffer }; alarms?: Array<{ id?: string; severity?: string; code?: string; acknowledged?: boolean }>; recovery?: { status?: string; last_verified_seq?: number; checkpoint_tick?: number }; }; export type Capabilities = { context_id?: string; abi?: Record; snapshot?: Record; commands?: string[]; streams?: string[]; limits?: Record; exclusions?: string[]; }; export function isEnvelope(value: unknown): value is MessageEnvelope { if (!value || typeof value !== "object") return false; const candidate = value as Partial; return candidate.schema_version === PROTOCOL_SCHEMA && typeof candidate.kind === "string" && typeof candidate.context_id === "string" && typeof candidate.session_id === "string" && Number.isSafeInteger(candidate.seq) && "payload" in candidate; }