StrideLabs/Writing/Building Roost: a terminal I extend and use daily
Building Roost: a terminal I extend and use daily
Why I built my own terminal: a native macOS and Linux app on libghostty, organized by project, with quick theme/font switching and scriptable launch points for the commands I run most.
I built my own terminal because I wanted one I could make my own. The starting point was a small itch: I liked how cmux organizes work into projects, and I wanted that shape on Linux as well as macOS, on a terminal I understood well enough to extend. So Roost began as a cmux-like, project-organized terminal built on libghostty.
The first cut was a Go app that bundled GTK through cgo and ran on both platforms. Once I had used it enough to know I wanted to keep using it, I rebuilt it native per platform: Swift and AppKit on macOS, Rust and gtk4-rs on Linux. Building on libghostty was deliberate. I like Ghostty, I have a lot of respect for Mitchell Hashimoto’s work and writing, and libghostty was encouraged as a reusable terminal foundation. That made it the natural starting point: high-quality terminal work I could build on while staying native and lean instead of reaching for web tech to render a terminal.
Cmux was the other major inspiration, especially the way it organizes work by project. But when I started rethinking the terminal I wanted, I also realized there were parts of cmux I rarely used. Roost intentionally cuts that scope down. An embedded browser and split panes are not things I needed, and leaving them out made the project more approachable to build and easier to tune around the parts I use every day.
A sidebar, not a tab bar
Roost organizes everything around projects instead of windows, a shape I took straight from cmux. The way I use it day to day, the left rail is a list of active repos: if I am working on a project, it gets a spot there; when the work is done, I close it out. Inside each project I might have a Claude Code tab, a strix tab for the diff view, a regular shell for ad hoc commands, and sometimes a second agent working a different worktree. Pair that with notifications that jump back to the tab asking for attention, and it becomes a tidy way to multitask across several agent sessions without losing track of which terminal belongs to which piece of work.
The workflow that shaped it
Working with agents has changed what I need from a terminal. I spend less time typing code and more time reading, reviewing, and reacting to work in flight. That happens in different rooms, different lighting, and different levels of fatigue. Quick theme, font, and size switching was not the feature I expected to care about most, but it has become one of the things I reach for constantly because it makes long agent transcripts easier to read.
The other piece is small extension points. A launcher can open strix when I want to inspect the diff, or run a quick script that builds a wizard for creating a new shed. Those are not big plugin-system ideas; they are simple hooks that let Roost fit around the tools I already use and the tools I am building. The extension guide shows the same patterns: fixed command = launcher entries, dynamic provider = menus, and scripts that can call back into Roost when they need to open a tab or present a choice.
That matters more because I want the same workflow on macOS and Linux. There are more and more good agent-oriented tools on the Mac, but I also use Linux machines and wanted the same project organization, readability controls, launch points, and automation surface available there too. The two UIs do not share code, so keeping them aligned is real work, but sharing the same concepts and IPC contract is what makes the workflow portable.
The agent integration is still early
The native agent integration is the least settled part of Roost. The current shape is useful: Claude Code hooks can tell Roost when a tab is running, finished, or waiting for input, and the UI can mark the tab and route you back to it. I recently landed changes to make that flow feel better, but the notifications, UI policy, and deeper Claude integration still need refinement.
This has turned out to be less of an immediate need than I expected, because the project organization and readability controls already carry a lot of the day-to-day value. But it is the current focus of development. Once the Claude Code path feels right, Codex and OpenCode integrations are the next obvious step.
On the shoulders of giants
Roost owes its shape to cmux and its terminal to Ghostty, both of which are more mature and more featureful than Roost, and both of which I would happily point you to. What Roost gives me that I could not get elsewhere is a terminal that is genuinely mine: small enough to understand, programmable to the core, and tuned to the way I work with coding agents every day.
If that sounds like a workflow you would enjoy, the Roost install docs cover both macOS and Linux. It is still young, but it is already the surface I run the rest of my tools and agents from.