""" FormScout headless CLI entrypoint. Usage: python -m formscout.run sample.mp4 """ from __future__ import annotations import sys import json from pathlib import Path from formscout.pipeline import Director from formscout.rubric import score_test def main(): if len(sys.argv) < 2: print("Usage: python -m formscout.run [test_name] [side]") sys.exit(1) video_path = sys.argv[1] test_name = sys.argv[2] if len(sys.argv) > 2 else "deep_squat" side = sys.argv[3] if len(sys.argv) > 3 else "na" print(f"FormScout — processing: {video_path}") print(f" Test: {test_name}, Side: {side}") print() director = Director() state = director.run(video_path, test_name=test_name, side=side) # Print pipeline state if state.errors: print("ERRORS:") for e in state.errors: print(f" ✗ {e}") print() if state.warnings: print("WARNINGS:") for w in state.warnings: print(f" ⚠ {w}") print() if state.ingest: print(f"Ingest: {len(state.ingest.frames)} frames, {state.ingest.fps:.1f}fps, " f"{state.ingest.duration:.1f}s, {state.ingest.width}x{state.ingest.height}") if state.pose2d: n_detected = sum(1 for kps in state.pose2d.keypoints if kps) print(f"Pose2D: {n_detected}/{len(state.pose2d.keypoints)} frames with detections, " f"confidence={state.pose2d.confidence:.2f}") if state.body3d: print(f"Body3D: used={state.body3d.used}") if state.features: print(f"Biomechanics: view={state.features.view}, " f"confidence={state.features.confidence:.2f}") if state.features.angles: print(f" Angles: {json.dumps({k: round(v, 1) for k, v in state.features.angles.items()}, indent=4)}") if state.features.alignments: print(f" Alignments: {json.dumps(state.features.alignments, indent=4)}") # Score via rubric if state.features and test_name == "deep_squat": score_result = score_test(state.features) print(f"\nSCORE: {score_result.score}/3") print(f" Rationale: {score_result.rationale}") print(f" Confidence: {score_result.confidence:.2f}") if score_result.needs_human: print(" ⚠ NEEDS HUMAN REVIEW") # Judge result if state.judge: print(f"\nJUDGE: score={state.judge.score}, needs_human={state.judge.needs_human}") print(f" Rationale: {state.judge.rationale}") if state.judge.compensation_tags: print(f" Compensations: {state.judge.compensation_tags}") if state.judge.corrective_hint: print(f" Corrective: {state.judge.corrective_hint}") if __name__ == "__main__": main()