Development
August 1, 2026 ยท View on GitHub
Files under src/ are the maintainable source of truth. The root
ai-candy.zsh-theme file is the generated standalone distribution used by Oh My
Zsh installations.
Build And Test
Regenerate or verify the distribution:
zsh scripts/build-theme.zsh
zsh scripts/build-theme.zsh --check
Run the test suite:
python3 -m unittest discover -s tests -v
Run the static checks:
shellcheck install.sh
ruff check tests
The tests cover cache concurrency and corruption, malformed timestamps, signal cleanup, process deadlines, Git cache invalidation, prompt escaping, symlink handling, startup behavior, and hot-path process counts.
Continuous integration exercises Ubuntu 22.04/24.04, AlmaLinux 9/10, and macOS runners. A pinned Zsh 5.4.2 image checks the minimum supported shell. The macOS runner exercises the BSD userland, while runtime tests also cover fallback paths that do not depend on GNU coreutils.
Demo Generation
Regenerate the animated terminal demo:
zsh scripts/generate-demo.zsh
The generator requires Zsh and Git plus either a local VHS toolchain or Docker.
Install VHS without sudo when Go is available:
GOBIN="$HOME/.local/bin" go install github.com/charmbracelet/vhs@v0.11.0
export PATH="$HOME/.local/bin:$PATH"
The Go command above installs VHS itself; ttyd and ffmpeg remain separate
dependencies. On macOS, brew install vhs installs the supported package and
its runtime dependencies. When the complete local toolchain is unavailable,
the generator uses a digest-pinned official VHS container. Docker may need
network access to obtain that image once, but the renderer runs with its network
disabled.
Host Zsh first renders the real theme into ANSI snapshots in a fresh synthetic Git repository, an empty synthetic home, and a minimal environment. A fail-closed worker stub rejects background work. Local or containerized VHS then records a POSIX playback script, so the container does not need Zsh. A local VHS process retains normal host filesystem and network access so it can resolve the requested user-installed font; the container receives only the tape and fresh render directory. The render directory is removed after generation.
demo.gif and the static demo.png frame are published only after text and
binary privacy checks pass; generation fails closed when strings is missing.
demo-assets.sha256 records the reviewed output. Any digest change should come
from this generator and include a visual review of both assets; binary scanning
only checks metadata and cannot inspect text rendered into compressed pixels.