feat(rawcli): render page-argument completion in the active entry mode

The memory-map completion for a page/block argument now follows the entry mode instead of
always emitting hex:

  hex mode     READ(  -> 0x04        user memory
  binary mode  READ(  -> 0b00000100  user memory   (full 8 bits — each bit visible)

Matching narrows in the same base (a binary partial filters bit-prefix-wise), and a 0x/0b
prefix on the argument overrides the session mode. Binary matters here because for the config
pages each bit carries its own meaning (CFG0 AUTH0, CFG1 PROT/CFGLCK/AUTHLIM), so seeing the
whole pattern is the point.

Hardware-verified against a real NTAG216 in binary mode (0b00000000..0b11100110 with roles).
Tests for binary rendering, bit-prefix filtering, and prefix-override. 1271 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-15 16:29:37 -07:00
parent b6fdb7bca4
commit c53c087e84
2 changed files with 41 additions and 6 deletions

View File

@@ -541,6 +541,25 @@ class TestCompleter:
s.protocol, s.transponder = "hf14a", "MIFARE Classic 1K" # no page layout
assert self._complete(s, "READ(") == []
def test_page_arg_binary_mode(self):
# in binary entry mode the landmarks render as full 8-bit values (each bit visible)
s = RawSession()
s.protocol, s.transponder = "hf14a", "NTAG216"
s.entry_mode = "bin"
by_text = {c.text: c.display_meta_text for c in self._complete(s, "READ(")}
assert by_text["0b00000100"] == "user memory" # 0x04
assert "PWD" in by_text["0b11100101"] # 0xE5
assert "0x04" not in by_text # not hex form in binary mode
# a binary partial filters bit-prefix-wise
assert [c.text for c in self._complete(s, "READ(0b111001")] == \
["0b11100100", "0b11100101", "0b11100110"] # 0xE4..0xE6
def test_page_arg_prefix_overrides_mode(self):
# a 0b prefix forces binary rendering even though the session is in hex mode
s = RawSession()
s.protocol, s.transponder = "hf14a", "NTAG216" # default hex
assert [c.text for c in self._complete(s, "READ(0b000001")] == ["0b00000100"]
class TestMemoryHint:
def _sess(self, tp="NTAG213"):