feat(scanner): add native artifact pipeline

Add native IK-style capture processing, Artifact Inventory, explicit promotion and single-result review. Confirm the three live OCR corrections in the eval corpus and preserve extraction/value separation.
This commit is contained in:
AzuTear
2026-07-09 23:30:42 +02:00
parent 28d60eb915
commit 639b0b7f59
92 changed files with 13606 additions and 1703 deletions
+49
View File
@@ -8,6 +8,10 @@ import type {
GdiCaptureResult,
HelperOperationResponse,
KeyPressResult,
NativeScannerCatalogStatus,
NativeScannerDataStatus,
NativeScannerPreflightStatus,
NativeScannerRunStatus,
WindowBounds,
RuntimeInfo,
ScrollResult,
@@ -153,6 +157,12 @@ export interface InputHelperService {
keyPress(key: string): Promise<KeyPressResult>;
getAutomationGuard(): Promise<AutomationGuard>;
capturePrimaryScreenViaGdi(): Promise<GdiCaptureResult>;
nativeScannerDataStatus(dataDir: string): Promise<NativeScannerDataStatus>;
nativeScannerCatalog(dataDir: string): Promise<NativeScannerCatalogStatus>;
nativeScannerPreflight(dataDir: string, category?: string): Promise<NativeScannerPreflightStatus>;
nativeScannerStart(options: { dataDir: string; outputRoot: string; limit?: number; category?: string }): Promise<NativeScannerRunStatus>;
nativeScannerStop(): Promise<NativeScannerRunStatus>;
nativeScannerStatus(): Promise<NativeScannerRunStatus>;
dispose(): void;
}
@@ -303,6 +313,39 @@ export function createInputHelperService(options: { userDataPath: string; exePat
};
}
function scannerPayload<T>(result: HelperOperationResponse): T {
return result.scanner as T;
}
async function nativeScannerDataStatus(dataDir: string) {
return scannerPayload<NativeScannerDataStatus>(await request("scanner-data-status", { dataDir }, 5000));
}
async function nativeScannerCatalog(dataDir: string) {
return scannerPayload<NativeScannerCatalogStatus>(await request("scanner-catalog", { dataDir }, 8000));
}
async function nativeScannerPreflight(dataDir: string, category = "artifacts") {
return scannerPayload<NativeScannerPreflightStatus>(await request("scanner-preflight", { dataDir, category }, 8000));
}
async function nativeScannerStart(options: { dataDir: string; outputRoot: string; limit?: number; category?: string }) {
return scannerPayload<NativeScannerRunStatus>(await request("scanner-start", {
dataDir: options.dataDir,
outputRoot: options.outputRoot,
limit: options.limit ?? 100,
category: options.category ?? "artifacts",
}, 8000));
}
async function nativeScannerStop() {
return scannerPayload<NativeScannerRunStatus>(await request("scanner-stop", {}, 4000));
}
async function nativeScannerStatus() {
return scannerPayload<NativeScannerRunStatus>(await request("scanner-status", {}, 4000));
}
return {
getRuntimeInfo,
focusGenshinWindow,
@@ -313,6 +356,12 @@ export function createInputHelperService(options: { userDataPath: string; exePat
keyPress,
getAutomationGuard,
capturePrimaryScreenViaGdi,
nativeScannerDataStatus,
nativeScannerCatalog,
nativeScannerPreflight,
nativeScannerStart,
nativeScannerStop,
nativeScannerStatus,
dispose: () => inputHelper.dispose(),
};
}