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 | boolean[]; homed_axes?: boolean[]; limits?: number | Record; on_any_limit?: boolean; fault?: string | null; velocity_limit?: number; velocity_scale?: number; jog_scale?: number; jog_velocity_linear?: number; jog_velocity_angular?: number; spindle_override?: number; }; export type TrajectorySnapshot = { queue?: Array<{ id?: number; source_line?: number | null; start?: Record; end?: Record }>; active?: { id?: number; source_line?: number | null; start?: Record; end?: Record } | null; queue_depth?: number; }; export type SimSnapshotV1 = { schema?: string; 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 }; program?: Record | null; motion?: MotionSnapshot; wasm_motion?: Record; authoritative?: { state_hash?: string; planner?: TrajectorySnapshot; kinematics?: Record }; 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 }; panel_snapshot?: PanelSnapshotV1; configuration?: Record | null; visual?: PanelSnapshotV1["visual"]; motion_sample?: { tick?: number; pose?: Record; joints?: number[]; active_segment_id?: number; active_progress?: number }; snapshot_mode?: "full" | "motion_delta"; kinematics?: XyzacKinematicsSnapshot; xyzac?: XyzacCapabilitySnapshot; gates?: Record; motion_authority?: string; task_authority?: string; }; export type XyzacKinematicsSnapshot = { schema: "wasm-xyzac-kinematics.v1"; status: "verified" | "error" | "blocked"; active_type: 0 | 1 | 2; native_type: string; coordinates: "XYZAC"; joint_count: 5; linear_units: "mm"; angular_units: "deg"; pose: Record<"x" | "y" | "z" | "a" | "b" | "c" | "u" | "v" | "w", number>; joints: [number, number, number, number, number]; offsets: { x_rot_point: number; y_offset: number; z_offset: number; tool_offset: number }; generation: number; switch_count: number; state_hash: string; wasm_state_hash: string; }; export type XyzacCapabilitySnapshot = { coordinates: "XYZAC"; joint_count: 5; active_type: 0 | 1 | 2; hal_pin_vars: boolean; switchkins_net: boolean; finite_offsets: boolean; userk_capability: boolean; }; export type PanelSnapshotV1 = { schema: "axis-panel-snapshot.v1"; context_id: string; session_id: string; simulation_tick: number; state_hash: string; task: Record; program: Record | null; motion: Record; coordinates?: { machine?: number[]; relative?: number[]; commanded?: number[] }; overrides?: { feed?: number; spindle?: number[] }; wasm_motion: Record; home_limit: Record; hal: Record; devices: Record; device_io: Record; configuration: Record | null; axis_state: AxisStateView; gates: Record; visual: { schema: "axis-visual.v1"; pose: Record; joints: number[]; toolpath?: Array>; active_segment_id?: number | null; active_progress?: number; motion_trace?: Array<{ tick: number; pose: Record; joints: number[]; active_segment_id: number; active_progress: number }>; source: "wasm_canonical_motion"; }; authoritative: Record; motion_authority: string; task_authority: string; kinematics?: XyzacKinematicsSnapshot; xyzac?: XyzacCapabilitySnapshot; io?: Record; }; export type Capabilities = { context_id?: string; abi?: Record; snapshot?: Record; commands?: string[]; streams?: string[]; limits?: Record; exclusions?: string[]; }; export type AxisStateView = { state: "ESTOP" | "ESTOP_RESET" | "OFF" | "ON" | "HOME" | "IDLE" | "RUNNING" | "PAUSED"; machine_state: "ESTOP" | "ESTOP_RESET" | "OFF" | "ON"; operation_state: "HOME" | "IDLE" | "RUNNING" | "PAUSED"; source_task_state: string; source_interp_state: string; source_mode: "MANUAL" | "MDI" | "AUTO"; }; 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; }