Both configure pages were one long form: a field you wanted to change
meant re-submitting everything, and the options page rendered the apps
map as `[object Object]`.
Verified against a real Home Assistant install (not assumed): the HTTP
flow view serialises a field's suggested value verbatim, so a dict handed
to a `type: string` field reaches the browser as a non-string; and real
HA validates a submitted page against the schema the step returned, where
the built-in EntitySelector rejects `''` and `None`.
- The options flow is a MENU (Main setup / Receiver / Apps / Scripts /
Save and close). Each sub-screen owns a disjoint set of keys and merges
into one pending dict under a single rule: a key the submission CARRIES
is authoritative (empty clears), a key it does not carry is untouched.
The per-command script dict is rebuilt from the submitted script fields,
so unsetting one persists instead of surviving as a stale key.
- The sub-screen step_id IS the menu row id. Real HA dispatches a menu
choice and a submitted form by that same name, so a mismatch is an
UnknownStep or an unsubmittable page (the setup menu first tried a
"setup_menu" step id and dead-ended in real HA).
- The apps map reaches the suggestion layer serialized to the documented
`package=name[|icon]` lines, and parses back to both maps.
- The setup flow keeps its first form and gains a menu after it; pairing
completion returns to the menu, and the "ADB then protocol" sequence
still happens automatically.
- Receiver accepts a `switch.*` as well as a media_player.
Tests: 522 pass on stubs, and tests/test_config_flow_real_ha.py drives
the real FlowManager + probatio + to_field_list; 53 + 11 of those fail on
the pre-fix tree.