feat: add erase-all protocol and browse helpers to protocol/client layer
protocol.py:
- SUB_ERASE_ALL_BEGIN = 0xA3, SUB_ERASE_ALL_CONFIRM = 0xA2 (confirmed 4-11-26 MITM)
- SUB_CHANNEL_CONFIG (0x06) data length = 0x24 (36 bytes) in DATA_LENGTHS
- begin_erase_all() — single frame, token=0xFE, response 0x5C
- confirm_erase_all() — single frame, token=0xFE, response 0x5D
- read_event_storage_range() — two-step read (probe+data), token=0xFE
Response last 8 bytes = first/last stored event key; both 0x01110000 after erase
client.py:
- list_event_keys() — browse-mode 1E→0A→1F walk, no waveform download;
returns list of hex key strings; used as fast pre-check before get_events()
- get_events(skip_waveform_for_keys=set())
— for already-seen keys: only 0A+1F(browse), skips 1E-arm/0C/POLL×3/5A entirely
- delete_all_events() — orchestrates the confirmed erase sequence:
0xA3 → 0x1C → 0x06 → 0xA2; logs first/last key from storage range response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>