Skip to main content

Standalone CLI for Paperang thermal printers

Project description

paperang-cli

CI PyPI version npm version Python versions License: MIT Hardware tested on Windows

paperang-cli is a standalone command-line tool and Python package for working with Paperang thermal printers.

It provides a small, script-friendly CLI for discovering a printer, checking its status, and printing text or images with explicit safety gates. JSON output is available for automation and agent-driven workflows.

The package also exposes a model-aware Python API surface. Today that means supported PaperangP1 and PaperangP2 facades plus a read-only API catalog for inspecting each shipped model contract.

Current Support

The current release ships two supported models with different validation levels:

Printer Transport Status
Paperang P1 Bluetooth Low Energy (BLE) Supported
Paperang P2 USB + Bluetooth Low Energy (BLE) Supported in software; not physically validated in this repo yet

Local, cable, and USB data transports are not supported for Paperang P1 in this package.

Real printer communication and physical printing have been tested only on Windows for validated paths. CI runs compatibility checks on Linux and macOS, but those checks do not prove BLE, USB, or printer behavior on those platforms.

Features

  • Discover supported Paperang printers over BLE, or detect a connected P2 over USB
  • Check battery level, Bluetooth MAC address, and live printer status
  • Print short text or wrapped paragraphs
  • Print local images with sticker and photo conversion presets
  • Configure default print styling through JSON config, including font family and 90-degree text or image orientation
  • Compose text and an image into one print job
  • Preview every print path with --dry-run
  • Emit machine-readable JSON with --json
  • Use explicit allow flags before any paper-consuming operation
  • Use the PaperangP1 and PaperangP2 Python facades for library-style automation
  • Inspect model-specific API availability with paperang api list

Image and composed printing are available, but remain experimental until you validate physical output on your printer.

Installation

Python 3.10 or newer is required.

Install the published package from PyPI:

python -m pip install paperang-cli

For local development, clone the repository and install it in editable mode:

git clone https://github.com/wyrtensi/paperang-cli.git
Set-Location "paperang-cli"
python -m pip install -e ".[dev]"
python -m pytest

The package installs two equivalent commands:

  • paperang
  • paperang-cli

Use paperang by default. Use paperang-cli if the shorter command conflicts with another executable on your system.

An npm wrapper is also maintained under npm/. Install it globally with:

npm install --global paperang-cli

The npm wrapper installs the matching Python package from PyPI and exposes the same two commands. Python 3.10 or newer is still required.

The published dependency set includes the upstream paperang-p2-lib runtime so P2 USB and BLE support install with the main package.

The npm wrapper uses a postinstall lifecycle script to run pip install for the matching Python package version. See the security policy for details and an --ignore-scripts audit path.

Agent Skill

This repository includes a portable Agent Skill at skills/paperang-cli/ and a synchronized repository-local copy at .agents/skills/paperang-cli/.

GitHub Copilot discovers it automatically when working from a repository checkout. The same skill can be installed as a personal skill for Codex, Claude Code, GitHub Copilot, and other Agent Skills-compatible clients.

With GitHub CLI 2.90.0 or newer, preview the skill before installation:

gh skill preview wyrtensi/paperang-cli paperang-cli
gh skill install wyrtensi/paperang-cli paperang-cli --agent universal --scope user

GitHub CLI may note that one hidden skill was excluded. That is expected: .agents/skills/paperang-cli/ is the synchronized checkout-local copy, while skills/paperang-cli/ is the public installation source.

GitHub CLI supports host-specific installation for many editors and coding agents. Replace universal with a value such as codex, claude-code, github-copilot, cursor, antigravity, gemini-cli, windsurf, or another value listed by gh skill install --help.

Skills installed through GitHub CLI include source metadata, so they can be checked and updated later:

gh skill update paperang-cli --dry-run
gh skill update --all

The repository also includes a small Python fallback installer for common personal locations. From a cloned repository:

python scripts/install-agent-skill.py --target all

Install directly from GitHub on Windows PowerShell:

irm https://raw.githubusercontent.com/wyrtensi/paperang-cli/main/scripts/install-agent-skill.py | py -3 - --source github --target all

Install directly from GitHub on Linux or macOS:

curl -fsSL https://raw.githubusercontent.com/wyrtensi/paperang-cli/main/scripts/install-agent-skill.py | python3 - --source github --target all

Use --target codex, --target claude, --target copilot, --target cursor, --target windsurf, --target opencode, --target antigravity, --target gemini, or --target agents to install only one personal copy. --target all installs the complete skill directory into all nine personal locations, even when a matching editor is not currently installed. Existing copies are preserved unless --force is provided. Restart the agent client after installation.

You can also ask an agent:

Install the paperang-cli Agent Skill from:
https://github.com/wyrtensi/paperang-cli/tree/main/skills/paperang-cli

The skill is available on all operating systems. Real BLE communication and physical printing remain tested only on Windows.

Safe First Run

Start with commands that do not consume paper:

paperang --json config show
paperang --json discover
paperang --json probe
paperang --json battery

Before a real print, run the matching command with --dry-run:

paperang --json print text "Hello from Paperang" --dry-run

After checking the result, explicitly allow paper use:

paperang --json print text "Hello from Paperang" --allow-paper-use

Keep the content, image, layout, conversion mode, font size, min-font-size, font-fit mode, font family, orientation, autofit intent, and feed options the same between dry-run and the real print.

Smart Layout Presets

The CLI can load a per-invocation JSON payload with --style-json. That payload can select a built-in preset and add structured overrides without changing your saved config.

For human-oriented workflows, treat built-in scenarios as reusable bases, not fixed modes. Start from the nearest scenario when one fits, then override only the fields needed for the current task. Reserve persistent print_defaults changes for explicit requests to make that behavior the default for future jobs.

For text, paragraph, and compose jobs, set "font_fit": "largest-fitting" and omit or clear font_size to let the renderer start large and shrink to the biggest fitting size automatically.

break_long_words is now opt-in. Leave it false to keep wrapping on whole words and let largest-fitting shrink a long token onto one line; set it to true only when you want forced character-chunk splitting.

As a practical rule, labels and tags often benefit from largest-fitting, while notes and lists usually read better with ordinary whole-word wrapping. If you are driving the CLI through an agent, the agent should explain the choice in human terms such as readability, glanceability, and approximate strip length.

Ready-to-copy copies of these payloads ship in skills/paperang-cli/examples/ inside this repository, and the installed Agent Skill bundle carries the same files under examples/ next to SKILL.md.

Useful ordinary home scenarios now include broader note presets like fridge-note and chore-list, plus label-style presets such as pantry-label, cable-tag, and storage-bin.

Address label example:

{
	"preset": "address-label",
	"paragraph": {
		"font_size": null,
		"min_font_size": 14,
		"font_fit": "largest-fitting",
		"max_length_mm": 75.0,
		"overflow_policy": "shrink-to-fit",
		"break_long_words": false
	}
}
paperang --json print paragraph "221B Baker Street London" --dry-run --style-json .\address-label.json

Home pantry label example:

{
	"preset": "pantry-label",
	"paragraph": {
		"max_length_mm": 65.0,
		"overflow_policy": "shrink-to-fit",
		"break_long_words": false
	}
}
paperang --json print paragraph "PASTA" --dry-run --style-json .\pantry-label.json

General fridge note example:

{
	"preset": "fridge-note",
	"paragraph": {
		"font_size": null,
		"min_font_size": 14,
		"font_fit": "largest-fitting",
		"max_length_mm": 120.0,
		"line_spacing_px": 2,
		"overflow_policy": "shrink-to-fit",
		"break_long_words": false
	}
}
paperang --json print paragraph "Buy milk\nFruit\nBread" --dry-run --style-json .\fridge-note.json

Long logo strip example:

{
	"preset": "logo-strip",
	"image": {
		"fit_mode": "fit-within-length",
		"max_length_mm": 70.0
	}
}
paperang --json print image .\banner.png --dry-run --style-json .\logo-strip.json

Composed badge example:

{
	"compose": {
		"font_family": "mono",
		"font_size": null,
		"min_font_size": 14,
		"font_fit": "largest-fitting",
		"layout": "image-above",
		"image_mode": "photo",
		"max_length_mm": 55.0,
		"overflow_policy": "report-only",
		"break_long_words": false
	}
}
paperang --json print compose "Product title" .\badge.png --dry-run --style-json .\product-style.json

When a dry-run uses length-aware styling, the JSON result can include estimated_length_mm, max_length_mm, and fits_length_limit so you can decide whether to print before consuming paper.

Python API

paperang-cli also ships model-aware Python facades for PaperangP1 and PaperangP2.

from paperang_cli import PaperangP1, PaperangP2

p1 = PaperangP1(address="04:7F:0E:3A:4F:31")
p2 = PaperangP2(transport="usb")

p1.connect()
status = p2.get_status()
preview = p2.print_text("Hello from Paperang", dry_run=True)

See Paperang P1 Python API for the P1 facade and Paperang P2 Python API for transport selection, supported methods, safety semantics, and current parity gaps versus paperang-p2-lib.

Use the installed CLI to inspect what is actually available in the current package version:

paperang --json api list
paperang --json api p1
paperang --json api p2

Printing

Text

paperang --json print text "Shipping label" --dry-run
paperang --json print text "Shipping label" --allow-paper-use

Use rotated label rendering when you want text to run along the paper path:

paperang --json print text "Long shipping label" --dry-run --orientation rotate-90-cw --font-family mono --autofit

Paragraph

paperang --json print paragraph "A longer wrapped note for the printer." --dry-run
paperang --json print paragraph "A longer wrapped note for the printer." --allow-paper-use

Preset-driven label flow:

paperang --json print paragraph "221B Baker Street London" --dry-run --style-json .\address-label.json

Image

Use --mode sticker for logos, icons, and line art:

paperang --json print image ".\sample.png" --dry-run --mode sticker
paperang --json print image ".\sample.png" --allow-paper-use --mode sticker

Use --mode photo as a starting point for photographs and smoother grayscale content:

paperang --json print image ".\photo.jpg" --dry-run --mode photo

You can also rotate an image 90 degrees before it is fit to the P1 width:

paperang --json print image ".\label.png" --dry-run --orientation rotate-90-ccw

For long banners or logo strips, pair a preset with a physical length budget:

paperang --json print image ".\banner.png" --dry-run --style-json .\logo-strip.json

Image quality depends on the source file and printer. A successful dry-run validates conversion and packaging, not the final paper output.

Compose

print compose combines wrapped text and an image in one vertical layout:

paperang --json print compose "Product label" ".\sample.png" --dry-run --mode sticker
paperang --json print compose "Product label" ".\sample.png" --allow-paper-use --mode sticker

Use --layout image-above when the image should be printed before the text:

paperang --json print compose "Product label" ".\sample.png" --dry-run --layout image-above

The same command can be driven by a JSON payload when you want a repeatable composed layout profile:

paperang --json print compose "Product label" ".\sample.png" --dry-run --style-json .\product-style.json

Compose printing uses the same experimental image conversion pipeline as print image.

Rotated compose printing is not implemented yet. print compose still uses the ordinary vertical layout path in the current release.

Built-In Self-Test

The printer self-test consumes substantially more paper than an ordinary print. Use it only when you explicitly want the printer's built-in diagnostic page:

paperang --json print self-test --dry-run
paperang --json print self-test --allow-large-paper-use

The self-test dry-run only validates the CLI path and warning payload. It does not query hidden hardware state.

Commands

Command Purpose
paperang discover Scan for nearby supported printers
paperang api list List known model-specific Python API entries and their availability
paperang api p1 Show the supported PaperangP1 Python API contract
paperang api p2 Show the supported PaperangP2 Python API contract
paperang battery Query the current battery percentage
paperang mac Query the printer-reported Bluetooth MAC address
paperang status Query live printer information
paperang probe Return a combined readiness summary
paperang print text Print a short text block
paperang print paragraph Print wrapped text
paperang print image Print a local image
paperang print compose Print text and an image as one job
paperang print self-test Print the built-in diagnostic page
paperang config show Show the resolved config and active settings
paperang config path Show the resolved config path
paperang config init Write an example config file

Run paperang --help or paperang <command> --help for the available options.

Configuration

Inspect the active config:

paperang --json config show

Create an example config:

paperang config init

Configuration is resolved in this order:

  1. --config PATH
  2. PAPERANG_CLI_CONFIG
  3. the per-user default config path
  4. built-in defaults

Default paths:

  • Windows: %APPDATA%\paperang-cli\paperang-cli.config.json
  • Linux and macOS: $XDG_CONFIG_HOME/paperang-cli/paperang-cli.config.json, or ~/.config/paperang-cli/paperang-cli.config.json

See Configuration for the full schema.

Documentation

Project History And Acknowledgements

The Paperang P1 logic in this standalone CLI builds on earlier reverse engineering and printer-control work by:

  • ihc童鞋@提不起劲
  • BroncoTc

Paperang P2 support in this repository uses mdj2812/paperang-p2-lib and references mdj2812/paperang-p2-usb. The USB and BLE code paths are implemented in software, but this repository has not yet physically validated P2 hardware on either path.

The current paperang-cli package is maintained by wyrtensi.

License

This package is available under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paperang_cli-0.1.8.tar.gz (61.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paperang_cli-0.1.8-py3-none-any.whl (58.3 kB view details)

Uploaded Python 3

File details

Details for the file paperang_cli-0.1.8.tar.gz.

File metadata

  • Download URL: paperang_cli-0.1.8.tar.gz
  • Upload date:
  • Size: 61.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for paperang_cli-0.1.8.tar.gz
Algorithm Hash digest
SHA256 beb2c9b4b88cb3dc523da86bd60f9a74369fc27d2f0fd22eeefa89c1000d3e85
MD5 68839f9089f7ff91acda00118a2dcf01
BLAKE2b-256 666f2cebffc92a95174fd5d4bdfff499a352d204278aec0182f0de2d43be88e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for paperang_cli-0.1.8.tar.gz:

Publisher: pypi-publish.yml on wyrtensi/paperang-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file paperang_cli-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: paperang_cli-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 58.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for paperang_cli-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 181c59e4559dde9a3301a13988dfa783d7b0acd65b0f19998761b50376317f8f
MD5 2237ef5f44b769c5306ee86a8e3cbb87
BLAKE2b-256 2d3cf39e40a817d344e925b4cefcc9485884f82b81e812539accf24a3c76a198

See more details on using hashes here.

Provenance

The following attestation bundles were made for paperang_cli-0.1.8-py3-none-any.whl:

Publisher: pypi-publish.yml on wyrtensi/paperang-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page