build(rawcli): make prompt_toolkit a core dependency + document rawcli

`pm3py rawcli` is a headline tool, so prompt_toolkit moves from the
[rawcli] extra into core dependencies — a plain `pip install` gets it and
the command just works. The extra is removed; the missing-module guard now
points at a reinstall (it only fires on a broken env).

README: add the rawcli feature bullet, a dedicated "pm3py rawcli"
section (breadcrumb, entry toggle, identify, function-style commands, live
trace, TLV, completion), prompt_toolkit in the dependency list, and cli/
in the architecture tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-14 12:25:52 -07:00
parent 3e7f47a740
commit 5f57cc4202
3 changed files with 44 additions and 6 deletions

View File

@@ -7,6 +7,7 @@ Pure-Python async client for the [Proxmark3](https://github.com/RfidResearchGrou
- **Async-first, REPL-friendly** — `async`/`await` core with a synchronous proxy (`Proxmark3.sync()`) that supports `dir()`, `help()`, and tab-completion.
- **Live sniff & simulation** — stream decoded reader↔tag frames into your REPL in real time; edit an emulated tag and push it live.
- **Software-defined tags** — pure-Python transponder models (ISO 14443-A, ISO 15693, MIFARE Classic, NTAG/Type-2, NXP ICODE/SLIX2/NTAG5, LF) served from a firmware response table.
- **Interactive raw console** — [`pm3py rawcli`](#pm3py-rawcli--interactive-raw-command-console) drops into a Proxmark-style TUI for raw command entry: a live annotated trace, hex/binary toggle, and function-style transponder commands.
## Install
@@ -19,8 +20,8 @@ cd pm3py
pip install -e . # or `pip install .`
```
Requires **Python 3.10+**; dependencies (`pyserial-asyncio`, `bitarray`, `pycryptodome`)
install automatically. It's pure Python + pyserial, so it also runs on a **Raspberry Pi**
Requires **Python 3.10+**; dependencies (`pyserial-asyncio`, `bitarray`, `pycryptodome`,
`prompt_toolkit`) install automatically. It's pure Python + pyserial, so it also runs on a **Raspberry Pi**
(aarch64) — see [Flashing firmware](#flashing-firmware-pm3flash) for the Pi bring-up.
## Quick Start
@@ -489,6 +490,43 @@ method (`pm3.hf.dropfield()`) for those.
> method names, and signatures (e.g. `rdbl(block, uid=None)`) instead of an opaque
> `(*args, **kwargs)` wrapper.
## `pm3py rawcli` — interactive raw-command console
`pm3py rawcli` opens an interactive, Proxmark-style console for driving a connected device at the
raw level — a live annotated trace, flexible hex/binary entry, and function-style transponder
commands. It's a **separate tool from the Python REPL**: its own command grammar, not Python.
```bash
pm3py rawcli # auto-detect the device (runs offline if none attached)
```
```text
[raw / 0x] identify # probe the field; sets HF/LF + transponder, keeps the link
NTAG213 (HF / 14a) UID 04A1B2C3
[raw / hf / NTAG213 / 0x] READ(4) # function-style command from the tag's catalog
[Rdr] Reader → Tag: 30 04 READ page 4
[Rdr] Tag → Reader: 01 02 03 04 …
[raw / hf / NTAG213 / 0x] 30 04 # …or send raw bytes directly
[raw / hf / NTAG213 / 0x] tlv 00 03 09 D1 01 05 54 02 65 6E 48 69 FE # decode a TLV / NDEF block
```
- **Breadcrumb prompt** `[raw / hf|lf / <transponder> / 0x|0b]` reflects the field, the identified
tag, and the current numeric entry mode.
- **Entry modes** — type hex (`30 04`) or binary; **Ctrl-/** toggles `0x`/`0b`, digits auto-group
into bytes, and `0x`/`0b` prefixes can be intermixed on one line.
- **`identify`** probes 14a → 15693 → LF and keeps the tag selected; **`transponder`** / **`close`**
manage the connection.
- **Function-style commands** — `READ(4)`, `GET_VERSION()`, `WRITE(4, 0x01020304)` from the
identified tag's catalog (Type 2 / MIFARE Classic / ISO 15693 seeded). `help` lists them,
`help READ` shows one.
- **Live annotated trace** — every exchange prints the reader↔tag frames with decoded annotations.
- **TLV / NDEF** — `tlv <hex>` prints a structured multi-line breakdown; a multi-line editor
composes long TLVs.
- **ipython-style completion** — command/argument menus with each command's help as the tooltip,
plus history auto-suggestion.
## Firmware Compatibility
On connect, pm3py pings the device and fetches the firmware version. The result is on
@@ -581,6 +619,7 @@ pm3py/
│ ├── decode_iso14a.py / decode_iso15.py # per-protocol decoders
│ ├── ndef.py # NDEF TLV/record decode
│ └── format.py # ANSI color trace formatting
├── cli/ # `pm3py` console-script: rawcli (interactive raw-command TUI)
├── sniff/ # SniffSession — protocol detection, live streaming lifecycle
├── sim/ # card-sim infrastructure: SimSession, response-table compiler,
│ # Medium/Reader models, MCU bridge, replay/relay/fuzzer