decode.py:
- decode_cat: TERMINAL RESPONSE (0x14) now extracts the proactive
command type from its echoed Command Details (tag 81) — no history
lookup needed since TR carries its own type
- decode_message gains prev param; GET RESPONSE (0xC0) resolves
'response_for' from the previous command when its SW1 was 0x61,
else None (orphaned)
- decode_sniff_msg threads prev through
database.py:
- _row_to_message accepts prev; new _decode_rows tracks previous-TPDU
context in sequence; get_messages/get_messages_after seed context
from the message before the window/cursor
tests: TR cat_command + GET RESPONSE context/orphaned cases (49 total)
decode_sniff_msg() dispatches to type-specific decoders:
- change: 4-byte flags bitmask → card insert/eject/reset/timeout
- fidi: 1-byte Fi/Di index → decoded values
- atr/pps: raw hex value
database.py now decodes all message types, not just tpdu.
Pure Python, no dependencies. Decodes raw TPDU bytes into
structured JSON: CLA bitfield, INS->name via APDU_SPEC table,
P1/P2 field breakdown, body extraction, SW name lookup.
~40 command types, 40+ SW codes, known FID notes.
database.py: _row_to_message() calls decode_message() for tpdu
messages, adding 'decoded' field to API responses.
Decoding happens at query time, not storage time — no schema
migration, all past sessions get decode retroactively.