export const YONEXUS_PROTOCOL_VERSION = "1" as const; export const builtinMessageTypes = [ "hello", "hello_ack", "pair_request", "pair_confirm", "pair_success", "pair_failed", "auth_request", "auth_success", "auth_failed", "re_pair_required", "heartbeat", "heartbeat_ack", "status_update", "disconnect_notice", "error" ] as const; export type BuiltinMessageType = (typeof builtinMessageTypes)[number]; export interface BuiltinEnvelope< TType extends BuiltinMessageType = BuiltinMessageType, TPayload extends Record = Record > { type: TType; requestId?: string; timestamp?: number; payload?: TPayload; } export interface HelloPayload { identifier: string; hasSecret: boolean; hasKeyPair: boolean; publicKey?: string; protocolVersion: string; } export type HelloAckNextAction = | "pair_required" | "auth_required" | "rejected" | "waiting_pair_confirm"; export interface HelloAckPayload { identifier: string; nextAction: HelloAckNextAction; } export type AdminNotificationStatus = "sent" | "failed"; export interface PairRequestPayload { identifier: string; expiresAt: number; ttlSeconds: number; adminNotification: AdminNotificationStatus; codeDelivery: "out_of_band"; } export interface PairConfirmPayload { identifier: string; pairingCode: string; } export interface PairSuccessPayload { identifier: string; secret: string; pairedAt: number; } export type PairFailedReason = | "expired" | "invalid_code" | "identifier_not_allowed" | "admin_notification_failed" | "internal_error"; export interface PairFailedPayload { identifier: string; reason: PairFailedReason; } export interface AuthRequestPayload { identifier: string; nonce: string; proofTimestamp: number; signature: string; publicKey?: string; } export interface AuthSuccessPayload { identifier: string; authenticatedAt: number; status: "online"; } export type AuthFailedReason = | "unknown_identifier" | "not_paired" | "invalid_signature" | "invalid_secret" | "stale_timestamp" | "future_timestamp" | "nonce_collision" | "rate_limited" | "re_pair_required"; export interface AuthFailedPayload { identifier: string; reason: AuthFailedReason; } export interface RePairRequiredPayload { identifier: string; reason: "nonce_collision" | "rate_limited" | "trust_revoked"; } export interface HeartbeatPayload { identifier: string; status: "alive"; } export interface HeartbeatAckPayload { identifier: string; status: "online" | "unstable" | "offline"; } export interface StatusUpdatePayload { identifier: string; status: "online" | "unstable" | "offline"; reason: string; } export interface DisconnectNoticePayload { identifier: string; reason: string; } export type ProtocolErrorCode = | "MALFORMED_MESSAGE" | "UNSUPPORTED_PROTOCOL_VERSION" | "IDENTIFIER_NOT_ALLOWED" | "PAIRING_REQUIRED" | "PAIRING_EXPIRED" | "ADMIN_NOTIFICATION_FAILED" | "AUTH_FAILED" | "NONCE_COLLISION" | "RATE_LIMITED" | "RE_PAIR_REQUIRED" | "CLIENT_OFFLINE" | "INTERNAL_ERROR"; export interface ErrorPayload { code: ProtocolErrorCode; message?: string; details?: Record; } export type BuiltinPayloadMap = { hello: HelloPayload; hello_ack: HelloAckPayload; pair_request: PairRequestPayload; pair_confirm: PairConfirmPayload; pair_success: PairSuccessPayload; pair_failed: PairFailedPayload; auth_request: AuthRequestPayload; auth_success: AuthSuccessPayload; auth_failed: AuthFailedPayload; re_pair_required: RePairRequiredPayload; heartbeat: HeartbeatPayload; heartbeat_ack: HeartbeatAckPayload; status_update: StatusUpdatePayload; disconnect_notice: DisconnectNoticePayload; error: ErrorPayload; }; export type TypedBuiltinEnvelope = BuiltinEnvelope< TType, BuiltinPayloadMap[TType] >;