format_cutlist now renders from build_cut_plan(scene) via a new
format_plan_cutlist(plan), instead of its own board-feet/shopping math. The CLI,
voice, and BOM window all read the same CutPlan now, so they can't disagree —
and kerf, sanding allowance, species, offcut reuse, and unplaced warnings all
surface in the text cut list automatically.
- cut_rows/shopping/board_feet kept (still used elsewhere) but no longer back
the text renderer.
- Output shape preserved (CUT LIST / Total / SHOPPING) plus species labels,
rough→final lines, and a WON'T FIT section.
- tests: CLI shopping counts == BOM CutPlan counts (kerf case), species +
sanding surfaced, unplaced flagged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>