Probe --json support via nix build --help and parse structured output
when available (robust across Nix versions and locales). Falls back to
the #5 text scraper on older Nix or unexpected payloads, feeding the
same tri-state contract.
Refactor dry-run text parsing into parse_dry_run_text(text, returncode)
so an empty set (warm cache) is distinct from None (unparseable). Only
None triggers the cold-cache whole-closure fallback in cli.py; an empty
set now correctly reports 'nothing to build'.