2.5 KiB
2.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Clojure TUI framework inspired by Bubbletea (Go), using the Elm Architecture with Hiccup for views. Two runtimes: full async (tui.core with core.async) and simple sync (tui.simple for Babashka).
Commands
# Run tests
bb test
# List available examples
bb examples
# Run examples (with Babashka - simple sync runtime)
bb counter
bb timer
bb list
bb spinner
bb views
bb http
# Run examples with full Clojure (async support)
clojure -A:dev -M -m examples.counter
Architecture
View (hiccup) → Render (ANSI string) → Terminal (raw mode I/O)
↑ |
| v
Model ←──────── Update ←─────────── Input (key parsing)
Core Modules
- tui.core - Full async runtime with core.async. Manages the event loop, executes commands (quit, tick, batch, seq), handles input via goroutines.
- tui.simple - Sync runtime for Babashka. Same API but no async commands.
- tui.render - Converts hiccup (
[:col [:text "hi"]]) to ANSI strings. Handles:text,:row,:col,:box,:spaceelements. - tui.terminal - Platform abstraction: raw mode via
stty, reads from/dev/tty, renders by printing ANSI. - tui.input - Parses raw bytes into key messages (
[:key {:char \a}],[:key :up],[:key {:ctrl true :char \c}]). - tui.ansi - ANSI escape codes, colors, box-drawing characters, string utilities.
Elm Architecture Flow
- App provides
:init(model),:update(fn [model msg] -> [new-model cmd]),:view(fn [model] -> hiccup) - Runtime renders initial view
- Input loop reads keys, puts messages on channel
- Update function processes messages, may return commands
- Commands execute async (ticks, batches), put results back on channel
- Loop until
[:quit]command
Command Types
tui/quit- Exit(tui/tick ms)- Send:tickafter delay(tui/batch cmd1 cmd2)- Parallel execution(tui/sequentially cmd1 cmd2)- Sequential execution(fn [] msg)- Custom async returning a message
Testing Philosophy
- E2E tests: Small number of integration tests to verify the full stack works (terminal init → input → update → render → cleanup)
- Unit tests: Cover all engine behavior for rendering (hiccup→ANSI), input handling (byte sequences→key messages), and model/command interactions