import { detailFingerprint } from "./autoScanLoop"; import type { CaptureResult, ClickResult, KeyPressResult } from "../types/global"; export type ScanDiagnosticSeverity = "info" | "ok" | "warn" | "error"; type InventoryGrid = NonNullable; type InventoryCount = NonNullable; export interface ScanDiagnosticEvent { id: string; at: string; phase: string; severity: ScanDiagnosticSeverity; message: string; details?: Record; capture?: { id: string; name: string; width: number; height: number; capturedAt: string; target?: CaptureResult["captureTarget"]; fingerprint: string; inventoryFingerprint?: string; layoutWarning?: string; grid?: { rows: number; cols: number; confidence: number; source: InventoryGrid["source"]; targets: number; }; count?: { current: number; total: number; confidence: number; source: InventoryCount["source"]; text: string; }; artifactDetail?: NonNullable; paimonMenu?: NonNullable; sanctified?: boolean; screenshots?: { detail?: string; inventory?: string; full?: string; }; }; } export function createScanDiagnosticEvent(input: { phase: string; severity?: ScanDiagnosticSeverity; message: string; details?: ScanDiagnosticEvent["details"]; capture?: CaptureResult | null; includeFullScreenshot?: boolean; }): ScanDiagnosticEvent { return { id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, at: new Date().toISOString(), phase: input.phase, severity: input.severity ?? "info", message: input.message, details: input.details, capture: input.capture ? summarizeCapture(input.capture, Boolean(input.includeFullScreenshot)) : undefined, }; } export function summarizeClickResult(result: ClickResult) { return { ok: result.ok, moved: result.moved, clicked: result.clicked, inputBlocked: result.inputBlocked, focused: result.focused, cursor: `${result.cursorX ?? "?"},${result.cursorY ?? "?"}`, foreground: result.foregroundProcess, target: result.targetProcess, }; } export function summarizeKeyPressResult(result: KeyPressResult | null | undefined) { return { ok: Boolean(result?.ok), key: result?.key, inputBlocked: Boolean(result?.inputBlocked), focused: Boolean(result?.focused), eventsSent: result?.eventsSent ?? 0, foreground: result?.foregroundProcess, target: result?.targetProcess, }; } function summarizeCapture(capture: CaptureResult, includeFullScreenshot: boolean): NonNullable { return { id: capture.id, name: capture.name, width: capture.width, height: capture.height, capturedAt: capture.capturedAt, target: capture.captureTarget, fingerprint: detailFingerprint(capture), inventoryFingerprint: capture.inventoryFingerprint, layoutWarning: capture.layout?.warning || undefined, grid: capture.inventoryGrid ? { rows: capture.inventoryGrid.rows, cols: capture.inventoryGrid.cols, confidence: capture.inventoryGrid.confidence, source: capture.inventoryGrid.source, targets: capture.inventoryGrid.centers.length, } : undefined, count: capture.inventoryCount ? { current: capture.inventoryCount.current, total: capture.inventoryCount.total, confidence: capture.inventoryCount.confidence, source: capture.inventoryCount.source, text: capture.inventoryCount.text, } : undefined, artifactDetail: capture.artifactDetail, paimonMenu: capture.paimonMenu, sanctified: capture.sanctified, screenshots: { detail: capture.detailDataUrl, inventory: capture.inventoryDataUrl, full: includeFullScreenshot ? capture.dataUrl : undefined, }, }; }