Every project a ship
The dashboard has known for a while which projects have an coding agentAn AI you give a task and some tools, and it edits files, runs commands and iterates on its own until the task is done. Claude Code and Codex are the two I use. working on them, because every Claude or Codex session sends small events as it goes: started, working on this task, committed, finished. For a while that turned into a list of lanes, one per session, with timestamps. Accurate and completely dead to look at. The work was happening and the page made it look like a spreadsheet was happening.
A harbour instead of a table
So the activity page became a harbour town. Every project in the fleet is a ship. The ones with work going on are tied up along the quay; the quiet ones ride at their moorings out in the bay, so the whole fleet is on screen at once and you can see at a glance which hulls have crew aboard. Each ship’s hull colour, sail colour and Jolly Roger come from a style seed hashRunning some text through a function that always turns the same input into the same jumbled number. Handy for giving each project a stable colour without storing one. from the project’s name, so a project looks the same every time you load the page without anyone having to pick colours for twenty ships.
Each agent session is a sailor, and sailors get names. Not “Claude” and “Codex”, which made every deck look like a staffing agency, but generated pirate names from the same kind of seed, stable for the life of the session, so the one hauling cargo up the gangplank on one project is recognisably the same one who wanders off to the tavern when it finishes. A gitThe tool that tracks every change to your code and lets you go back to any earlier version. The history lives in a hidden .git folder inside the project. sends a crate up the gangplank and down the hatch. A sailor who’s done goes into The Plastered Bastard. A session that’s gone quiet for too long falls asleep sitting up against the mast, which took two attempts, because the first version had him lying on his side and it looked like a crime scene.
Underneath the harbour runs the ship’s log, one line per event, newest at the top, repeats folded together so twelve commits in a row read as one line with a count. Clicking a ship zooms the harbour in on it and opens a card with the crew and what they’re working on.
The same port, seen from the street
The fun part was making it public. x-hakt.com/crew shows the same scene, embedded from the dashboard, and the dashboard itself stays behind a login. The public feed is built from a whitelist rather than a filter: every field that goes out is chosen on purpose, times are rounded, task keys and host names never leave, and a project only appears under the alias I’ve approved for it. Down here, it’s our time, and you can watch it, but you can’t read the charts. The iframeA web page embedded inside another web page, in its own box. The outer page can't reach inside it, so the two talk by passing messages. sizes itself by a postMessage from the embed, checked against the originThe scheme, host and port a page was loaded from, like https://control.x-hakt.com. Browsers use it to decide who is allowed to talk to whom. and the source window before the page believes a word of it, and there’s a full width button and a full screen one, because a harbour crammed into a blog column looks like a harbour seen through a keyhole.
None of it does anything useful that the old lanes didn’t. It’s just that I now leave it open on the second screen, and I never once left the lanes open. Fair winds.
-x