chore: initialize repository baseline

Import the existing Electron + React + TypeScript app as the version-control
baseline before the scanner rework (C# input/capture sidecar, resolution-anchored
layout profiles, OCR preprocessing, eval harness, rescan-merge, GOOD interop).

Housekeeping in this commit:
- Remove orphaned temp_inputhelper_block.ts (duplicate of the input-helper script).
- Ignore .claude/scheduled_tasks.lock local session state.
- Add .gitattributes to normalize line endings (LF in repo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AzuTear
2026-07-05 20:31:01 +02:00
commit e76d88e0c7
147 changed files with 26220 additions and 0 deletions
@@ -0,0 +1,185 @@
import { detailFingerprint } from "../../../../lib/autoScanLoop";
import { sourceVersion } from "../../../../lib/genshinData";
import { useCallback, useMemo, type MouseEvent } from "react";
import type { ScanDiagnosticsModalProps } from "../types";
export interface ScanDiagnosticsModelProgress {
width: number;
show: boolean;
}
export interface ScanDiagnosticsModalModel {
closeDiagnostics: () => void;
openDetails: () => void;
handleSaveReviewSample: () => void;
stopPropagation: (event: MouseEvent<HTMLDivElement>) => void;
canOpenDetails: boolean;
statusTitle: string;
rightsClassName: string;
rightsValue: string;
genshinClassName: string;
genshinValue: string;
shouldShowAdminBanner: boolean;
gridSourceClass: string;
gridMainValue: string;
gridMetaValue: string;
learningRulesText: string;
learningRulesSubtext: string;
autoScanModeLabel: string;
fingerprintText: string;
runtimeRows: string[];
scanLimitText: string;
scanTipText: string;
autoScanStatsLines: Array<{ label: string; value: number }>;
playerProgress: ScanDiagnosticsModelProgress;
autoScanRunning: boolean;
showDevRows: boolean;
reviewStatus: string;
automationLogLines: string[];
canSaveReviewSample: boolean;
}
interface UseScanDiagnosticsModalModelInput extends Pick<
ScanDiagnosticsModalProps,
| "setDetailsOpen"
| "setDiagnosticsOpen"
| "saveReviewSample"
| "canSaveReviewSample"
| "latestCapture"
| "controller"
> {
captureStatus: string;
}
export function useScanDiagnosticsModalModel({
setDetailsOpen,
setDiagnosticsOpen,
saveReviewSample,
canSaveReviewSample,
latestCapture,
controller,
captureStatus,
}: UseScanDiagnosticsModalModelInput): ScanDiagnosticsModalModel {
const closeDiagnostics = useCallback(() => setDiagnosticsOpen(false), [setDiagnosticsOpen]);
const openDetails = useCallback(() => setDetailsOpen(true), [setDetailsOpen]);
const handleSaveReviewSample = useCallback(() => {
if (canSaveReviewSample && controller.parsedArtifact) {
void saveReviewSample();
}
}, [canSaveReviewSample, controller.parsedArtifact, saveReviewSample]);
const stopPropagation = useCallback((event: MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
}, []);
const canOpenDetails = Boolean(latestCapture?.crops?.length || latestCapture?.ocr?.length);
const shouldShowAdminBanner = !controller.runtimeInfo?.isElevated;
const rightsClassName = controller.runtimeInfo?.isElevated ? "ok" : "blocked";
const rightsValue = controller.runtimeInfo?.isElevated ? "Admin" : "Standard";
const genshinClassName = controller.runtimeInfo?.genshinFound ? "ok" : "neutral";
const genshinValue = controller.runtimeInfo?.genshinFound ? "Gefunden" : "Nicht gefunden";
const statusTitle = controller.devMode ? "Dev-Ausgabe kompakt" : "Dev-Ausgabe erweitern";
const autoScanModeLabel = controller.autoScanRunning ? "Scan active" : "Last scan";
const inventoryGrid = latestCapture?.inventoryGrid;
const gridSourceClass = inventoryGrid?.source ?? "missing";
const gridMainValue = inventoryGrid
? inventoryGrid?.source === "missing"
? "not detected"
: `${inventoryGrid?.cols} x ${inventoryGrid?.rows}`
: "waiting";
const gridMetaValue = inventoryGrid
? `${inventoryGrid?.confidence}% confidence - ${inventoryGrid?.centers.length} click targets`
: "Run a capture once while the artifact inventory is visible.";
const learningRulesText = controller.learningRulesLoaded ? `${controller.learningRuleCount} local rules` : "loading";
const learningRulesSubtext = `Review samples feed deterministic OCR fixes before each new parse. Data package: ${sourceVersion}`;
const playerProgress = useMemo(() => {
const width = Math.min(
100,
controller.autoScanStats.attempted > 0
? Math.round((controller.autoScanStats.verified / Math.max(1, controller.autoScanStats.attempted)) * 100)
: 0,
);
const show = controller.autoScanRunning || controller.autoScanStats.clicked > 0 || controller.autoScanStats.parsed > 0;
return { width, show };
}, [
controller.autoScanRunning,
controller.autoScanStats.attempted,
controller.autoScanStats.clicked,
controller.autoScanStats.parsed,
controller.autoScanStats.verified,
]);
const autoScanStatsLines = useMemo(
() => [
{ label: "clicked", value: controller.autoScanStats.clicked },
{ label: "attempted", value: controller.autoScanStats.attempted },
{ label: "verified", value: controller.autoScanStats.verified },
{ label: "parsed", value: controller.autoScanStats.parsed },
{ label: "stored", value: controller.autoScanStats.stored },
{ label: "review", value: controller.autoScanStats.review },
{ label: "duplicates", value: controller.autoScanStats.duplicates },
{ label: "misses", value: controller.autoScanStats.misses },
{ label: "pages", value: controller.autoScanStats.pages },
],
[
controller.autoScanStats.clicked,
controller.autoScanStats.attempted,
controller.autoScanStats.verified,
controller.autoScanStats.parsed,
controller.autoScanStats.stored,
controller.autoScanStats.review,
controller.autoScanStats.duplicates,
controller.autoScanStats.misses,
controller.autoScanStats.pages,
],
);
const runtimeRows = useMemo(() => {
const selectedSourceLabel = controller.selectedSource
? `Selected: ${controller.selectedSource.name}`
: "No source selected";
const storedTotalLabel = controller.storedTotal !== null ? `DB: ${controller.storedTotal} Artifacts` : "DB: -";
const runtime = controller.runtimeInfo
? `${controller.runtimeInfo?.isElevated ? "admin" : "standard"} - target ${controller.runtimeInfo?.genshinFound ? controller.runtimeInfo?.targetProcess || "Genshin" : "missing"} - fg ${controller.runtimeInfo?.foregroundProcess || "unknown"}`
: "unknown";
return [selectedSourceLabel, storedTotalLabel, runtime, captureStatus, controller.reviewStatus].filter(Boolean);
}, [controller.selectedSource, controller.storedTotal, controller.runtimeInfo, captureStatus, controller.reviewStatus]);
const fingerprintText = latestCapture ? detailFingerprint(latestCapture) : "--";
const scanLimitText = controller.scanLimit ? `Scan-Limit: ${controller.scanLimit}` : "Keine Limitinfo.";
const scanTipText = "Tip: Die Auto-Scan Logik bleibt aktivierbar, aber Dev-Ansicht ist rein informativ.";
return {
closeDiagnostics,
openDetails,
handleSaveReviewSample,
stopPropagation,
canOpenDetails,
statusTitle,
rightsClassName,
rightsValue,
genshinClassName,
genshinValue,
shouldShowAdminBanner,
gridSourceClass,
gridMainValue,
gridMetaValue,
learningRulesText,
learningRulesSubtext,
autoScanModeLabel,
fingerprintText,
runtimeRows,
scanLimitText,
scanTipText,
autoScanStatsLines,
playerProgress,
autoScanRunning: controller.autoScanRunning,
showDevRows: controller.devMode,
reviewStatus: controller.reviewStatus,
automationLogLines: controller.automationLog,
canSaveReviewSample: canSaveReviewSample && Boolean(controller.parsedArtifact),
};
}