Launching today
tabsh
Work with agents with an IDE in your browser tab
64 followers
Work with agents with an IDE in your browser tab
64 followers
Most ADEs bring the browser into the IDE. tabsh takes the opposite approach: bring coding sessions to your browser, where your work already happens. It's a small Rust daemon that puts all your sessions across projects on one Kanban board/list, with status updates via agent hooks. Use real terminals or chat panels with Claude Code, Codex, Cursor CLI, OpenCode, and more. Free, MIT-licensed, macOS/Linux.





Maker here! My ADE was the last thing I kept ⌘-Tab-ing to. Issues, PRs, docs, design, and localhost were all in the browser. Why not bring the ADE there too?
tabsh is a small Rust daemon that brings all your coding-agent sessions into one browser board, across projects. Hooks update statuses automatically, including when an agent needs your input.
Everything runs locally. No account, no server, macOS and Linux.
Free, MIT-licensed. I'd love you to give it a try and fork it and make it your own.
how does the daemon guards localhost against DNS rebinding and cross-origin requests ? does the token check also validates Origin and Host headers, or what's planned next ?
@boutar_badii
Great question. All three are checked in one guard that wraps every route.
1. Host first, unconditionally:
only localhost, tabsh.localhost, or a literal IP is accepted. Anything else gets a 403. That is the DNS rebinding defence. A domain resolving to 127.0.0.1 still sends its own name in Host, so it is rejected before anything else runs.
2. Origin, when a browser sends one:
it must exactly match http:// (the page we served) or the allowlisted hosted origin (tabsh.cc, replaceable via TABSH_ORIGINS). Anything else is a 403, even with a valid token.
3. Token, separately:
with an Origin present, a valid token is still required (401 without one). It is compared in constant time and stored 0600.
@blaise_tiong2 would a request without an origin header still require a token ? ex: curl or local processes do not usually send that header ?
Across several projects, I'd want sessions waiting on me to be the first thing I see. Hook-based status updates seem a useful way to keep that view current.