top | item 47079718

Show HN: cmux - Ghostty-based terminal with vertical tabs and notifications

198 points| lawrencechen | 1 month ago |github.com | reply

I run a lot of Claude Code and Codex sessions in parallel. I was using Ghostty with a bunch of split panes, and relying on native macOS notifications to know when an agent needed me. But Claude Code's notification body is always just "Claude is waiting for your input" with no context, and with enough tabs open, I couldn't even read the titles anymore.

I tried a few coding orchestrators but most of them were Electron/Tauri apps and the performance bugged me. I also just prefer the terminal since GUI orchestrators lock you into their workflow. So I built cmux as a native macOS app in Swift/AppKit. It uses libghostty for terminal rendering and reads your existing Ghostty config for themes, fonts, colors, and more.

The main additions are the sidebar and notification system. The sidebar has vertical tabs that show git branch, working directory, listening ports, and the latest notification text for each workspace. The notification system picks up terminal sequences (OSC 9/99/777) and has a CLI (cmux notify) you can wire into agent hooks for Claude Code, OpenCode, etc. When an agent is waiting, its pane gets a blue ring and the tab lights up in the sidebar, so I can tell which one needs me across splits and tabs. Cmd+Shift+U jumps to the most recent unread.

The in-app browser has a scriptable API ported from agent-browser [1]. Agents can snapshot the accessibility tree, get element refs, click, fill forms, evaluate JS, and read console logs. You can split a browser pane next to your terminal and have Claude Code interact with your dev server directly.

Everything is scriptable through the CLI and socket API – create workspaces/tabs, split panes, send keystrokes, open URLs in the browser.

Demo video: https://www.youtube.com/watch?v=i-WxO5YUTOs

Repo (AGPL): https://github.com/manaflow-ai/cmux

[1] https://github.com/vercel-labs/agent-browser

77 comments

order
[+] bdbz|1 month ago|reply
Nice work! I have actually been working on something similar.

Main differentiators: - Based on tmux, so you can connect to a persistent session from multiple devices - Responsive, resizes sidebar based on mobile/desktop client connecting - Status indicator icons for major LLM CLIs (needs input/thinking) - Completely built into tmux, emulator-agnostic - Supports grouping of windows - Supports color and emoji-coding windows / panes / window groups - It's higly configurable using yaml

https://github.com/brendandebeasi/tabby

[+] johnthedebs|1 month ago|reply
Hey, this looks seriously awesome. Love the ideas here, specifically: the programmability (I haven't tried it yet, but had been considering learning tmux partly for this), layered UI, browser w/ api. Looking forward to giving this a spin. Also want to add that I really appreciate Mitchell Hashimoto creating libghostty; it feels like an exciting time to be a terminal user.

Some feedback (since you were asking for it elsewhere in the thread!). Happy to go into more detail about any of these if it's helpful:

- It's not obvious/easy to open browser dev tools (cmd-alt-i didn't work), and when I did find it (right click page -> inspect element) none of the controls were visible but I could see stuff happening when I moved my mouse over the panel

- Would be cool to borrow more of ghostty's behavior:

  - hotkey overrides - I have some things explicitly unmapped / remapped in my ghostty config that conflict with some cmux keybindings and weren't respected

  - command palette (cmd-shift-p) for less-often-used actions + discoverability

  - cmd-z to "zoom in" to a pane is enormously useful imo
[+] lawrencechen|1 month ago|reply
Thanks for the feedback! Mitchell Hashimoto is awesome. Have a PR for fixing devtools here: https://github.com/manaflow-ai/cmux/pull/117

> hotkey overrides - I have some things explicitly unmapped / remapped in my ghostty config that conflict with some cmux keybindings and weren't respected

We need to be better about this; right now you can modify keyboard shorcuts with cmd+, in the GUI. Planning on making it a config file in the spirit of ghostty though, not sure if we want to reuse ghostty's config file though since it might become a maintenance burden for them...

> command palette (cmd-shift-p) for less-often-used actions + discoverability

yes

> cmd-z to "zoom in" to a pane is enormously useful imo

Thinking of the right way to design this. Like hypothetically we can expand it, but what happens if you make a vertical/horizontal split, or cmd+t to make a new tab? I guess we could just "merge" it back into the original space which would be pretty cool.

[+] behrlich|1 month ago|reply
I had sort of the same idea. https://wingthing.ai/ This idea started at “sandbox” and worked its way toward “remote access”. But same thoughts about muxing sessions. Love being able to leave and reattach while an agent is working. I’ll give yours a shot!
[+] blorenz|1 month ago|reply
I like what you did here and with your direction with the stack. We have some common overlap. Last week I started clauding up something to manage my Claude sessions. It is built on Tauri 2 using xterm.js. It has is project-based and each project has resumable sessions. I borrowed inspiration from Happy coder and clauded an Expo app so I can claude remotely on-the-go. It has been a force multiplier in my clauding with developing new features and addressing bugs and defects. It was a pretty amazing feeling when I started using it to further its own development. There's a slew of other features as I adapt it to my development style.
[+] lawrencechen|1 month ago|reply
Mobile interface is definitely nice. Planning on adding iOS app since libghostty works there too! And I imagine that having your main terminal app be synced directly to your phone must be nice, though it doesn't solve the problem of closing my laptop.

Would love to hear what other features have been particularly beneficial to your dev style too. Some directions I'm interested in is having everything be programmable; so my coding agent can set up workspaces for me, click through browsers to test things, etc. And having a main Claude Code manage subagents that have their own easily visible terminal windows.

[+] sltr|1 month ago|reply
I've been looking for something like this. It was just two weeks ago I had Claude modify Wezterm to add tree-style vertical reorderable tabs. It works OK but your solution is nicer.

So I've been using cmux for a few hours this morning, and I like it. One thing I'd like to disable is the reordering of tab groups. Currently it shows the most recent notifications on top. This also makes the keyboard shortcut for a given conversation change all the time, which is a cognitive burden for me.

[+] gavmor|1 month ago|reply
Hm... any idea how I might script `git worktree` into the new-pane action?

Currently experimenting with agent-of-empires for tmux+worktrees to parallelize code changes.

[+] lawrencechen|1 month ago|reply
No built in way to override new-pane actions right now, but `cmux --help` can automate all parts of cmux.

So you can make your own script that can make new panels/workspaces and just invoke it from the terminal:

  git worktree add -b my-branch ../repo-my-branch
  ws=$(cmux new-workspace 2>&1 | awk '{print $2}')
  cmux send --workspace "$ws" "cd ../repo-my-branch && claude"
  cmux send-key --workspace "$ws" Enter
I think we should make this easier though, open to suggestions!
[+] snisarenko|1 month ago|reply
Hey, this is great. And looks similiar to WaveTerm https://www.waveterm.dev/

I currently use WaveTerm and it's pretty good. (But a bit laggy sometimes, i think it's electron based)

But both your terminal and waveterm are missing an important UX feature.

When you keep appending vertical terminals to the right (in the same view). They all get squished, to fit in the current window width.

Instead, I would love a horizontal scroll at the bottom, so I can have infinite termnial appending without having them squeezed to be smaller and smaller.

[+] twostorytower|1 month ago|reply
Looks like this could be really cool, but it's a buggy mess. Can't switch top tabs, can't close tabs. Once I lose focus in a tab, I can't ever type again in that terminal tab. Can't switch between the different sidebar tabs, either.
[+] mikkupikku|1 month ago|reply
Vertical tabs for a terminal emulator seems killer, I'll be trying this out for sure.
[+] anta40|1 month ago|reply
Yes it's cool. I wonder if other terminal emulator apps like WezTerm, iTerm etc also has this feature?
[+] jvican|1 month ago|reply
Have you looked into zmx? [0]

It doesn't have built-in notifications and there's no panel to see all the open sessions, but I wonder how hard that would be to add.

I've used zmx since I ran into it a few weeks ago. Uses libghostty as well. It's great because it allows me to replace tmux completely in all my ssh sessions, and can keep one session per assistant.

[0]: https://github.com/neurosnap/zmx

[+] lawrencechen|1 month ago|reply
zmx solves persistence well, and I like their minimalism (not supporting windows, tabs, or splits). I think it's possible to make a CLI wrapper for zmx that adds notifications though, so you can have some niceties of cmux without switching to a new terminal. Lowkey we might explore this direction as well.
[+] rcarmo|1 month ago|reply
Nice. I should add notifications to https://github.com/rcarmo/webterm - I already have sparklines as a CPU usage indicator and live thumbnails, but a visual highlight should be easy to add.
[+] swah|1 month ago|reply
If I were you, I'd just start always in what you call "dashboard mode". Its underwhelming to start it up and not see the "boxes" :)
[+] lawrencechen|1 month ago|reply
Cool project! How are you liking ghostty-web so far?
[+] pupppet|1 month ago|reply
Just took it for a spin, thought it was pretty nice. Some quirks with the tab dragging, you never really know what it's going to do on mouseup, a drop-target indicator would help.

Would love to be able to color the sidebar tab.

Nice work!

[+] lawrencechen|1 month ago|reply
Thanks! Will add drop target and sidebar coloring.
[+] boloust|1 month ago|reply
Looks really useful! Does this support the new Claude Code agent teams feature, so it will open all the team members in their own pane?
[+] lawrencechen|1 month ago|reply
We're working on a tmux/it2 compatibility layer to make this happen!
[+] arjie|1 month ago|reply
This is pretty slick, man. The only thing is that the Ctrl-Cmd-] is too hard to press but I'll just use the number thing.
[+] lawrencechen|1 month ago|reply
Thank! I personally have caps lock mapped ctrl... but open to suggestions! Since it's hard to handle both horizontal and vertical tabs.
[+] AM1010101|1 month ago|reply
Awesome work, keen to try it out tomorrow. Can I make the notifications work with Gemini CLI and Kiro CLI too?
[+] lawrencechen|1 month ago|reply
Thanks! Yup, notifications can be triggered via cli:

  cmux notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input"
And afaik, both Gemini/Kiro should have stop hooks. If they send OSC notifications, then notifications will "just work" as well.

Docs: https://www.cmux.dev/docs/notifications

[+] warthog|1 month ago|reply
vertical tabs are a great idea for ghostty!
[+] rubyn00bie|1 month ago|reply
This looks cool. I honestly haven’t ever thought about using vertical tabs in a terminal window but that seems nice.

One question though, have you thought about trying to upstream any of this into Ghostty instead of making an entirely different app?

[+] lawrencechen|1 month ago|reply
Upstreaming into Ghostty would be very difficult as it's not actually a fork, I just used libghostty under the hood.
[+] simlevesque|1 month ago|reply
VSCode has vertical tabs for it's terminals like this, but on the right side.
[+] goro-7|1 month ago|reply
Good idea, but I don't want to move to another terminal now, will stick with Ghossty
[+] lawrencechen|1 month ago|reply
Fair enough! I like Ghostty a lot too, and the only reason I built this was because I wanted vertical tabs and nicer notifications.