← flue.sh

How flue works

A daemon owns the shells. A tab draws them. What that gives you, and what it costs.

Sessions own their shells

Every session is a small process of its own that holds the shell and its scrollback. A Go daemon coordinates them, and everything that draws them is a client, including the tab you are reading this in.

The whole product rests on that one move. Normally a shell belongs to the window that opened it, so closing the window takes the work with it. Here the shell belongs to a process that outlives every window, and the window becomes a view instead of an owner.

Closing the tab does not kill the session. It only detaches it. The build keeps running, the agent keeps working, the SSH session stays up. Reattach and the session replays the scrollback you missed.

It outlives the daemon too. Updating flue, restarting it, even a crash: sessions keep running through all of it, and the next daemon picks them back up where they were.

Every device is another view

A client only draws, so there can be more than one. Attach from two devices and they mirror live: what you type on the phone appears in the laptop’s browser.

Size follows the view you are using. Pick up the phone and the session fits the phone. Type on the laptop and it fits the laptop again. Being held at another view’s size is the failure that makes most screen sharing useless for real work.

One list, every machine

Join more than one machine to a relay and the sessions screen shows all of them together, grouped by machine, with the same search, tags and pins across the whole fleet. Finding out what is running stops meaning logging in to everywhere.

One keystroke to any of them

Press ⌘K on a Mac, or Ctrl+Shift+K on any platform including macOS, from any screen that can see a daemon. Pinned sessions come first, with number keys on them, then the sessions this browser has opened before, then the rest.

The highlighted row shows its own last fourteen lines beside the list, so you can see which one is the build instead of guessing from its name. Ctrl+Shift+1 to 9 jumps straight to a pinned session. Ctrl+Shift+] and Ctrl+Shift+[ step forward and back through every session, not only the pinned ones. None of them open the list.

When a machine goes unreachable the fleet stops listing its sessions, on purpose: rows from a machine nobody can reach are a claim it cannot stand behind. The switcher still shows the ones this browser has opened before, greyed and marked unreachable, and it still opens them. That memory is per browser, so what your laptop remembers is not what your phone remembers.

Installing it

One static binary and no runtime. flue enable installs a login service so the daemon comes back after a reboot, starts it, and opens the UI.

$ flue enable  ✓ login service installed  ✓ daemon running on 127.0.0.1:7717  opening http://127.0.0.1:7717

The daemon listens on loopback and nothing else. Reaching it from another device is opt-in, and the order to do things in is in the setup guide.

The CLI stays small

Everything after flue enable happens in the browser. The commands exist for the things a browser cannot do.

flue enableInstall the login service, start the daemon, open the UI.
flue disableRemove it.
flue statusCheck the daemon, the login service and the sessions.
flue open [path]Start a session here. Useful from a shell prompt.
flue serveRun the daemon in the foreground, with no login service.
flue relay setupDeploy a relay into your own Cloudflare account.
flue relay joinPoint this machine at a relay another machine deployed.

Where the code is

The daemon, the web app and the relay Worker are all MIT licensed in one repository. The dev loop and the split between dev and prod are in DEVELOPMENT.md. The rough edges we already know about are in FOLLOW-UPS.md.

Other pages