Refactor report pipeline: redesign HTML, add motion alignment, remove legacy reporter

- scripts/generate_cutter_report.py: complete HTML redesign with glassmorphism
  dark-mode style, compare video links in markdown output
- cli.py: cmd_report now calls _regenerate_cutter_report directly; also writes
  legacy match_report.html; removes dependency on src/pipeline/reporter.py
- src/cv/global_scan.py: add motion-phase alignment refinement step after
  initial in-point search (align_in_point_by_motion, threshold +0.015)
- Remove HANDOVER.md and src/pipeline/reporter.py (superseded)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Melbar
2026-05-06 12:44:10 +02:00
parent 3b90905d07
commit 45769aa366
5 changed files with 216 additions and 655 deletions
+12 -12
View File
@@ -149,7 +149,12 @@ def _regenerate_cutter_report(cfg: "AppConfig") -> None: # type: ignore[name-de
md, html = render_report(project_root, with_stills=True, with_clips=True)
(project_root / "CUTTER_REPORT.md").write_text(md, encoding="utf-8")
(project_root / "CUTTER_REPORT.html").write_text(html, encoding="utf-8")
logging.getLogger(__name__).info("Cutter report regenerated (md + html + compare clips)")
legacy_report_path = project_root / "output" / "report" / "match_report.html"
legacy_report_path.parent.mkdir(parents=True, exist_ok=True)
legacy_report_path.write_text(html, encoding="utf-8")
logging.getLogger(__name__).info("Cutter report regenerated (md + html + compare clips + legacy match_report.html)")
except Exception as exc:
logging.getLogger(__name__).warning("Cutter report regen failed: %s", exc)
@@ -1890,17 +1895,12 @@ def cmd_rematch(args: argparse.Namespace, cfg) -> None:
def cmd_report(args: argparse.Namespace, cfg) -> None:
from src.pipeline.reporter import generate_report
beats = _select_beats(_load_beats(cfg), getattr(args, "beat", None))
beat_ids = {b.beat_id for b in beats} if getattr(args, "beat", None) is not None else None
results = _select_results(_normalize_cached_results(_load_beats(cfg), _load_results(cfg), cfg), beat_ids)
out = generate_report(beats, results, cfg)
if getattr(args, "beat", None) is not None and not results:
print(
f"\n⚠️ Beat {args.beat} has no cached match yet. "
f"Run: python cli.py match --beat {args.beat}"
)
print(f"\n\u2705 Report \u2192 {out}")
if getattr(args, "beat", None) is not None:
print(f"\n⚠️ Generating cutter report for all beats (ignoring --beat {args.beat}).")
_regenerate_cutter_report(cfg)
project_root = cfg.paths.cache_dir.parent
print(f"\n✅ Report → {project_root / 'CUTTER_REPORT.html'} and CUTTER_REPORT.md")
def cmd_export(args: argparse.Namespace, cfg) -> None: