133 lines
4.0 KiB
TypeScript
133 lines
4.0 KiB
TypeScript
import { detailFingerprint } from "./autoScanLoop";
|
|
import type { CaptureResult, ClickResult, KeyPressResult } from "../types/global";
|
|
|
|
export type ScanDiagnosticSeverity = "info" | "ok" | "warn" | "error";
|
|
type InventoryGrid = NonNullable<CaptureResult["inventoryGrid"]>;
|
|
type InventoryCount = NonNullable<CaptureResult["inventoryCount"]>;
|
|
|
|
export interface ScanDiagnosticEvent {
|
|
id: string;
|
|
at: string;
|
|
phase: string;
|
|
severity: ScanDiagnosticSeverity;
|
|
message: string;
|
|
details?: Record<string, string | number | boolean | null | undefined>;
|
|
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<CaptureResult["artifactDetail"]>;
|
|
paimonMenu?: NonNullable<CaptureResult["paimonMenu"]>;
|
|
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<ScanDiagnosticEvent["capture"]> {
|
|
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,
|
|
},
|
|
};
|
|
}
|