Skip to content
Merged
110 changes: 46 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h1 align="center">flue</h1>

<p align="center"><strong>Continue your Claude Code and Codex sessions on any screen.</strong></p>
<p align="center"><strong>Your Claude Code sessions and terminals, in one place.</strong></p>

<p align="center">
<a href="https://github.com/karnstack/flue/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/karnstack/flue/ci.yml?branch=main&label=ci" alt="CI status"></a>
Expand All @@ -26,28 +26,29 @@
</picture>
</p>

Start on your laptop. Check in from your phone or iPad. Pick up again at your
desk. The shell stays on the machine; flue moves the view.

A small Go daemon holds the shells and their scrollback, and a web app draws
them. Closing the tab does not kill a session. It only detaches it: the agent
keeps working, the build keeps running, the SSH session stays up, and
reattaching replays what you missed.

- **Sessions outlive the tab.** Close it and the build keeps running.
- **One list, every machine.** Name, tag, pin, group and search the whole
fleet from one place. Hover a session to see what it is doing.
- **One keystroke to any of them.** `⌘K`, or `Ctrl+Shift+K` anywhere, opens
every session on every machine. The highlighted row shows its own last
fourteen lines, so you can see which one is the build. `Ctrl+Shift+1` to `9`
jumps to a pinned session.
- **Reachable from anything you own.** Pair a phone with a QR code, once for
the whole fleet. Two devices on one session mirror live, and the size follows
whichever view you are using.
- **No hosted service.** Remote access runs through a relay you deploy into
your own Cloudflare account, end-to-end encrypted, with the daemon's key
pinned at pairing. flue.sh is a landing page and is never part of the data
path.
flue is a daemon that keeps terminal sessions alive, and a web app that lists
every one of them across your machines. Claude Code, Codex, Pi, builds, SSH.
Name them, tag them, pin them, find them, open them from any screen you own.

- **Sessions outlive the tab.** Close it, the agent keeps working. Reopen it,
the scrollback replays.
- **Sessions outlive flue.** Each one runs in its own holder process. Update
or crash the daemon, nothing stops. After a reboot, each comes back with its
history and the command that resumes the conversation.
- **One list, every machine.** Group by machine or by tag. Name, tag, pin,
search. Drag a row onto a group to retag it. Save a view.
- **One keystroke to any of them.** `⌘K` or `Ctrl+Shift+K` lists every session
on every machine, and the highlighted row shows its last 14 lines.
`Ctrl+Shift+1` to `9` jumps to a pinned one.
- **Splits and tabs.** `⌘D` splits right, `⇧⌘D` splits down, `⌥⌘T` opens a
tab. `⌘/` lists every chord, spelled for the keyboard you are on. Linux and
Windows use Ctrl.
- **Agent history.** Every Claude Code, Codex and Pi conversation from every
machine. Search it, see tokens and cost per day, read the transcript, resume
it in a terminal.
- **Files.** Select a path in a terminal, peek at the file, open it in a tab.
- **Phone and tablet.** Pair once with a QR code. A key bar with Esc, Tab,
arrows and Ctrl. Two devices can mirror one session.

One static Go binary. macOS, Linux, WSL. No Node, no Python, no toolchain.

Expand All @@ -64,33 +65,21 @@ survive your last logout. If lingering cannot be turned on, which happens in
some containers, `flue enable` warns you and names the command to run.
Everything after that happens in the browser.

## Recommended setup
## More than one machine

One relay, every machine joined to it, every device paired once.

1. Install flue and run `flue enable` on every machine that runs work: the
laptop, the desktop, the Pi, the VPS.
1. Install flue and run `flue enable` on every machine that runs work.
2. Run `flue relay setup` **once**, on one machine. Running it again does not
add a relay, it replaces the one you have: every machine then has to re-join
with the newly printed line, and every device has to pair again.
add a relay, it replaces the one you have, and every machine and device
has to join and pair again.
3. Run the `flue relay join` line it prints on every other machine.
4. Pair each phone or tablet once, from a QR code. That pairing covers the
whole fleet, so there is no second ceremony per machine. It is per browser,
so Safari and Chrome on one iPad pair separately.
whole fleet. It is per browser, so Safari and Chrome on one iPad pair
separately.

Long jobs belong on a machine that stays on. A sleeping laptop's sessions are
not lost, but nothing runs until it wakes.

The full version is at [flue.sh/docs/setup](https://flue.sh/docs/setup).

## Sessions outlive flue

Every session runs in its own small holder process, not inside the daemon.
Updating flue, restarting it, even the daemon crashing outright: the shells
and agents keep running, and the next daemon picks them back up with their
scrollback where you left it. A machine reboot is the one thing that ends a
session, and even then flue brings it back with its history, a fresh shell,
and the command that resumes the agent conversation it was in.
The full version, with a recording of the whole thing, is at
[flue.sh/docs/setup](https://flue.sh/docs/setup).

## The CLI

Expand All @@ -112,25 +101,26 @@ flue version # print the version (also --version, -v)

## Remote access

The daemon listens on loopback and nothing else, so reaching it from somewhere
The daemon listens on loopback and nothing else. Reaching it from somewhere
else is opt-in and takes one command:

```sh
flue relay setup # machine 1: paste a Cloudflare token
flue relay join wss://<your-relay> --secret <...> --fleet <...> # every other machine
```

That deploys a Worker **and** this web app into your own Cloudflare account,
on the free plan. The same deploy is a card on the UI's Remote screen. One
relay fronts every machine you own, and pairing a device covers the whole
fleet rather than one machine.
That deploys a Worker and this web app into your own Cloudflare account, on the
free plan. Everything crossing it is end-to-end encrypted with Noise IK, with
the daemon's key pinned when a browser pairs, so the Worker forwards ciphertext
it holds no key for. There is no flue account, no flue server and no billing.
flue.sh serves docs and downloads and is never part of the data path.

What it deploys and what it costs is at
[flue.sh/docs/relay](https://flue.sh/docs/relay), with the operator-grade
version in [docs/RELAY.md](docs/RELAY.md). What a hostile relay origin could do
despite the end-to-end encryption, which is the honest version because the
browser loads its JavaScript from that origin, is in the
[FAQ](https://flue.sh/docs/faq) and at length in [docs/faq.md](docs/faq.md).
despite the encryption, because the browser loads its JavaScript from that
origin, is in the [FAQ](https://flue.sh/docs/faq) and at length in
[docs/faq.md](docs/faq.md).

<p align="center">
<img src="docs/architecture.png" width="830"
Expand All @@ -139,18 +129,11 @@ browser loads its JavaScript from that origin, is in the

## Status

Released and in daily use. v0.5.1 is the current release, `brew install
karnstack/tap/flue` gets it, and the whole of it works: the local terminal, the
login service, the fleet-wide sessions list, pairing, and the Cloudflare relay.
The relay has been through its manual end-to-end gate
([docs/RELAY.md](docs/RELAY.md)) against a real account, with a phone on a
different network paired to it and a second machine joined to the same relay.
There is a recording of that run at
[flue.sh/docs/setup](https://flue.sh/docs/setup).

It is 0.x, which means what it usually means: commands, flags and the config
file can still change between releases, and an upgrade may ask something of
you. Known rough edges live in [docs/FOLLOW-UPS.md](docs/FOLLOW-UPS.md).
Released and in daily use. The current release is on the
[releases page](https://github.com/karnstack/flue/releases/latest), and
`brew install karnstack/tap/flue` gets it. It is 0.x, so commands, flags and
the config file can still change between releases. Known rough edges live in
[docs/FOLLOW-UPS.md](docs/FOLLOW-UPS.md).

flue is open source and always free.

Expand All @@ -169,4 +152,3 @@ under [site/](site/), and `make site-dev` runs it.
## License

[MIT](LICENSE)

Loading
Loading