Token-optimized TOON output wrapper for any CLI
Project description
cartoon
Token-optimized output for any CLI. Prefix cartoon onto a command and
its output becomes TOON — a compact
structured format built for LLM agents. Same exit codes, same behavior,
~70%+ fewer tokens on test runs.
A cartoon is a compressed rendering of reality. So is this.
Why
Agents (Claude Code, Cursor, Codex, ...) read CLI output formatted for
humans: banners, progress noise, hundreds of PASSED lines. You pay for
every token. cartoon keeps what the agent needs — counts, failures,
tracebacks — and drops the rest.
Install
uv tool install cartoon # or: pipx install cartoon
npm install -g cartoon-wrap # installs the `cartoon` binary
cargo install cartoon
For agents (Claude Code, Codex, Copilot, Cursor, …)
Teach your agent to use cartoon automatically — and to install it when missing — with the skills shipped in this repo:
# Claude Code (plugin)
/plugin marketplace add abhijitbansal/cartoon
/plugin install cartoon@cartoon
# Everything else (skills.sh CLI auto-detects 40+ agents)
npx skills add abhijitbansal/cartoon
Copy-paste blocks for AGENTS.md / copilot-instructions.md and the full integration matrix: docs/agents.md.
Use
cartoon pytest # asymmetric test report in TOON
cartoon jest src/ # same for jest
cartoon python -m unittest # same for unittest
cartoon aws ec2 describe-instances --output json # any JSON CLI → TOON
cartoon --heuristic make # lossy compression for plain text (opt-in)
cartoon --raw pytest # escape hatch: no transformation
cartoon stats --since 7d # how many tokens you've saved
cartoon adapters # list built-in adapters
cartoon --tag api pytest # tag the archived run
cartoon logs # list archived raw logs
cartoon logs --last --stdout # full raw output of the newest run
cartoon --fast pytest # opt-in: parallel via pytest-xdist (-n auto)
Failing test run, before (pytest, ~4800 tokens) vs after (~300 tokens):
runner: pytest
summary:
total: 48
passed: 45
failed: 2
skipped: 1
duration_s: 3.2
failures[2]{id,loc,msg}:
"tests/test_auth.py::test_expiry","tests/test_auth.py:42",assert exp < now
"tests/test_user.py::test_create","tests/test_user.py:88","KeyError: 'email'"
traces:
"tests/test_auth.py::test_expiry"[2]: "tests/test_auth.py:42 in test_expiry",assert token.exp < now()
Guarantees
- Exit codes always mirrored —
cartoon pytest && deploybehaves likepytest && deploy. - If parsing fails, the original output passes through untouched (one warning on stderr). Information is never silently lost.
- A transform must pay for itself: if the TOON rendering (footer included) wouldn't beat the original token count, the original is emitted byte-identically. Savings are never negative.
- Heuristic (lossy) mode is off unless you ask for it.
Raw log archive
Every wrapped run keeps its full raw output under
~/.local/state/cartoon/runs/<run-id>/ (stdout.log, stderr.log,
meta.json). Transformed output ends with a raw_log: line pointing at the
archive — if the TOON summary dropped something you need, fetch the original
with cat or cartoon logs <id> instead of rerunning. Passthrough and
--raw output stay byte-identical (no footer) but are still archived.
Retention is capped (keep_runs, default 50; max_archive_mb, default 50);
keep_runs = 0 disables archiving.
Fast mode
cartoon --fast pytest appends -n auto so pytest-xdist runs the suite in
parallel. Strictly opt-in — parallel execution is NOT "same behavior" (test
order changes; shared-state tests can flake), so cartoon never enables it on
its own and always discloses it with a fast: "-n auto" line in the report.
Failures under --fast? Rerun without it before debugging. If pytest-xdist
isn't installed, cartoon retries serially once and notes it on stderr.
Other runners: no-op (jest is already parallel; unittest has no parallel
runner).
Config
~/.config/cartoon/config.toml:
heuristic = false # default for lossy fallback
tokenizer = "o200k" # or "approx" (bytes/4) for zero-cost estimates
trace_lines = 20 # per-failure traceback cap
keep_runs = 50 # archived raw logs to keep (0 disables)
max_archive_mb = 50 # max total archive size
Stats live in ~/.local/state/cartoon/stats.jsonl.
Adapters
| Adapter | Trigger | Source |
|---|---|---|
| pytest | pytest, python -m pytest |
injected --junit-xml |
| unittest | python -m unittest |
stderr text parse |
| jest | jest, npx jest |
injected --json |
No adapter match → JSON auto-detection → optional heuristic → passthrough.
Want another runner (cargo test, go test, vitest, rspec)? See CONTRIBUTING.md — adapters are one trait impl + fixtures.
Support
If cartoon saves you tokens, a ⭐ on this repo helps other agent users find
it — and cartoon stats will tell you exactly how much it earned one.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cartoon-0.1.1-py3-none-win_amd64.whl.
File metadata
- Download URL: cartoon-0.1.1-py3-none-win_amd64.whl
- Upload date:
- Size: 3.2 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5701c9e09d894a7882f64862bc419b1f313fb04ad7dc065db636fbf8f579484d
|
|
| MD5 |
d02c65850aedec5516396e23b8d6d73c
|
|
| BLAKE2b-256 |
375a6a533335e1e6cd4f75b581d844ce6e0c635f56f48768f6fd233895ddff09
|
Provenance
The following attestation bundles were made for cartoon-0.1.1-py3-none-win_amd64.whl:
Publisher:
release.yml on abhijitbansal/cartoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cartoon-0.1.1-py3-none-win_amd64.whl -
Subject digest:
5701c9e09d894a7882f64862bc419b1f313fb04ad7dc065db636fbf8f579484d - Sigstore transparency entry: 1787630152
- Sigstore integration time:
-
Permalink:
abhijitbansal/cartoon@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/abhijitbansal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cartoon-0.1.1-py3-none-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: cartoon-0.1.1-py3-none-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: Python 3, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8c775ad10cee5dd57920f025f2be843fc72d51e523af03c645e7d08360bf72b
|
|
| MD5 |
17be4bc6a3fd1d452372988ecb85335d
|
|
| BLAKE2b-256 |
b90be2af69aee2b565e19ec229dd4eaba178b6a381d20b7060f4d3c7932b30ba
|
Provenance
The following attestation bundles were made for cartoon-0.1.1-py3-none-manylinux_2_39_x86_64.whl:
Publisher:
release.yml on abhijitbansal/cartoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cartoon-0.1.1-py3-none-manylinux_2_39_x86_64.whl -
Subject digest:
b8c775ad10cee5dd57920f025f2be843fc72d51e523af03c645e7d08360bf72b - Sigstore transparency entry: 1787629454
- Sigstore integration time:
-
Permalink:
abhijitbansal/cartoon@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/abhijitbansal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cartoon-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: cartoon-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 3.5 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49043eb64e209be5670656047e64ef3b759ad746882a3d44f993c2ad49fe93e9
|
|
| MD5 |
9641742bb43b7002d875ecf14cfe7073
|
|
| BLAKE2b-256 |
1d0b8154def7a38e63c488f91a565e7fab0427cb532c0ef4bd0c166c89c9ffd8
|
Provenance
The following attestation bundles were made for cartoon-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on abhijitbansal/cartoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cartoon-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
49043eb64e209be5670656047e64ef3b759ad746882a3d44f993c2ad49fe93e9 - Sigstore transparency entry: 1787629364
- Sigstore integration time:
-
Permalink:
abhijitbansal/cartoon@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/abhijitbansal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cartoon-0.1.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: cartoon-0.1.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.4 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
403df1f5cbddc27498c179c9066f2ef5577114d35dc6ee498527e7fa4dcd22c6
|
|
| MD5 |
32b050920048fa16b505e7932ae766e4
|
|
| BLAKE2b-256 |
536dac9aea8266ebc433f514cfcc1436ab98927f00fd95dd06136ccf8c4a9525
|
Provenance
The following attestation bundles were made for cartoon-0.1.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on abhijitbansal/cartoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cartoon-0.1.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
403df1f5cbddc27498c179c9066f2ef5577114d35dc6ee498527e7fa4dcd22c6 - Sigstore transparency entry: 1787629817
- Sigstore integration time:
-
Permalink:
abhijitbansal/cartoon@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/abhijitbansal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cartoon-0.1.1-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: cartoon-0.1.1-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07fa8e383db31a5f53396a6457b2beb2f6c82eeb06092cbcfa7b13e72ee282ac
|
|
| MD5 |
5fb24d0a624f7a98427c77931350fb17
|
|
| BLAKE2b-256 |
8106a4d1406f4b521b133adf62e64d8d36e8a37b2d65c46c8f371af236b8fc8a
|
Provenance
The following attestation bundles were made for cartoon-0.1.1-py3-none-macosx_10_12_x86_64.whl:
Publisher:
release.yml on abhijitbansal/cartoon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cartoon-0.1.1-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
07fa8e383db31a5f53396a6457b2beb2f6c82eeb06092cbcfa7b13e72ee282ac - Sigstore transparency entry: 1787630307
- Sigstore integration time:
-
Permalink:
abhijitbansal/cartoon@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/abhijitbansal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da5f38530413a1ddfcf8d0eae6f644e873c8167 -
Trigger Event:
push
-
Statement type: