Metadata-Version: 2.4
Name: cuere
Version: 0.1.0
Summary: QR codes in your terminal: Unicode half-block rendering, Rich integration, wallet-URI helpers
Keywords: qr,qrcode,terminal,tty,cli,wallet,walletconnect
Author-Email: Ivan Anishchuk <ivan@agorism.org>
License-Expression: CC0-1.0
License-File: LICENSE.md
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Terminals
Classifier: Topic :: Multimedia :: Graphics
Classifier: Typing :: Typed
Project-URL: Homepage, https://github.com/IvanAnishchuk/cuere
Project-URL: Repository, https://github.com/IvanAnishchuk/cuere
Project-URL: Issues, https://github.com/IvanAnishchuk/cuere/issues
Project-URL: Changelog, https://github.com/IvanAnishchuk/cuere/blob/main/CHANGELOG.md
Project-URL: Security, https://github.com/IvanAnishchuk/cuere/blob/main/SECURITY.md
Requires-Python: >=3.13
Requires-Dist: segno>=1.6.1
Requires-Dist: typer>=0.16
Requires-Dist: rich>=13.0
Description-Content-Type: text/markdown

# cuere

[![PyPI](https://img.shields.io/pypi/v/cuere)](https://pypi.org/project/cuere/)
[![test](https://github.com/IvanAnishchuk/cuere/actions/workflows/test.yml/badge.svg)](https://github.com/IvanAnishchuk/cuere/actions/workflows/test.yml)
[![lint](https://github.com/IvanAnishchuk/cuere/actions/workflows/lint.yml/badge.svg)](https://github.com/IvanAnishchuk/cuere/actions/workflows/lint.yml)
[![typecheck](https://github.com/IvanAnishchuk/cuere/actions/workflows/typecheck.yml/badge.svg)](https://github.com/IvanAnishchuk/cuere/actions/workflows/typecheck.yml)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/IvanAnishchuk/cuere/badge)](https://scorecard.dev/viewer/?uri=github.com/IvanAnishchuk/cuere)

QR codes in your terminal — the way Claude Code CLI draws its remote-connection
codes: Unicode half-blocks, low error correction so the code stays small, a
proper quiet zone. Plus a [Rich](https://github.com/Textualize/rich) renderable
and helpers for crypto-wallet URIs.

```
█▀▀▀▀▀█ ▄▀ ▄▀ █▀▀▀▀▀█
█ ███ █ ▄▀ ▄  █ ███ █
█ ▀▀▀ █ ▄▄█▀█ █ ▀▀▀ █
▀▀▀▀▀▀▀ ▀ █▄█ ▀▀▀▀▀▀▀
█▀█▀▀▄▀▀▀▀  █▀ █ █▄█▄
 ▄▄▄▄▄▀▄▀▀█▀ ▀ ▄█▀  ▀
 ▀▀  ▀▀ ██▀█▄█▄ ▀▄▀▄▄
█▀▀▀▀▀█ ▀▄█▄█▄█▀ ▄▀ █
█ ███ █ █ ▄ █  █  █
█ ▀▀▀ █ █ ▄▀ ▀ ▄█ █ ▄
▀▀▀▀▀▀▀ ▀  ▀ ▀  ▀ ▀
```

## Install

```bash
uv add cuere        # or: pip install cuere
```

## Use

```python
from cuere import render, show, fits

payload = "wc:7f6e504b...@2?relay-protocol=irn&symKey=587d..."
show(payload)                                       # prints to stdout
text = render("HELLO", mode="block", invert=True)   # returns a str
if not fits(payload):                               # does it fit the terminal?
    ...
```

With Rich (centering, panels, layouts):

```python
from rich.console import Console
from rich.panel import Panel
from cuere.rich import QRCode

Console().print(Panel(QRCode("bitcoin:BC1Q..."), title="scan to pay"), justify="center")
```

Wallet URIs — `optimize_uri()` uppercases a fully lowercase `bitcoin:` or
`lightning:` URI (bech32 is case-insensitive per BIP-173) so it encodes in QR
alphanumeric mode, yielding a smaller code. Other schemes (e.g. `ethereum:`,
whose EIP-55 checksums are case-significant), mixed-case URIs, and URIs with
non-alphanumeric query parts are returned unchanged:

```python
from cuere import optimize_uri

optimize_uri("bitcoin:bc1q...")  # -> "BITCOIN:BC1Q..."
```

Need the raw module grid (to render it yourself or inspect it)? Encode to a
`QRMatrix`:

```python
from cuere import QRMatrix

m = QRMatrix.encode("HELLO", error="L", border=4)
m.modules   # tuple[tuple[bool, ...], ...] — True is a dark module
m.size      # side length, quiet zone included
```

CLI:

```bash
cuere "wc:...your walletconnect uri..."
echo "some payload" | cuere
cuere --input payload.txt              # read the payload from a file
cuere 12345 --micro                    # compact Micro QR for a tiny payload
cuere HELLO --mode ansi --invert --border 2 --error M
```

### Rendering modes

| mode | one module is | width of a v2 code | notes |
|---|---|---|---|
| `half` (default) | ½ character (`▀▄█`) | 33 cols | survives copy-paste; inherits terminal colors |
| `ansi` | ½ character, forced black-on-white | 33 cols | theme-proof; falls back to `half` when piped or `NO_COLOR` is set |
| `block` | 2 characters (`██`) | 66 cols | most font-robust, twice as wide |

The block-drawing glyphs (`█▀▄`) are East-Asian *Ambiguous* width: a terminal
configured to render those double-width will widen the output, so the column
counts above assume standard single-width rendering.

### Scanning notes

- On dark terminals the default mode shows an *inverted* code (light modules
  on dark). Modern phone cameras handle this; for a stubborn scanner pass
  `invert=True` / `--invert`, or use `mode="ansi"` for spec-correct polarity.
- Error correction defaults to `L`: screens don't get dirty or torn, and
  lower correction means a smaller code that fits your terminal.
- The quiet zone (4 modules) is part of the output on purpose — don't strip
  the "blank" margins.

## Development

```bash
uv sync                  # editable install via meson-python
uv run pytest            # 100% branch coverage enforced
uv run ruff check && uv run mypy src/ tests/ && uv run ty check && uv run basedpyright
uv run pre-commit install --install-hooks
```

Build-system notes (meson-python):

- Every shipped file must be listed in `src/cuere/meson.build` — meson does
  not glob. `tests/test_packaging.py` fails if the list drifts.
- The version lives only in the root `meson.build`.
- sdists are produced from *committed* files (`meson dist`); commit before
  `uv build`.

## License

[CC0-1.0](LICENSE.md) — public domain.
