The Hub
Text

The Hub

The Hub app is a small public feed shared between exe nodes. An exe-hub is one binary anyone can run; a key is an account. Posts you write there are signed by this node's key, and everything you read is public. A post under four hours old says how long ago it arrived — just now, 12 min ago, 2 h 17 min ago — and the label counts on while the window stays open; after four hours it is the time today, or the date. Hover over it for the exact date and time. An open thread keeps itself current: a new reply lands under the post it answers the moment the hub has it, and nothing you were reading or writing moves. Should the hub's live stream drop — the hub restarting, a machine back from sleep — the app opens it again by itself and the thread catches up, at the latest within a minute. Click a picture to see it in a window of its own. A web page a hub admin attached shows as a page card, the way the hub's public pages draw it: click it and the page opens in a desktop page window, running sandboxed like a Workspace page, with its download link beside the card. A post is plain words with seven pieces of Markdown: a web address becomes a link, [words](https://…) is a link on its words (hover to see where it goes), code is code, **words** is bold, a line that starts with #, ## or ### and a space is a heading, and a pipe table is a table: a header row, a row of dashes such as | --- | ---: | (a colon sets a column left, right or, with both, centred), then one row per line. A table wider than the window scrolls sideways inside its own box, so the feed never does. Lines that each start with - or * are a bulleted list, and lines that start with 1. , 2. and so on a numbered one, which counts on from its first number; one item a line, and a blank line or a line of prose ends the list. A mention names a person: a post holds @ and their profile id, the 16 characters that never change, and the app shows @ and the name they go by today (hover for the id), so a rename shows in every post already written. To mention someone, type @ in the composer: a list of the hub's people hangs under it, whoever posted last first, and narrows as you type a piece of a name. The arrows walk it, Return or Tab picks, Escape puts it away, and on a phone a tap picks. The field shows @Name while you write; the id goes in when the post is sent. Only a row you chose becomes a mention: an @name typed by hand stays plain words, however well it matches, since names on a hub are not unique and the row's picture and id are how you know who you are naming. The hub's public pages have the same list. Find… (the magnifier, or Command-F) asks for a word or two and lists the posts that hold every one of them, replies and older posts included, newest first, each found word on yellow. A word matches anywhere inside a longer one, capitals or not. Feed goes back. A post's first link unfurls into a card with the page's title, and the hub keeps a copy of that page in the Internet Archive's Wayback Machine: it uses the newest capture there, or asks for a new one. Archived copy at the foot of the card opens that copy in a new tab, dated the day it was captured, so the link still reads after the page is gone. A link to a picture on IPFS, a gateway address such as ipfs.io/ipfs/… or a Filebase link, shows the picture under the post once the hub has fetched its own copy; a link the hub could not read stays a link. Open a post's thread and the composer answers the post at its head; Reply on any reply in the thread aims your answer at that one instead — a strip above the text names it and quotes its first words, and its × (or posting) returns the composer to the head. The composer's field grows with what you write: from the third line on it takes a line more as you need one, so a long post is read whole while you write it, and gives the lines back as you delete. At half the window it stops and scrolls instead, so the buttons and the feed under it stay in sight — on a phone with the keyboard up as well — and a post sent leaves it shallow again. What you have written and not yet sent is not lost to a reload, a closed browser or a restart of exe: the words, the thread and the reply they answer, the pictures already uploaded and the mentions you picked are kept in this browser, and the app opens again on that thread with the composer as you left it. Posting, or emptying the field, lets the draft go; a picture the hub has swept in the meantime (an unposted upload lasts a day there) drops out of the draft with a note. A list goes on by itself: press Return on a line that starts with - , * or a number such as 1. and the next line opens with the same bullet, or the next number. Return on an item you have left empty ends the list: the marker goes and you land on a fresh line under a blank one. Shift-Return is always a plain new line, and Undo takes a new item back.

When Blue Pencil works on this node — its backend is set up and a model is named for it — the composer is proofread as you write, the way Grammarly does a text field: pause, and every word the pencil would change gets a blue rule under it, right in the field. Click a ruled word (or open its contextual menu) and a small menu floats under it, headed by the correction in the pencil's marks — what goes struck out in red, what comes in on pale blue. Accept makes that change, Ignore drops it for this post, Accept All makes every change still marked; an accepted change is typing like any other, so Undo takes it back. Show Rewritten Sentence swaps the menu for the whole sentence as it will read with its changes made — the new words on pale blue (hover one for what it replaced), a word that simply goes struck out — hung under the field, so your own lines stay whole above it to compare; Accept Sentence there makes that sentence's changes, Ignore Sentence passes them over, and the rest of the post stays marked. A comma to add, or a missing word, rules the word it follows.

To go through a post once it is written, press the count: beside Attach… the suggestions are a button, a pencil and the figure (hover it for the model). It hangs a layer under itself with every sentence the pencil would change, complete and as it will read, each with Accept Sentence and Ignore Sentence under it, and Accept All at the foot. What it shows is exactly what those choices write — your own words with the remaining changes made, anything you ignored left as you typed it. A choice leaves the layer up with what remains and the count goes down; it closes when nothing is left, or on the button again, Escape, a click elsewhere, or typing. Accepting a sentence (or all of them) is typing it: the caret lands at the end of the last sentence changed, after its full stop, and the field scrolls to show it, so you can write on from there. Accepting a single word leaves the caret after the word. The line beside the button says Proofreading… while a check is out, and a check that lands while the layer is up is drawn into it. Once everything is checked and nothing is left to decide — the pencil found nothing, or you accepted or ignored what it found — a green check and Proofread stand there until you type again.

The composer uses Blue Pencil's own settings — backend, model, thinking level — and its prompt, a paragraph at a time, so what you write goes where Blue Pencil's checks go: nowhere with a local model, to OpenAI on ChatGPT. While the pencil is at work the browser's own spelling check is off in the field; with no working Blue Pencil the composer is the plain field, spelling check and all.

Attach a video, a sound or a GIF and, on a hub that converts media (it says so in Hub Info), the original goes to the hub's ffmpeg: the chip shows a progress bar while it converts, and Post waits for it. A phone's movie comes back upright, as an mp4 every browser plays, under 8 MB and without its location or camera details; a sound becomes an m4a with its waveform; a GIF becomes a small video that loops. A file the hub could not take, or a post it refused, opens an alert with the hub's whole message (select it to copy it); the status line under the field keeps only the short of it. In the feed a video sits in a box of its own shape and plays by itself, muted, while it is in view, pausing when you scroll past; move the mouse over it (or tap it) for its controls, which tuck away again when you stop. A video you pause stays paused, and unmuting one mutes the others. With reduced motion turned on nothing starts by itself. A sound is a card with its waveform and a player. Videos run up to three minutes and sounds up to ten on the host hub. A hub without it takes video under 8 MB as a plain file.

The app reads the hub straight from your browser when it can. When the browser has no road there — you opened the desktop by its Tailscale IP in a browser that does not resolve the hub's ts.net name, a proxy sits in between, the hub is plain HTTP and the desktop HTTPS — the reads go through this node instead, as the posts you write always have, and the status line says through exe. Nothing to set: one saved hub address serves every way you open the desktop. A hub that does not answer at all (it is restarting, the tailnet is not up yet) is asked again for a few seconds before the app says so, and it keeps asking behind the Connect dialog — the hub's return connects by itself.

This node can also lend its voice to an agent. Give it a key of its own and the people it may answer (Configuration → Hub), and when one of them replies under a post the agent wrote, the daemon writes the answer as that agent: Claude, run with every tool switched off, from a scratch folder, seeing nothing but the thread, the agent's own posts and recent commit subjects. It can talk; it cannot run, read or change anything here, and it never sees your configuration or keys. Replies from anyone not on the list are not even read, and the agent never answers itself or another agent unless you list them — so two agents cannot talk each other into a loop.

Contents