- Rust 99.7%
- Just 0.3%
The GitHub repo is deliberately kept as a mirror, but its main is frozen at b08f1f0 (pre-thor-deployment) with a .gitmodules that still points every submodule back at GitHub — the same trap finding 3 caught in install.md. An agent following this link lands on stale code, not the current tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FGisjtKSjUcVGw1jX1Hf8M |
||
|---|---|---|
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| justfile | ||
| LICENSE | ||
| README.md | ||
| rustfmt.toml | ||
openbooks-cli
Terminal client for openbooks-api. Run it with no arguments and you get a TUI; give it a subcommand and it becomes a quiet, scriptable CLI.
Run it
From this repo, with the API already up:
just run # the TUI
just run balances --json # arguments pass straight through
just test # unit and render tests, no API needed
just check # fmt and clippy, as CI would
From the openbooks superproject, which starts postgres and the API first if they're down:
just cli
just cli balances --json
Point it elsewhere with --api or OPENBOOKS_API (default http://localhost:38081).
The TUI
Four tabs in fixed positions, the money on hand always in the header:
| Dashboard | balance of every account |
| History | every transaction, newest first |
| Reports | money in and out, plus what we hold and owe, for any month/quarter/year |
| Record | log money in, money out, or a transfer |
Keys — ? shows them all:
Tab / Shift-Tab next / previous tab j k / ↓ ↑ move
1 2 3 4 jump to a tab g G first / last row
r reload q quit
Reports: m Q y monthly / quarterly / annual [ ] previous / next period
History: d delete the selected transaction
Record: Tab next field ← → change Enter save Esc clear
Needs at least 80x24; below that it says so rather than drawing a broken layout. Respects
NO_COLOR, and the selected row uses reverse video so it stays visible with no colour at all.
The CLI
Text by default — aligned columns, no escape sequences, safe to pipe. --json emits the
API's own JSON untouched, so jq sees exactly what the server said.
openbooks accounts
openbooks balances
openbooks transactions --from 2026-01-01 --to 2026-03-31
openbooks income --from 2026-04-01 --to 2026-06-30
openbooks balance-sheet --as-of 2026-06-30
openbooks record out --amount 45.00 --account checking --category Food \
--date 2026-03-05 --description "Meeting pizza"
record takes in, out, or transfer and works out the double-entry split itself.
Accounts resolve by name, by unambiguous prefix, or by id — an ambiguous prefix is an error
rather than a guess. Anything wrong exits non-zero with the reason on stderr, so a script
can trust the exit code.
Amounts
Dollars in, 45 or 45.50, parsed to integer cents without ever touching a float —
19.99 * 100.0 is 1998.9999… in binary floating point, and truncating that loses a penny
every time. cargo test covers that case specifically.
Tests
cargo test
19 tests, no network needed: money parsing and formatting, the debit/credit split, account
resolution, period arithmetic across year boundaries and leap Februaries, and the whole
render path against ratatui's TestBackend — including the too-small-terminal gate and the
warning shown if a balance sheet ever fails to balance.