tutorial
Across the hosts.
So far fleet-top has watched your machine. Now we reach one running on
another box, over ssh, and show its top in your browser — using the exact
same surface. The trick is a mirror: the remote box serves the surface, a
local parent folds its frames into a local copy of the same surface and re-serves
that, and the browser only ever talks to the local copy. Swap the box behind it
and the browser never notices.
The agent — what runs on the far box
The remote side is tiny: it serves the same top surface over stdin/stdout. This
is what the parent runs on each target — ssh <host> fleet-top-agent --stdio for
a remote box, the realised binary directly for localhost. It is ephemeral — a
fresh one per link — which is the right shape for a re-run-fresh reader like top.
/**
* fleet-top-agent — serve the `top` surface over stdin/stdout.
*
* This is what `ssh <host> fleet-top-agent --stdio` runs on the far box. The
* agent is ephemeral (a fresh one per link — `serveOverStdio` makes THIS
* process be the server, so it's gone when the link drops); the parent's
* `makeSession` re-spawns it on reconnect. That's the right shape for a
* re-run-fresh reader like `top`.
*
* **Stdout is the protocol channel** — every diagnostic goes to fd 2. A stray
* write to fd 1 corrupts the next frame.
*/
import { serveOverStdio } from "@kolu/surface/peer-server";
import { createTop } from "./top";
function log(line: string): void {
process.stderr.write(`fleet-top-agent: ${line}\n`);
}
async function main(): Promise<void> {
if (!process.argv.slice(2).includes("--stdio")) {
process.stderr.write("usage: fleet-top-agent --stdio\n");
process.exit(1);
}
const top = createTop();
top.start();
log(`serving top over stdio (pid ${process.pid})`);
const end = await serveOverStdio({
router: top.router,
onFirstRequest: () => log("first RPC received — link is live"),
});
top.dispose();
log(`stdin closed (${end.reason}) — agent exiting`);
}
main().catch((err) => {
log(`fatal: ${(err as Error).message}`);
process.exit(1);
});
The three-hop mirror
On the parent, each host is one binding. First, dial it —
makeSession({ connectOnce: sshConnector(...) }) provisions the agent closure
onto the box and runs it (over ssh for a remote host, directly for localhost),
reconnecting on drop.
const session: Session<
AgentClient<typeof surface.contract>,
SshProv
> = makeSession({
initialConnection: "probing",
connectOnce: sshConnector<typeof surface.contract>({
host,
binary: "fleet-top-agent",
// Constant resolver — this demo takes the agent .drv from the environment.
// A consumer that picks the .drv per host's nix-system passes an async
// `resolveSystem(host)` probe here instead.
resolveDrvPath: () => Promise.resolve(agentDrv),
}),
label: `host:${host}`,
});
Then pump the agent’s frames inward, folding each into a local
implementSurface of the same surface. The local copy is what browser
subscribers read; makeSink writes the incoming frames through its ctx.
let firstLoad = true;
void pumpRemoteSurface({
source: surface,
session,
makeSink: () => {
firstLoad = true;
return {
cells: {
load: (v) => {
if (firstLoad) {
firstLoad = false;
session.markConnected();
}
fragment.ctx.cells.load.set(v);
},
memory: (v) => fragment.ctx.cells.memory.set(v),
},
collections: {
processes: {
upsert: (k, v) => fragment.ctx.collections.processes.upsert(k, v),
remove: (k) => fragment.ctx.collections.processes.remove(k),
},
},
};
},
});
Finally re-serve: a directLink over the local fragment’s flattened router is
the link the browser reaches. Three hops — dial, pump, re-serve — and the surface
that started on another machine now serves from this process.
Watch it arrive
-
Point the parent at one host and start it.
HOSTis the target (localhosthere — no ssh needed);FLEET_TOP_AGENT_DRVis the agent’s flake output, resolved in place.# resolve the agent .drv (works from anywhere in the repo): export FLEET_TOP_AGENT_DRV="$(nix eval --raw "$(git rev-parse --show-toplevel)#fleet-top-agent.drvPath")" HOST=localhost pnpm run devfleet-top part 3 serving 1 host(s) on http://localhost:7740 -
Open http://localhost:5176. The header chip shows the host warming while the agent closure is realised, then flips to connected — and the same live
topyou built in part 1 fills in, this time streaming from the agent the parent stood up (onlocalhost, directly; on a remote box, over ssh).
You changed nothing about the surface or the browser code. The box could be a laptop across the room; the mirror makes it read like local state.
Next
One box is a mirror. Many boxes is a map. In A fleet of surfaces you gather N hosts into one keyed surface, render them as chips, and watch a single box’s trouble stay confined to its own chip — the moment fleet-top becomes a mini-drishti.