Task #5 building blocks, each a pure + unit-tested module:
- goodInterop.ts: GOOD (Genshin Optimizer / Inventory Kamera / Akasha) import and
export for scanned StoredArtifactRecords - slot/stat/set key maps both ways,
substat string <-> { key, value }, main-value reconstruction on import
(ADR-003). Export is lossless; import is best-effort (GOOD lacks piece names).
- artifactMerge.ts: rescan-merge (ADR-006 follow-up). Level-independent identity
(set + slot + main + substat NAME set) collapses leveled re-scan duplicates,
keeping the higher-level/stronger record and summing timesSeen. Conservative:
differing substat lineups never merge.
- dataPackageStatus.ts: warns when the genshin-db package is older than ~45 days
(a patch cycle) so new sets/characters aren't silently missed; surfaced in the
Scanner Diagnose data-package line. Adds dataGeneratedAt to genshinData.
- lockDetection.ts: EXPERIMENTAL read-only lock-status heuristic (gold-pixel
ratio in a top-right icon crop). Pure + tested but not wired into capture; crop
position and threshold need calibration against a reference 16:9 screenshot.
120 tests + build green. Remaining wiring (needs UI / live calibration): GOOD
import/export buttons and live lock detection.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds src/lib/cardReadyGate.ts: after a tile click, poll the detail fingerprint
until it has both changed from the previous artifact and stabilized across
consecutive samples, instead of waiting a hardcoded 280ms and hoping.
- Faster on quick machines (proceeds as soon as the card is stable), correct on
slow ones (waits up to the budget).
- Robust to particle/hover-glow animation: requiring two consecutive equal
samples ignores single-frame noise, and if the card never fully stabilizes it
still proceeds once the content has changed rather than looping on an animated
frame.
- ESC/stop abort is honored between polls via checkAbort.
autoScanLoop now uses waitForCardReady for both the initial read and the one
retry; CLICK_SETTLE_MS removed. 6 new unit tests; 94 total green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implements ADR-009 (structure + preprocessing; exact IK fixed coordinates still
need calibration against a reference 16:9 screenshot).
- src/lib/layoutProfile.ts: pure, unit-tested geometry for the artifact screen -
detail rect, the four detail crops, inventory rect/count crop, 5-col grid,
16:9 detection, aspect label, and an off-16:9 support warning. Single source of
truth; electron/main.ts now delegates all crop/grid geometry to it and keeps
colour detection only as the detail-rect fallback.
- src/lib/ocrPreprocess.ts: pure, unit-tested Otsu binarization with inversion
(artifact text is the bright foreground) over a BGRA bitmap.
- main.ts: OCR now reads an upscaled + binarized copy of each crop; the original
crop is retained for the diagnostics UI. CaptureResult carries layout info
{ aspect, isSixteenNine, warning }.
NOTE: image preprocessing changes the OCR input and cannot be validated by the
text-level eval harness; it needs a live Genshin 16:9 capture to confirm/tune
(threshold, invert, upscale factor). 88 tests + build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implements ADR-008. native/input-helper is a self-contained .NET 9 console exe
speaking the identical JSON-over-stdin/stdout protocol as the old PowerShell
helper (ping/cursor/runtime/focus/click/scroll/bounds/capture), so the
InputHelperService interface is unchanged.
- Win32 interop compiled once (native exe), not per call.
- PerMonitorV2 DPI via manifest so click/capture coordinates stay correct on
mixed-DPI multi-monitor setups.
- capture returns base64 PNG bytes inline (imageBase64) instead of writing a
temp file per frame; the client handles both base64 and the PowerShell path.
- InputHelperClient prefers the exe and falls back to the embedded PowerShell
helper when the exe is absent, so the app still runs without the .NET build.
- main.ts resolves the exe (INPUT_HELPER_EXE env -> packaged resources/input-helper
-> native/input-helper/bin/publish). electron-builder ships it via extraResources.
- npm run helper:build; README documents the build + fallback.
Verified end-to-end through the compiled client: sidecar spawns, runtime info
and a base64 primary-screen capture return correctly. Build stays green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The scan feature had 16 tsc errors from refactor drift; npm run build failed.
- modals/hooks/* are five levels deep but imported ../../../../lib (four);
corrected to ../../../../../lib.
- useScanDiagnosticsModalModel / useScanReviewQueueModalModel picked
saveReviewSample / canSaveReviewSample / loadReviewQueue from the modal Props,
but the components wire those through from controller.*; source them from the
controller type instead (fixes the downstream unknown-type errors).
- useScanResultCardModel let its field-row tuple array widen to
(string | ParsedField)[][]; annotate it Array<[string, ParsedField]> like the
sibling hook.
- ScanTopControlsModel was missing autoScanRunning (destructured by the
component); add it. useScanTopControlsModel does not use refreshCaptureSources,
so its input is Omit<...,"refreshCaptureSources">.
tsc, vite build, and the electron build all pass; 74 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a measurement gate for the artifact OCR parser (ADR-007), the prerequisite
for the layout-profile and preprocessing rework. runOcrEval feeds labeled OCR
text through the real parseArtifactCandidate and scores per-field / per-case
accuracy.
- src/eval/ocrEvalHarness.ts: pure metrics (per-field, critical-field, exact).
- src/eval/corpus/seedCorpus.ts: 23 cases transcribed from the verified parser
test assertions; runs at 100%.
- src/eval/reviewSampleCorpus.ts: converts review samples into label *candidates*
(never ground truth) so the review queue can grow the corpus.
- src/eval/ocrEval.test.ts + reviewSampleCorpus.test.ts: gate (must stay 1.0) and
converter unit tests.
- npm run eval script; docs/ocr-eval.md; ADR-007/008/009.
Also records the agreed rework direction: C# input/capture sidecar (ADR-008) and
resolution-anchored layout profiles + OCR preprocessing (ADR-009).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>