import type { ProjectContext, ProtocolVersion, Session, SessionContext } from "./protocol.js"; export class ProtocolParseError extends Error { constructor(message: string) { super(message); this.name = "ProtocolParseError"; } } function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function hasString(value: Record, key: string): boolean { return typeof value[key] === "string" && value[key] !== ""; } export function isProtocolVersion(value: unknown): value is ProtocolVersion { return isRecord(value) && ["major", "minor", "patch"].every( (key) => Number.isInteger(value[key]) && (value[key] as number) >= 0, ); } export function isProjectContext(value: unknown): value is ProjectContext { return isRecord(value) && hasString(value, "server_id") && hasString(value, "project_id"); } export function isSessionContext(value: unknown): value is SessionContext { return isProjectContext(value) && hasString(value, "session_id"); } export function isSession(value: unknown): value is Session { if (!isRecord(value) || !isSessionContext(value)) return false; return hasString(value, "name") && hasString(value, "state") && hasString(value, "first_seen_at") && hasString(value, "last_active_at") && Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === "string") && Array.isArray(value.capabilities) && value.capabilities.every((capability) => typeof capability === "string"); } export function parseSession(value: unknown): Session { if (!isSession(value)) { throw new ProtocolParseError("无效的 Session:缺少上下文字段或标准字段类型错误"); } return value; }