Show HN: Boo – 基于 libghostty 构建的类屏幕终端复用器
Show HN: Boo – Screen-style terminal multiplexer built on libghostty

原始链接: https://github.com/coder/boo

**boo** 是一款基于 `libghostty` 构建、使用 Zig 语言编写的现代终端复用器。与传统复用器不同,它利用 Ghostty 的终端仿真核心,能够精准记录并恢复每个会话的状态,包括光标位置、SGR 样式以及回滚缓冲区。 **主要特性:** * **持久性:** 会话在断开连接后依然存在,并可通过全屏界面 (`boo ui`) 进行管理。 * **支持自动化:** 专为脚本和 AI 代理设计,`boo` 提供了无头(headless)原语,无需活动 TTY 即可发送输入、等待特定输出以及查看渲染后的屏幕。 * **精确性:** 通过 `libghostty-vt` 解析输出,`boo` 确保即使在分离状态下,终端查询(如屏幕尺寸或窗口标题)也能得到准确响应。 * **开发者友好:** 为自动化提供机器可读的 `--json` 输出,并采用标准的 GNU screen 风格快捷键(前缀 `Ctrl-a`)。 尽管目前该项目尚处于早期阶段(每个会话仅支持一个客户端和单窗口),但它为传统工具提供了一种稳定且可编程的替代方案。它支持 Linux 和 macOS,可通过提供的脚本或 Nix 轻松安装。`boo` 将终端转变为一个可靠、可观测的沙箱,适用于复杂的工作流和程序化交互。

Hacker News | 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 | 登录 Show HN: Boo – 基于 libghostty 构建的类 screen 终端多路复用器 (github.com/coder) 17 点,由 kylecarbs 发布于 1 小时前 | 隐藏 | 过往 | 收藏 | 1 条评论 帮助 stereo 11 分钟前 [–] 显然你写这个是因为 screen 不能满足你的需求,但你的自述文件只写了它是“一个尚处早期的项目,并非 GNU screen 的直接替代品”。相比 screen 或 tmux,它有什么优势? 回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

A GNU screen style terminal multiplexer built on libghostty (libghostty-vt), written in Zig.

Every session's output is parsed through Ghostty's terminal emulation core, so boo always knows the exact screen state of every session: contents, styles, cursor, scrollback, and terminal modes. That state is used to rehydrate your terminal on attach, to answer terminal queries for detached sessions, and to let scripts and AI agents read the screen exactly as a human would see it.

  • Sessions that survive disconnects: detach with Ctrl-A d, reattach with boo attach.
  • A full-screen session manager: boo ui lists sessions in a sidebar.
  • Faithful redraws from libghostty terminal state, including SGR styles, cursor position, scrolling regions, window title, and terminal modes.
  • Agent-friendly automation primitives: send, peek, wait, and --json output, all usable without a TTY.
demo.mp4

For Linux and macOS:

curl -fsSL https://raw.githubusercontent.com/coder/boo/main/install.sh | sh

Pre-built binaries are published on the releases page. Set BOO_VERSION to pin a release and BOO_INSTALL_DIR to change the install location (default: /usr/local/bin when writable, otherwise ~/.local/bin).

boo new                    # new session running $SHELL, attached
boo new work               # named session
boo new work -d -- make    # create detached, running a command
boo ui                     # manage sessions in a full-screen UI (alias: i)
boo ls                     # list sessions
boo attach work            # reattach (alias: at, a)
boo rename work api        # rename a session
boo kill work              # end a session
boo kill --all             # end every session

With no name, boo new names the session after the current directory, falling back to the process id when that name is taken or unusable.

Run boo help for the full overview, boo help <command> for flags and examples, and boo help --all to print every help page at once.

Key bindings (prefix Ctrl-a)

Bindings follow GNU screen's defaults, including the C-x variants (C-a C-d detaches just like C-a d).

Keys Action
C-a d, C-a C-d detach
C-a l, C-a C-l redraw
C-a a send a literal C-a

boo ui adds additional keybinds for switching, resizing, creating sessions, and killing them.

Everything except attach works without a terminal, which makes boo a natural sandbox for scripts and AI agents driving interactive programs. The canonical loop:

boo new build -d -- bash               # 1. headless session
boo send build --text 'make' --enter   # 2. type into it
boo wait build --idle                  # 3. let output settle
boo peek build --scrollback            # 4. read the screen
boo kill build                         # 5. clean up
  • Reading state: peek prints the rendered screen reconstructed from terminal state, not a raw byte log: ordered, fully redrawn, and stable. --scrollback includes history; --json adds size, cursor, and title.
  • Waiting: wait --text <text> blocks until the screen contains the text; wait --idle until output has been quiet for 2 seconds; --timeout <dur> exits 4 instead of hanging forever (durations: 500ms, 2s, 1m, 4h, 1d). No more sleep-and-poll loops.
  • Sending input: send --text is literal: no escape processing, no implicit newline, no quoting layer to fight. --enter submits, --key Enter,C-c,Up names control keys, and stdin mode is binary safe.
  • Machine-readable output: ls --json and peek --json.
  • Exit codes: 0 success, 1 error, 2 usage error, 3 no such session, 4 wait timed out.

See boo help automation for the full page.

Requires Zig 0.15.2.

zig build                       # binary in zig-out/bin/boo
zig build test                  # unit tests
zig build test-integration     # end-to-end tests on a real PTY
zig build test-all             # everything

The libghostty dependency is fetched and built from source automatically (pinned in build.zig.zon).

With Nix, nix develop opens a shell with the right Zig version, and nix build builds the package to ./result/bin/boo.

your terminal <-(raw tty)-> boo client <-(unix socket)-> session daemon
                                                         `- PTY + ghostty-vt Terminal
  • The client puts your TTY in raw mode and shuttles bytes over a framed Unix-socket protocol (src/protocol.zig).
  • The daemon (forked on session creation) owns the session's command: a PTY-attached child whose output feeds a persistent ghostty-vt TerminalStream (src/window.zig).
  • While attached, output is passed through to your terminal byte for byte. On attach the daemon sanitizes your terminal and replays the screen from libghostty state using its VT TerminalFormatter.
  • Terminal queries (DSR, DA, XTWINOPS, ...) while detached are answered by libghostty's stream handler; while attached your real terminal answers, avoiding double replies.

This is a young project, not a drop-in GNU screen replacement:

  • One attached client per session (attaching steals); no -x sharing.
  • One window per session: no splits or tabs inside a session. Run one session per task and juggle them with boo ui.
  • The C-a prefix is not yet configurable, and pasted bytes containing 0x01 are interpreted as the prefix (GNU screen has the same quirk; boo ui is immune thanks to bracketed paste).
  • Sessions run with TERM=xterm-256color.

Feel free to open an issue if you have questions, run into bugs, or have a feature request.

MIT. Ghostty itself is MIT licensed.

联系我们 contact @ memedata.com