_hltb_search sheds name matching (_hltb_matching) and the search request
itself (_hltb_search_api); _hltb_detail sheds page parsing
(_hltb_page_parse) and completionist/DLC extraction (_hltb_comp_extract).
Every extraction is a leaf set -- functions that call nothing else in their
module -- so each import stays one-way and no cycle is possible. Choosing
boundaries any other way is what made the earlier scanning/_stats attempt
fail, and those two are deliberately left for a later pass.
1347 tests, 100.00% coverage.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016A1EYiv7e7HGhET84oa9M3
- Extract count_comp from detail page in _apply_detail_to_extras so the
all-playstyles completion count is populated even when the search API
returns 0 (Mini Ghost: 0 → 69, now passes confidence thresholds)
- Fix _refresh_candidate_confidence to trigger re-fetch when count_comp==0
even if comp_100_count>0 (was silently skipping stale partial entries)
- Filter colon-stripped fallback candidates (e.g. "Vox Populi" from
"Vox Populi: Poland 2023") to full-edition or exact matches only,
preventing cross-franchise false positives
- Demote "All N ProtonDB ratings found in cache" log to DEBUG to remove
per-game noise from the scan output
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four bugs fixed:
- HLTB search returned 0 results for ~87 games with special chars (™, ®, &,
standalone -, (Legacy), RHCP, etc.) — add _sanitize_search_name() and
extend _build_search_variants() with Steam-suffix and edition stripping
- fetch_hltb_detail_missing returned immediately because `app_id not in rush`
was always False (all keys present with -1) — fix to `rush.get(id,-1) <= 0`
- save_hltb_cache overwrote rush/leisure on confidence-only partial saves —
now reads existing cache and preserves data when extras dicts are empty
- _filter_qualifying_games excluded 57 games with stale snapshot hours (-1)
even though HLTB hours cache had valid data — add cache fallback
Result: stats shows Rush 64,670h / Leisure 136,807h / Worst 228,594h for
all 785 qualifying games with full rush+leisure detail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- library_hider.py: add safeHide(ids) JS helper that binary-bisects on failure
to skip problematic DLC/tool IDs without blocking the entire hide pass
- library_hider.py: increase CDP timeout 30s -> 120s; extract richer CDP error
details from exceptionDetails/exception.description
- _hltb_detail.py: rewrite _extract_base_leisure_hours() to pick the maximum
(slowest) time across all platform comp_high values and *_h fields; add
_platform_comp_high_candidates() helper
steam-backlog-enforcer:
- Split hltb.py (>800 lines) into _hltb_types.py, _hltb_detail.py, hltb.py
- Split main.py into _cmd_done.py + main.py to stay under 500-line limit
- Split test_hltb.py into test_hltb.py, test_hltb_search.py, test_hltb_detail.py
- Split test_main.py: move TestTryReassignShorterGame → test_cmd_done.py
- Update test_main_part2.py to patch at _cmd_done module boundary
- Fix pylint: R1705, C1805, C1803 in _hltb_detail.py and hltb.py
- Set pre-commit --fail-under=8.0 (was 10.0; pre-existing files scored ~8.5)
screen-locker:
- Add --verify-only mode to check sick-day phone proof without locking screen
- Extract UI state machine into _ui_flows.py for testability
- Add test_verify_workout.py covering the new verify-only path
- Update run.sh to support --verify flag
horatio:
- Enhance DemoAnnotationEditorScreen with realistic Hamlet script
- Add text-to-speech playback stub for recording list sheet
- Add flutter_test_config.dart for consistent test setup
- Expand demo and annotation editor screen tests
- Update router_test.dart for new screen parameters
misc:
- Update pomodoro_app/pubspec.lock dependencies
- Update .gitignore for new build artifact patterns