Help us shape the future of Go! Take the 2026 Go Developer Survey

ttybus

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: MIT

README

ttybus

Home: github.com/ttyzero/ttybus (moved from tjstebbing/ttybus).

 ________
|[][][]|_\_
| TTYBus   |
=-OO----OO-=

A text message bus for TUIs, CLIs, and shell scripts.

Unix programs compose with pipes. TUIs cannot: stdin is the keyboard and stdout is the screen. ttybus is the side channel. TUIs never join a pipeline. A small CLI does.

ttybus serve                  # user daemon; also auto-started by pub/sub

ttybus pub  files main.go
echo main.go | ttybus pub files
ttybus sub  files             # lines on stdout until Ctrl-C
ttybus sub  files --limit 1   # one line, then exit 0

# compose like any Unix filter
ttybus sub animals | grep --line-buffered '^cat' | ttybus pub cats

ttybus ls
ttybus send --to yazi-1 files main.go
ttybus plumb main.go:42

grep block-buffers when its stdout is a pipe. Use GNU grep --line-buffered, or awk '/^cat/ { print; fflush() }'.

Speak the protocol yourself:

nc -U "$XDG_RUNTIME_DIR/ttybus/bus.sock"
HELLO name=demo pid=$$
SUB files
PUB files /tmp/hello.go

Install

curl -fsSL https://raw.githubusercontent.com/ttyzero/ttybus/main/install.sh | sh

Installs to ~/.local/bin. Pin a release or put the binary somewhere else:

VERSION=v0.1.0 PREFIX=/usr/local curl -fsSL https://raw.githubusercontent.com/ttyzero/ttybus/main/install.sh | sh

Linux amd64/arm64 and macOS amd64/arm64. Needs curl, tar, and a GitHub release (tag v*).

Companion TUIs (gitwing, peek, buscope, ttythemer) are a second, optional step — same PREFIX / BINDIR:

curl -fsSL https://raw.githubusercontent.com/ttyzero/ttybus/main/install-kit.sh | sh

Subset: sh -s -- gitwing peek, or TOOLS=ttythemer. Pin with VERSION=v0.1.0. SOURCE=go builds from module source instead of release tarballs.

From source:

go install github.com/ttyzero/ttybus/cmd/ttybus@latest
# or
make build
./ttybus serve --foreground

Why

A TUI running in one tmux pane has no Unix-native way to tell a TUI in another pane "open this file", or to let a shell script inject an event, or to emit something grep can see without trashing the alternate screen.

Each TUI that has solved this has grown a private bus (Yazi DDS, lf -remote, Kakoune sockets). ttybus is the shared one: text lines over a unix stream socket, a CLI that behaves like cat/tee for named channels, an optional plumber for "this looks like a file:line → editor".

This is a clean-room take on an idea from 2018 (ttyzero/minibus). Clients connect in; the protocol is newline-delimited text; the CLI is pipeline-correct (line-flushed, logs on stderr, never opens /dev/tty).

Rules of the road

  1. TUIs never participate in pipelines. stdin = keys, stdout = screen, socket = bus.
  2. The CLI is a Unix filter. Logs go to stderr. Every message is one line, flushed. --limit and --timeout exist so scripts can block without head races. Timeout exits 124 like GNU timeout.
  3. Text on the wire. PUB files {"path":"…"} is fine; JSON as the envelope is not. nc, grep, and awk must work.
  4. One user daemon, socket at $XDG_RUNTIME_DIR/ttybus/bus.sock (or $TMPDIR/ttybus-<uid>/bus.sock). Named buses (--bus NAME / $TTYBUS_BUS) isolate multiplexer sessions.

A TUI can export TTYBUS_ID so shells it spawns identify themselves. Full contract: docs/PROTOCOL.md.

Go helper

c, err := ttybus.Dial(ttybus.DefaultSocket())
_ = c.Hello(ttybus.Info{Name: "mytui"})
ch, _ := c.Sub("files")
_ = c.Pub("files", path)

See client/ and examples/bubbletea.

Plumber

~/.config/ttybus/plumb (or $TTYBUS_PLUMB):

match ^([^\s:]+):(\d+)$
  pub editor.open

match ^https?://
  exec open $0

match \.(go|rs|py)$
  pub editor.open

$0 is the whole text; $1… are capture groups. First match wins.

Layout

cmd/ttybus/          serve | pub | sub | ls | send | plumb
internal/protocol/   line parser
internal/daemon/     socket server, subscriptions, fan-out
internal/socket/     path resolution, flock, auto-start
internal/plumb/      rule file
client/              Go helper for TUI authors
examples/bubbletea/  bus messages as Bubble Tea Msg
contrib/             tmux.conf, systemd --user unit
docs/PROTOCOL.md     wire spec
install.sh           ttybus binary
install-kit.sh       optional companion TUIs
PLAN.md              implementation notes

Prior art

Closest production system is Yazi DDS (ya pub / ya sub), which is Yazi-only. Philosophical ancestor is Plan 9 plumber. D-Bus is the desktop equivalent and is the thing we are deliberately not.

License

MIT. See LICENSE.

Directories

Path Synopsis
Package ttybus is a small Go helper for TUI authors.
Package ttybus is a small Go helper for TUI authors.
cmd
ttybus command
Command ttybus is the daemon and the Unix-filter CLI for the ttybus text message bus.
Command ttybus is the daemon and the Unix-filter CLI for the ttybus text message bus.
internal
daemon
Package daemon is the ttybus server: accept loop, subscription hub, per-connection reader/writer.
Package daemon is the ttybus server: accept loop, subscription hub, per-connection reader/writer.
protocol
Package protocol parses and prints ttybus protocol lines.
Package protocol parses and prints ttybus protocol lines.
socket
Package socket resolves the ttybus socket path, takes the listen lock, unlinks stale sockets, and auto-starts the daemon for CLI commands.
Package socket resolves the ttybus socket path, takes the listen lock, unlinks stale sockets, and auto-starts the daemon for CLI commands.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL