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,218 @@
import { getAssistantBridge } from "../../services/assistantBridge";
import {
type ArtifactRepositoryPort,
type AutomationRepositoryPort,
type CaptureRepositoryPort,
type RendererRepositories,
type RuntimeRepositoryPort,
type ReviewSampleRepositoryPort,
type LearningRepositoryPort,
type SnapshotRepositoryPort,
type OverlayRepositoryPort,
type ScanExportPort,
} from "./rendererBridgeRepositoryTypes";
import type { AppSnapshot } from "../../types/domain";
import type {
ArtifactStoreLoadResult,
ArtifactStoreSaveResult,
LoadScannerLearningRulesResult,
BooleanResult,
CaptureSourceInfo,
FocusGenshinResult,
RuntimeInfo,
SaveResultWithPath,
ScrollResult,
AutomationGuard,
ClickResult,
ReviewSampleListResult,
SaveScannerLearningRulesResult,
} from "../../types/global";
const EMPTY_SNAPSHOT: AppSnapshot | null = null;
const EMPTY_CAPTURE_SOURCE_LIST: CaptureSourceInfo[] = [];
const EMPTY_SAVE_RESULT: SaveResultWithPath = { ok: false, path: "" };
const EMPTY_RUNTIME_INFO: RuntimeInfo = {
ok: false,
isElevated: false,
platform: "unknown",
};
const EMPTY_ARTIFACT_STORE_LOAD_RESULT: ArtifactStoreLoadResult = {
ok: false,
artifacts: [],
total: 0,
path: "",
};
const EMPTY_ARTIFACT_STORE_SAVE_RESULT: ArtifactStoreSaveResult = {
ok: false,
added: 0,
updated: 0,
total: 0,
path: "",
};
const EMPTY_REVIEW_SAMPLES_RESULT: ReviewSampleListResult = {
ok: false,
samples: [],
total: 0,
path: "",
};
const EMPTY_SCANNER_LEARNING_RULES_RESULT: LoadScannerLearningRulesResult = {
ok: false,
path: "",
rules: {},
};
const EMPTY_SCAN_STATUS_RESULT: SaveResultWithPath = { ok: false, path: "" };
const EMPTY_SAVE_RULES_RESULT: SaveScannerLearningRulesResult = {
ok: false,
path: "",
rules: {},
total: 0,
};
async function createBridgeSafeCall<TResult>(
callback: () => Promise<TResult> | TResult | null | undefined,
fallback: TResult,
): Promise<TResult> {
try {
const result = await callback();
return result == null ? fallback : result;
} catch {
return fallback;
}
}
function emptyAutomationGuard(): AutomationGuard {
return { ok: false, escapePressed: false };
}
function emptyFocusGenshinResult(): FocusGenshinResult {
return { focused: false, alreadyForeground: false };
}
function emptyClickResult(): ClickResult {
return {
ok: false,
x: 0,
y: 0,
clicked: false,
moved: false,
focused: false,
inputBlocked: false,
};
}
function emptyScrollResult(): ScrollResult {
return { ok: false, notchesSent: 0, inputBlocked: false };
}
function emptyBooleanResult(): BooleanResult {
return { ok: false };
}
export function createRendererRepositories(): RendererRepositories | null {
const bridge = getAssistantBridge();
if (!bridge) return null;
const artifactRepo: ArtifactRepositoryPort = {
loadAll: () =>
createBridgeSafeCall(
() => bridge.loadArtifacts(),
EMPTY_ARTIFACT_STORE_LOAD_RESULT,
),
saveMany: (records) =>
createBridgeSafeCall(
() => bridge.saveArtifacts(records),
EMPTY_ARTIFACT_STORE_SAVE_RESULT,
),
};
const captureRepo: CaptureRepositoryPort = {
listSources: () => createBridgeSafeCall(() => bridge.listCaptureSources(), EMPTY_CAPTURE_SOURCE_LIST),
captureSource: (sourceId, delayMs, focusGenshin, options) =>
bridge.captureSource(sourceId, delayMs, focusGenshin, options),
};
const runtimeRepo: RuntimeRepositoryPort = {
getRuntimeInfo: () =>
createBridgeSafeCall(
() => bridge.getRuntimeInfo(),
EMPTY_RUNTIME_INFO,
),
};
const reviewSamplesRepo: ReviewSampleRepositoryPort = {
loadSamples: (limit = 50) =>
createBridgeSafeCall(
() => bridge.loadReviewSamples(limit),
EMPTY_REVIEW_SAMPLES_RESULT,
),
saveSample: (sample) =>
createBridgeSafeCall(
() => bridge.saveReviewSample(sample),
EMPTY_SCAN_STATUS_RESULT,
),
};
const learningRepo: LearningRepositoryPort = {
loadRules: () =>
createBridgeSafeCall(
() => bridge.loadScannerLearningRules(),
EMPTY_SCANNER_LEARNING_RULES_RESULT,
),
saveRules: (rules) =>
createBridgeSafeCall(
() => bridge.saveScannerLearningRules(rules),
EMPTY_SAVE_RULES_RESULT,
),
};
const snapshotRepo: SnapshotRepositoryPort = {
load: () => createBridgeSafeCall(() => bridge.loadSnapshot(), EMPTY_SNAPSHOT),
save: (snapshot) => createBridgeSafeCall(() => bridge.saveSnapshot(snapshot), EMPTY_SAVE_RESULT),
runMockScan: () => createBridgeSafeCall(() => bridge.runMockScan(), EMPTY_SNAPSHOT),
publishScannerStatus: (status) =>
createBridgeSafeCall(() => bridge.publishScannerStatus(status), EMPTY_SCAN_STATUS_RESULT),
};
const automationRepo: AutomationRepositoryPort = {
getAutomationGuard: () =>
createBridgeSafeCall(
() => bridge.getAutomationGuard(),
emptyAutomationGuard(),
),
focusGenshin: () =>
createBridgeSafeCall(
() => bridge.focusGenshin(),
emptyFocusGenshinResult(),
),
focusMainWindow: () => createBridgeSafeCall(() => bridge.focusMainWindow(), emptyBooleanResult()),
clickScreen: (x, y) => createBridgeSafeCall(() => bridge.clickScreen(x, y), emptyClickResult()),
scrollScreen: (notches, anchorX, anchorY) =>
createBridgeSafeCall(() => bridge.scrollScreen(notches, anchorX, anchorY), emptyScrollResult()),
onCommand: bridge.onScannerCommand,
};
const overlayRepo: OverlayRepositoryPort = {
show: () => createBridgeSafeCall(() => bridge.showOverlay(), emptyBooleanResult()),
};
const exportRepo: ScanExportPort = {
exportGood: (payload) => createBridgeSafeCall(() => bridge.exportGood(payload), EMPTY_SAVE_RESULT),
};
return {
artifacts: artifactRepo,
capture: captureRepo,
runtime: runtimeRepo,
reviewSamples: reviewSamplesRepo,
learning: learningRepo,
snapshot: snapshotRepo,
automation: automationRepo,
overlay: overlayRepo,
export: exportRepo,
canExportGood: bridge.canExportGood,
canShowOverlay: bridge.canShowOverlay,
canAutoScan: bridge.canAutoScan,
canReviewSamples: bridge.canReviewSamples,
isAvailable: true,
};
}