term-animate
term-animate is a Python library for projecting curated terminal animations into a host-provided viewport. It also includes an interactive, standalone gallery for previewing the bundled artwork locally.
The library is host-neutral: it returns styled, bounded terminal rows and leaves terminal output, input, timing, layout, and application state to the program embedding it.
term-animate was abstracted from visual-material work created for ccusage-viz. It remains a standalone library with no ccusage-viz or ccuv runtime dependency.
Install and launch the gallery
Requires Python >=3.11,<3.14.
With uv:
uv tool install term-animate
term-animate gallery
With pip:
python -m pip install term-animate
term-animate gallery
The gallery is a preview tool; applications should embed the library rather than automate it. To open a particular effect with a named theme:
term-animate gallery --effect mole-cat --theme dracula
Development from source
uv sync
uv run term-animate gallery
Gallery controls:
n/],p/[: browse effectsSpace: pause or resume the preview policyt/T: switch themesf: freeze or resume cat traversal while source frames continues: switch cats between stationary and traverse modesi,?: show provenance details or helpq,Esc,Ctrl-C: exit safely
Embed in a host
Use project_curated() for the usual integration. Each projection is pure and stateless: pass the host's current selection, viewport, terminal capabilities, theme, clocks, and logical state on every call.
from term_animate import LogicalState, TerminalCapabilities, Viewport, project_curated
capabilities = TerminalCapabilities(color="truecolor")
frame = project_curated(
"nature",
"rain",
viewport=Viewport(columns=current_pane_width, rows=current_pane_height),
capabilities=capabilities,
theme="dracula",
monotonic_seconds=effective_nature_seconds,
logical_state=LogicalState.ACTIVE,
)
Call the function again whenever the selection, theme, or pane size changes. viewport is the sole size input: animal art moves within it without stretching, clocks stay centered at their fixed presentation size, and nature scenes adapt procedurally while retaining their glyph sizes.
ProjectedFrame.next_deadline_seconds is an absolute monotonic timestamp. The host owns redraw scheduling and terminal serialization. The library never performs terminal I/O, reads input, runs a timer, stores selection/theme/viewport state, accesses application data, or imports ccuv.
For hosts that already manage selections and palette tokens, use the lower-level composition primitives:
from term_animate import ThemeTokens, project, select_effect
effect = select_effect("animal", "mole-cat")
frame = project(
effect,
viewport=viewport,
capabilities=capabilities,
theme=ThemeTokens(artwork=(120, 220, 255)),
monotonic_seconds=now_monotonic,
)
All five stateful nature scenes accept host-selected LogicalState.ACTIVE or LogicalState.IDLE; idle scenes have no redraw deadline. Clocks consume timezone-aware wall_time, and hosts can control cat traversal separately from source-frame animation.
See docs/embedding.md for host ownership, timing, state, traversal, and viewport behavior in detail.
Curated effects and themes
The fixed catalog contains eleven host-selectable effects:
| Category | Style | Effect ID |
|---|---|---|
logo |
claude-code |
claude-code |
animal |
mole-cat |
mole-cat |
animal |
campy-cat |
campy-cat |
nature |
rain |
rain |
nature |
snow |
snow |
nature |
night-sky |
night-sky |
nature |
lightning |
lightning |
nature |
meteor-shower |
meteor-shower |
time |
analog-clock |
analog-clock |
time |
compact-digital-clock |
compact-digital-clock |
time |
digital-clock |
digital-clock |
analog-clock uses analog hands. compact-digital-clock uses compact block digits, while digital-clock uses a wider seven-segment treatment; both digital clocks blink their separators.
Named palettes are compatible with ccuv naming: classic, vivid, contrast, dracula, catppuccin, solarized, gruvbox, nord, github, mono, and no-color.
Local image content
Local PNG, JPEG, GIF, WebP, APNG, and SVG content can be prepared explicitly as local animation packs. It is never downloaded, bundled, or merged into the immutable curated catalog. SVG preparation requires CairoSVG and its platform Cairo library.
See docs/asset-format.md for supported formats and pack details, and docs/asset-policy.md for catalog and distribution policy.
Boundaries
A future ccuv integration owns layout, resizing, rendering, terminal lifecycle, input, scheduling, preference persistence, theme resolution, and logical activity decisions. This repository contains no ccuv adapter or ccuv integration tests.
term-animate does not collect or interpret provider, token, session, request, cost, quota, account, or product data.
Sources and licenses
| Effect | Origin | License |
|---|---|---|
| Claude Code logo, Rain, Snow, Night Sky, Lightning, Meteor Shower, Analog Clock, Compact Digital Clock, Digital Clock | Original term-animate artwork and deterministic procedural scenes |
GPL-3.0-only |
| Mole Cat | Adapted from tw93/Mole | GPL-3.0-only |
| Campy Cat | Adapted from dropdevrahul/campy | MIT |
The distributed package is GPL-3.0-only. Complete upstream revisions, adaptation details, and retained license notices are in THIRD_PARTY_NOTICES.md.
Development checks
uv run pytest
uv run ruff check .
uv run ty check src
uv build
License
Metadata
Release files for term-animate 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| term_animate-0.1.1.tar.gz | 79.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| term_animate-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 169.1 kB
Release files / term_animate-0.1.1.tar.gz
| Download URL | term_animate-0.1.1.tar.gz |
|---|---|
| Size | 79.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91f1ea0b8fc66a117353c4ea2f8af05b43fa60d59dc03dffa96619f647f464f3
|
|
BLAKE2b-256 checksum How to use checksums |
aab4c117bc91ac4e7ba344868a110d726822542ed09f6ea20cef7cf1dec1745e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / term_animate-0.1.1-py3-none-any.whl
| Download URL | term_animate-0.1.1-py3-none-any.whl |
|---|---|
| Size | 89.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d1c859c90c6bc000c36c700239ca0b6d5a3e285a4f99e09d2104c34c19c4d17
|
|
BLAKE2b-256 checksum How to use checksums |
287fc288b0ebddea25b8b9b10e574d76dd6889e7f3bb9264cfdbee09094b8b65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log