- Add extract_table_blocks() to split a document into contiguous table
blocks, ignoring prose, headings, and blank lines between them
- Add parse_document() as the new top-level entry point that runs
extract_table_blocks + detect_has_duration_column + parse_table per
block and returns a combined flat list of rows
- Guard against empty End cells (e.g. in-progress rows) by validating
the end field before calculating duration
- Update cli.py to use parse_document() instead of the manual
detect + parse combo
- Add tests for extract_table_blocks and parse_document, including two
smoke tests against the real 2026-W21 weekly timesheet file