the o family · Go terminal tools
Vim-inspired modal TUIs and CLIs in Go.
A family of Go TUIs, CLIs and the modal TUI framework under them. Every action is a named command that your keys, the palette and the shell all reach, keys and settings are data you can rebind, and Vim's grammar (modes, counts, registers, dot-repeat) runs through all of it.
go install github.com/unixsuperhero/matomeru/cmd/mtm@latest
go get github.com/unixsuperhero/ochazuke@latest
go get github.com/unixsuperhero/oden@latest
go get github.com/unixsuperhero/monogatari@latest
git clone https://github.com/unixsuperhero/o-json && cd o-json && go build -o ~/bin/o-json .
ochazuke · The CSV example: moving through 3,000 rows, a palette command on a whole column, a filter, a sort and an edit with undo
01 · the projects
Five to start with.
Two libraries, a story runner, an agent workspace and a JSON viewer. Each one is a Go module with an MIT license and a README that is the full reference.
-
01 / 05
ochazuke お茶漬け
libraryv0.55.0pre-1.0
A modal TUI framework for Go, built on Bubble Tea v2: Vim-style modes and an extensible command model, so every action in your app can be bound to a key, run from the palette or scripted from the shell.
Overview of ochazuke GitHub for ochazuke README for ochazuke
-
02 / 05
oden おでん
libraryv0.1.1early
Subcommand dispatch for Go CLIs: a bin's inline commands and every <bin>-<sub> executable on PATH, in one table, resolved by name, alias or unique prefix.
-
03 / 05
matomeru まとめる
appv0.1.0early
A terminal workspace for coding agents: projects, tasks, notes, live agent panes, their turns and your reviews, gathered in one TUI.
Overview of matomeru GitHub for matomeru README for matomeru
-
04 / 05
monogatari 物語
libraryv0.1.0early
Stories for apps built on ochazuke: JSON keystroke scripts played headless against your app's real UI, with expectations on what the screen shows.
Overview of monogatari GitHub for monogatari README for monogatari
-
05 / 05
o-json
toolv0.4.5early
A JSON structure and table viewer: every path with its types and counts, arrays of objects as tables, and restructure, query with jq and export.
-
And 9 more on the menu.
Smaller tools and extensions, from a disk-hog finder to a fleet checker. Every one is an
o-*bin the hosts can mount.
02 · how it fits
Built on ochazuke and oden.
Two libraries at the bottom, two hosts in the middle, and every o-* tool an extension the hosts can mount.
libraries oden ─────────────► ochazuke CLI dispatch: the modal TUI framework: names on PATH modes, commands, keys as data │ │ hosts mtm (matomeru) nabe (o tui) the agent workspace a page per extension │ │ └──────┬─────────────┘ extensions o-json o-ai o-inventory o-proj o-md ... each an o-* bin that answers `catalog`
- Libraries
- oden resolves a command name to an inline handler or an executable on PATH, so commands are just names and a tool composes them. ochazuke is the modal TUI framework on top of it: an app declares its commands, keys and settings as data, and one declaration drives the TUI, the palette and the command line.
- Hosts
- matomeru (
mtm) and nabe are ochazuke apps that mount other tools.mtm <sub>ando <sub>findmtm-<sub>ando-<sub>bins on PATH. - Extensions
- Every
o-*tool answersBIN catalogwith a JSON description of its commands and keys; a host mounts it as pages, keys and palette commands, and neither side forks the other. monogatari tests any of them from stories.
03 · principles
The rules every tool keeps.
-
01 / 04
Keys are data
A binding is a row of data: where it applies, the mode, the keys and the command it runs. Every default key is written once in an embedded JSON file, and a row in your
bindings.jsonreplaces it, adds to it or unbinds it. No row runs Go code.{ noun: "directory", mode: "normal", keys: "U", request: { verb: "undo", noun: "input", args: { steps: 3 } } } -
02 / 04
Every action is a command
Each action is registered once as a named command with typed arguments, and that one definition drives the keys, the command palette and the command line. Anything you do in the TUI you can also script from another terminal.
mtm task new --title "Write it" mtm project pin ochazuke input undo --json '{"steps":3}' -
03 / 04
A setting for every UI change
Anything that changes what the screen shows or how it moves, from a status segment to an auto-opened picker, comes with a setting that turns it off. The setting is data in the app's settings, not a code branch.
mtm settings set schedule.gh-signals.enabled off mtm settings set prompt.on-screen false -
04 / 04
Stories before fixes
A UI bug becomes a story before it is fixed: a JSON keystroke script played headless against the app's real UI, with expectations on what the screen shows. Then it stays fixed.
mtm-story story run panes mtm-story story keep 2 detach-bug mtm-story story replay detach-bug
04 · install
Go 1.26 and a terminal.
The snippets come from each project's README. Libraries are go get; apps are go install or a build from a checkout.
ochazuke
go get github.com/unixsuperhero/ochazuke@latest
go run ./cmd/ochazuke run # from a checkout
oden
go get github.com/unixsuperhero/oden@latest
go build -o ~/bin/o ./cmd/o # from a checkout
matomeru
go install github.com/unixsuperhero/matomeru/cmd/mtm@latest
make install # stamps the version from git describe
monogatari
go get github.com/unixsuperhero/monogatari@latest
go build -tags monogatari -o bin/mtm-story ./cmd/mtm
o-json
git clone https://github.com/unixsuperhero/o-json && cd o-json && go build -o ~/bin/o-json .