Which machine needs you?
One page for every machine running your AI agents: which are up, what runs on each, and which one is waiting for you. That one comes first. Click a session and you are in that terminal, on that machine.
curl -fsSLO https://raw.githubusercontent.com/andreaderuvo/panoptes/master/install.sh && bash install.sh
Reads the Argus on each machine. Runs on Linux, macOS and Windows, needs no tmux, and fits in a container.
When one machine becomes three, you become the polling loop.
A tab per machine, and you going round them. The agent that finished forty minutes ago finished into an empty room. The board does the going round for you.
Without it
- Three tabs, and you check each of them in turn.
- Which box had the full disk? You open all of them to find out.
- A machine that is off looks exactly like one you forgot you had.
With the board
- One page, sorted: waiting for you first, whatever machine it is on.
- Load and the fullest disk on every tile, amber over 74%, red over 90%.
- A machine that stops answering goes red and stays, saying when it last called in.
A tile says what the machine said
Name, state, load, memory, the fullest disk, and one chip per tmux session. A chip is a link into that session, on that machine's own Argus.
Plus one line of yours
A note per machine, in pencil: what the box is for, what it was doing. It is the only part of a tile that only you know.
A colour per machine
Taken from the name, so it is the same on every device you open the board from, and yours to change.
It can look. It cannot get in.
The board reads a handful of numbers off each machine, and it is built so that losing it costs you a list of session names.
One read-only key per machine
A watcher token opens GET /api/overview on
that machine's Argus and nothing else: no shell, no files, no writes, no proxy.
No key reaches a browser
The board holds them and the page never sees one. A click opens that machine's own Argus, in its own origin, with its own token.
No shell of its own
No terminal, no file browser, and no way to run a command it was not given by name on the machine itself.
Two directions, because networks are not symmetrical.
Local pull, remote push: the same arrangement as Prometheus in agent mode, or any dial-out agent such as Tailscale or the kubelet.
The board asks
Write the machine down and it gets polled. A request that fails is itself the signal that the machine is down.
# ~/.config/panoptes/config.yaml
machines:
- name: hetzner
url: http://hetzner.internal:8090
token: <a watcher token from that machine's Argus>The machine calls in
Some networks only open one way. Then the machine opens the connection, in the direction that already works.
# argus config, on the machine that cannot be reached
report_to:
url: http://board.internal:8070
token: <the registration token>
name: gpu2
every: 10Announcing and looking use different tokens: the registration key cannot read the board, and the board's key cannot invent machines. The list you wrote by hand wins, so nothing holding the registration key can replace a real machine with one of its own. And a machine that stops calling in goes cold instead of staying green for ever.
Start and stop, without a command in a request.
The menu on a tile can start and stop things on that machine. Each machine publishes named things in its own config, and the board may ask for one of those names and nothing else.
Named by the machine
Only what a machine lists under
runnablecan be started or stopped, and only by a watcher allowed to.Stopping Argus asks twice
And says what it costs: every tmux session keeps running, but starting Argus again takes a shell on that machine.
Every press is written down
The board's journal keeps who pressed what, and the address it came from.
# argus config, on the machine runnable: - name: nightly run: python3 nightly.py watchers: - name: panoptes token: … may_run: true # otherwise the token stays read-only may_stop_argus: false # the one thing this board cannot undo
A glance, from anywhere.
On a phone the board is one column in the same order, so the answer is at the top of the screen. It follows your light or dark setting, and installs as an app where the certificate allows it.
Running in a minute.
Python 3.11 or newer, on Linux, macOS or Windows. The first run prints a link with a token in it, and shows a demo board until you tell it about a machine.
# read it first, then run it curl -fsSLO https://raw.githubusercontent.com/andreaderuvo/panoptes/master/install.sh less install.sh && bash install.sh panoptes # prints a URL with a token in it panoptes --qr # and a code to photograph
No sudo, nothing outside your home, and the same line again updates it.
git clone https://github.com/andreaderuvo/panoptes && cd panoptes
docker compose up -d
# images for amd64 and arm64: ghcr.io/andreaderuvo/panoptesHere a container is the natural shape: the board has no tmux, no files and no terminal to reach into, so it needs nothing from the host.
git clone https://github.com/andreaderuvo/panoptes && cd panoptes
pip install -r requirements.txt
python3 -m app.main # prints a URL with a token in itThen add your machines, or let them call in: the machine guide has both, with the exact configuration on each side.
Before you try it.
Do I need Argus for this?
Yes. The board reads each machine's Argus and links back into it. Argus is one machine in a browser tab; the board is every machine on one page. Start with Argus, and add the board when one tab per machine stops scaling.
What does it actually hold?
Per machine: a name, a URL, a read-only watcher token, an optional colour and your note. Per sweep: hostname, uptime, load, memory, the fullest disk, and the session names with which of them is waiting. No file, no path, no command.
What happens when I restart the board?
The machines that called in are still there. A machine you stopped goes red instead of vanishing, because for the one question the board answers, gone and never-existed must not look alike. Forgetting one is something you do on purpose.
Can several people watch one board?
Yes, and the journal is why that works: a machine only knows that the board pressed stop, while the board knows which browser the click came from.
What is it built with?
Python on the server and plain JavaScript in the browser. No build step and no database: one file for the config, one for the machines that called in, one for the journal. MIT licensed.