o-family

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 .
go run ./examples/csvrec
The CSV example: moving through 3,000 rows, a palette command on a whole column, a filter, a sort and an edit with undo

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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 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> and o <sub> find mtm-<sub> and o-<sub> bins on PATH.
Extensions
Every o-* tool answers BIN catalog with 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.

  1. 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.json replaces 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 } } }
  2. 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}'
  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
  4. 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
go get github.com/unixsuperhero/ochazuke@latest
demo
go run ./cmd/ochazuke run   # from a checkout

oden

go get
go get github.com/unixsuperhero/oden@latest
o root bin
go build -o ~/bin/o ./cmd/o   # from a checkout

matomeru

go install
go install github.com/unixsuperhero/matomeru/cmd/mtm@latest
checkout
make install   # stamps the version from git describe

monogatari

go get
go get github.com/unixsuperhero/monogatari@latest
tester build
go build -tags monogatari -o bin/mtm-story ./cmd/mtm

o-json

build
git clone https://github.com/unixsuperhero/o-json && cd o-json && go build -o ~/bin/o-json .