import type { CaptureOptions, CaptureResult, CaptureSourceInfo, ArtifactStoreLoadResult, ArtifactStoreSaveResult, BooleanResult, ReviewSampleListResult, ReviewSamplePayload, SaveResultWithPath, FocusGenshinResult, LoadScannerLearningRulesResult, ScrollResult, RuntimeInfo, SaveScannerLearningRulesResult, SaveSnapshotResult, GoodDatabase, GoodImportFileResult, ScannerCommand, ScannerStatusPayload, ScannerLearningRulePayload, KeyPressResult, } from "../types/global"; import type { AppSnapshot } from "../types/domain"; import type { StoredArtifactRecord } from "../types/storage"; import type { AutomationGuard, ClickResult } from "../types/global"; export interface AssistantBridge { isAvailable: boolean; canExportGood: boolean; canShowOverlay: boolean; canAutoScan: boolean; canReviewSamples: boolean; loadSnapshot: () => Promise; saveSnapshot: (snapshot: AppSnapshot) => Promise; runMockScan: () => Promise; listCaptureSources: () => Promise; captureSource: ( sourceId: string, delayMs?: number, focusGenshin?: boolean, options?: CaptureOptions, ) => Promise; exportGood: (payload: GoodDatabase) => Promise; importGoodFile: () => Promise; showOverlay: () => Promise; loadArtifacts: () => Promise; saveArtifacts: (records: StoredArtifactRecord[]) => Promise; loadReviewSamples: (limit?: number) => Promise; saveReviewSample: (sample: ReviewSamplePayload) => Promise; loadScannerLearningRules: () => Promise; saveScannerLearningRules: (rules: ScannerLearningRulePayload) => Promise; getRuntimeInfo: () => Promise; getAutomationGuard: () => Promise; publishScannerStatus: (status: ScannerStatusPayload) => Promise; focusMainWindow: () => Promise; focusGenshin: () => Promise; focusGenshinForScanStart: () => Promise; clickScreen: (x: number, y: number) => Promise; scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => Promise; keyPress: (key: string) => Promise; onScannerCommand: (callback: (command: ScannerCommand) => void) => () => void; } function hasFunction(api: Record, key: string): boolean { return typeof api[key] === "function"; } export function getAssistantBridge(): AssistantBridge | null { const api = window.assistantApi; if (!api) return null; const apiRecord = api as unknown as Record; const canAutoScan = hasFunction(apiRecord, "clickScreen") && hasFunction(apiRecord, "scrollScreen"); const canReviewSamples = hasFunction(apiRecord, "loadReviewSamples") && hasFunction(apiRecord, "saveReviewSample"); const hasFocusGenshinForScanStart = hasFunction(apiRecord, "focusGenshinForScanStart"); return { isAvailable: true, canExportGood: Boolean(api.exportGood), canShowOverlay: Boolean(api.showOverlay), canAutoScan, canReviewSamples, loadSnapshot: () => api.loadSnapshot(), saveSnapshot: (snapshot: AppSnapshot) => api.saveSnapshot(snapshot), runMockScan: () => api.runMockScan(), listCaptureSources: () => api.listCaptureSources(), captureSource: (sourceId, delayMs, focusGenshin, options) => api.captureSource(sourceId, delayMs, focusGenshin, options), exportGood: (payload) => api.exportGood(payload), importGoodFile: () => api.importGoodFile(), loadArtifacts: () => api.loadArtifacts(), saveArtifacts: (records) => api.saveArtifacts(records), loadReviewSamples: (limit = 50) => api.loadReviewSamples(limit), saveReviewSample: (sample) => api.saveReviewSample(sample), loadScannerLearningRules: () => api.loadScannerLearningRules(), saveScannerLearningRules: (rules) => api.saveScannerLearningRules(rules), getRuntimeInfo: () => api.getRuntimeInfo(), getAutomationGuard: () => api.getAutomationGuard(), publishScannerStatus: (status) => api.publishScannerStatus(status), focusMainWindow: () => api.focusMainWindow(), focusGenshin: () => api.focusGenshin(), focusGenshinForScanStart: () => (hasFocusGenshinForScanStart ? api.focusGenshinForScanStart() : api.focusGenshin()), clickScreen: (x: number, y: number) => api.clickScreen(x, y), scrollScreen: (notches: number, anchorX?: number, anchorY?: number) => api.scrollScreen(notches, anchorX, anchorY), keyPress: (key: string) => api.keyPress(key), showOverlay: () => api.showOverlay(), onScannerCommand: (callback) => api.onScannerCommand(callback), }; }