First slice of `pm3py rawcli` — the interactive, annotated raw-command
tool (separate from pyws and from the future `pm3py client` CLI).
- pm3py/cli: a top-level `pm3py` console-script dispatcher (argparse)
with a `rawcli` subcommand; prompt_toolkit gated behind a [rawcli] extra
- rawcli/session.py: RawSession — device/field/transponder/entry-mode
state + the segmented breadcrumb `[raw / hf|lf / $tag / 0x|0b]`
- rawcli/trace_view.py: render a reader<->tag exchange as annotated,
Proxmark-style trace lines, reusing TraceFormatter + the 14a/15693
decoders
- rawcli/app.py: minimal PromptSession loop (connect best-effort,
breadcrumb prompt, help/quit, raw-hex -> annotated exchange)
Entry-mode toggle, identify/connection, the command catalog, and TLV
editing follow in later phases. 9 hardware-free tests (session, trace
render, CLI dispatch); device I/O is the user's local hardware test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Exposes pm3py as a pyws workspace, discovered via the pyws.plugins entry point:
- ReaderResource: connects/disconnects a Proxmark3 as `reader`; a missing device is
non-fatal (reports disconnected)
- namespace injection of the transponder/sim classes, SimSession and Proxmark3
- effect declarations so autoreplay/replay withhold writes/field/sim/destructive while
reads and pure model edits replay
Hardware-free tests via AsyncMock. The live `sim` resource is P2.
See docs/plans/2026-07-05-pm3py-pyws-plugin-plan.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the 'is the device running the right firmware, and flash it if not'
layer on top of the flasher.
- _firmware.py: FirmwarePin (pinned to the firmware/ submodule commit) and
matches() — a device version-string test against the pinned git SHA (or a
release tag, once tagged releases exist).
- FirmwareInfo gains expected_firmware + matches_pin, computed on connect, so
pm3.firmware.matches_pin tells you whether the fork build is present.
- pm3flash console-script: auto-detect, compare to the pin, resolve the image
(--image / $PM3PY_FIRMWARE / local build), confirm, flash with progress,
then reopen and verify the new version. Flashes only on mismatch unless
--force; fullimage-only unless --allow-bootrom.
Detection + CLI are unit-tested; the auto-download layer (fetch the pinned
release asset) and hardware validation are still to come. Suite 1034 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add MIT LICENSE (PEP 639 'license = "MIT"' + license-files).
- Move all metadata into a [project] table (description, readme, authors,
keywords, classifiers); drop the now-redundant setup.py.
- Declare bitarray and pycryptodome: used by pm3py.sim and the transponder
crypto paths but previously undeclared, so a clean install failed on the
README's own 'from pm3py.sim import SimSession'.
- gitignore build/ and dist/.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>