Metadata-Version: 2.5
Name: zoetty
Version: 0.1.0
Summary: Looping terminal demo clips as plain SVG or HTML and CSS
Project-URL: Homepage, https://github.com/phalt/zoetty
Project-URL: Documentation, https://phalt.github.io/zoetty/
Project-URL: Issues, https://github.com/phalt/zoetty/issues
Author-email: Paul Hallett <paulandrewhallett@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: animation,cli,demo,docs,readme,svg,terminal
Classifier: Environment :: Console
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Topic :: Documentation
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.12
Requires-Dist: click>=8.5.0
Requires-Dist: rich>=15.0.0
Description-Content-Type: text/markdown

# ⚜ zoetty

## What is zoetty?

zoetty turns terminal sessions into small, looping, animated clips made of plain SVG or HTML and CSS. No video, no GIF, no JavaScript.

[![Package version](https://img.shields.io/pypi/v/zoetty?color=%2334D058&label=latest%20version)](https://pypi.org/project/zoetty)
![Python versions](https://img.shields.io/badge/python-3.12+-blue)
![PyPI - License](https://img.shields.io/pypi/l/zoetty)

![zoetty init writes a starter clip spec, zoetty build renders it to SVG, and zoetty check confirms it is up to date](https://raw.githubusercontent.com/phalt/zoetty/main/docs/clips/quickstart.svg)

That's zoetty, recorded by zoetty. Every clip in this README is built from a spec in [`docs/clips/`](https://github.com/phalt/zoetty/tree/main/docs/clips).

## Why use zoetty?

Terminal GIFs go stale, weigh megabytes, look blurry, and have to be re-recorded by hand every time the output changes.

- **Real output** - `zoetty record` runs your commands in a real terminal and keeps their colours.
- **Small and sharp** - A clip is a few KB of text, crisp at any size.
- **Works in READMEs** - The SVG is just an image: it plays on GitHub, PyPI and anywhere else that shows one.
- **Or in your docs** - The HTML fragment drops into any page, with selectable text.
- **Kept in your repo** - The spec is a short TOML file. When your tool changes, re-record and rebuild.
- **Checked in CI** - `zoetty check` fails if a clip is out of date.

## Install

```sh
uv tool install zoetty
```

Or with pip:

```sh
pip install zoetty
```

zoetty needs Python 3.12 or later, and runs on **macOS and Linux**.

## Quick start

```sh
zoetty init docs/clips/hello.toml    # write a starter spec
zoetty build docs/clips/hello.toml   # render it to docs/clips/hello.svg
```

Then put it in your README like any image:

```markdown
![What the clip shows](docs/clips/hello.svg)
```

## A basic clip

Two commands, with their output written by hand:

```toml
title = "~/my-project"
label = "Typing two commands in a terminal: echo prints a greeting, ls lists three files"
cols = 60

[[run]]
cmd = "echo 'Hello from zoetty!'"
lines = ["Hello from zoetty!"]

[[run]]
cmd = "ls"
lines = ["[blue]docs[/]  README.md  [green]tool.py[/]"]
```

![Typing two commands in a terminal: echo prints a greeting, ls lists three files](https://raw.githubusercontent.com/phalt/zoetty/main/docs/clips/hello.svg)

## Recording real output

Give a run an `output` file and `zoetty record` runs the command for real and saves what it printed. `input` is typed into interactive programs, a line at a time, once each prompt is waiting:

```toml
title = "python"
label = "A Python REPL importing zoetty's markup parser and parsing some styled text"
cols = 64

[record]
env = { PYTHON_BASIC_REPL = "1" }

[[run]]
cmd = "python -q"
output = "captures/repl.ansi"
input = """
from zoetty.markup import parse, plain
plain(parse("[bold]zoe[/]tty"))
[s.styles for s in parse("[bold green]ok[/] done")]
"""
```

```sh
zoetty record docs/clips/repl.toml
zoetty build docs/clips/repl.toml
```

![A Python REPL importing zoetty's markup parser and parsing some styled text](https://raw.githubusercontent.com/phalt/zoetty/main/docs/clips/repl.svg)

Long output scrolls once it passes `rows`, and `[theme]` recolours the whole window:

![python -m this printing the Zen of Python, scrolling past the bottom of a ten-row terminal](https://raw.githubusercontent.com/phalt/zoetty/main/docs/clips/zen.svg)

See [more examples](https://phalt.github.io/zoetty/examples/), including the HTML output and hand-timed clips.

## Use it with your coding agent

zoetty is easy for coding agents to drive: specs are small text files, and every command says what it did. Paste this into Claude Code, Codex, Cursor or similar:

```text
Use zoetty to add an animated terminal demo of this project to the README.
Read https://phalt.github.io/zoetty/agents/ first and follow it: install zoetty,
write a clip spec in docs/clips/ that shows the most useful commands, record the
real output with `zoetty record`, build it with `zoetty build`, look at the result,
embed the SVG in README.md, and add `zoetty check docs/clips/*.toml` to CI.
```

## Documentation

👉 Read the [full documentation](https://phalt.github.io/zoetty/) for the clip format, every command, embedding clips and more examples.

Want to help? See [CONTRIBUTING.md](https://github.com/phalt/zoetty/blob/main/CONTRIBUTING.md).
