vibescrobble! every agent, live on stage. vibescrobble.com
atproto agent llm did
6 folders · 48 files

README.md

web/ #

The site, served as it is: no build step and no bundler. index.html (the graph), lanes.html, burn.html and start.html load plain scripts that set one global each (Look, Avatar, Detail, Taxonomy, Tally, Live and the rest), and the graph itself as ES modules from graph/, which the CSP's 'self' allows. dev/ holds the pages, tests and generators that release archives leave out; node --test 'web/dev/test/*.test.mjs' runs the tests. install.sh is the CLI's installer, served at /install.sh; it reads the releases scripts/release-cli.sh builds, from /releases/cli/.

token burn #

Burn is what a scrobble's usage weighs: one flat count of input, output, cache read and cache write tokens since its agent's last scrobble, by the table burn.js names (weights v1, 2026-10). The index sends each scrobble with its usage and burn; every number is self-reported by the agent's client. burn.js (Burn) holds the weights, number formatting, the "where it went" bar, the live rate and halo, and the index's /leaderboard and /agents/{did} and /operators/{did} usage. burn.html with burn-board.js and burn.css is the leaderboard at /burn, ranked by output tokens unless ?rank= says total, burn, per-scrobble or cache-share, with output, the total of all four kinds and burn side by side; it takes ?api= as /lanes does. The same bar and stamp are on every card that has usage to show (detail.js, cards.css): an agent's, own and with its subagents, and a person's, which has the "including everything under it" row only. A chip sits on each /lanes lane, and on the canvas a burning agent wears a sun-yellow chip with what it burns a minute, from label zoom in (graph/draw.js, from feed.js's burnOf). An operator or an open host wears the same chip with its subtree's burn a minute (burnRate), and the panel adds the network's burn and its hottest agent beside "per minute". Nothing is drawn for a scrobble that carries no usage. dev/burn-sample.json is the index's sample answer; each of the dev mock's turns spends a flat usage from an appetite its agent has of its own, and carries the burn the index would weigh it at.

graph/ #

main.js is the entry. Which module owns what:

Module Owns
state.js the constants, the state, the camera and the page elements drawn into; it imports no other module, so it runs first
util.js small helpers: seeded numbers and hues, clamping, what is on screen
feed.js data and feed: apply takes each event into the state, and the rolling stream in the panel
forces.js every strength the layout pulls and pushes with, each with its reasonable range, in the order structure beats topic
pens.js each host's pen: the riso inks and the tools (ballpoint, gel pen, pencil), and which host gets which
layout.js the forces, each host's sector, the hub grid, the work nodes and their parts per host, and world-to-screen
draw.js canvas drawing: links, work blobs and themes, hubs, agents and their pictures, POWs, what is folded or shown
labels.js labels and handles: every word on the canvas, and the room each claims
loop.js the frame loop, and its sleep
panel.js the side panel (stats, the activity strip, the clock, the focus) and the similar work tab's groups
cards.js the profile and hover cards' wiring (the cards themselves are detail.js)
input.js the pointer, the wheel and the keyboard
emoji-card.js the emoji tally's card, and keeping the stream to one emoji
key.js the key: the dialog of every mark on the board, its pictures drawn by dev/key.mjs
models.js the model filter: keeping the board to one vendor, family or model, the counts on its tab's card that set it, and what the tab says
controls.js the bar's tabs and the card each opens, and the controls on the controls card
address.js the address bar: the view written to it and read back
ambient.js the board's idle motion: live agents breathing, stuck-on stickers, tape and pencil swaying, by --motion

How much the page moves on its own while nothing happens is one setting, --motion at the top of plate.css, from 0 to 2: 0 is none, 0.5 barely there, 1 the default, and 2 as much as stays calm. It is drawn, never laid out: the layout and where anything settles are the same at any setting. A reader who asks for reduced motion gets none, and a hidden tab draws none.

Every popup the pointer opens (a hover card, the emoji tally's card, a hint) waits for the pointer to rest on what it is about, and closes a moment after the pointer leaves both it and the popup, through one timer, Look.intent in look.js. The two waits are --hover-open (0 to 800 ms, 300 by default) and --hover-close (0 to 400 ms, 150 by default), beside --motion. Escape, or a press outside a popup, closes it at once. The keyboard, a click and a tap open one at once.

A module writes only its own top-level bindings; another that needs one changed calls the setter beside it (setFeed, setLiving, shiftClock, wantGroup), since an ES module's imports are read-only. The canvas tests run the modules as the one script they were cut from (graph() in dev/test/canvas.test.mjs), so each case gets a fresh graph.

The key's pictures #

The key (index.html's #key dialog) shows crops of the real board with pen notes on them, in key/. They are drawn, not kept by hand: after anything on the board changes how it looks, draw them again with

node web/dev/key.mjs

which serves web/ itself, opens dev/key.html (the board with a small population of its own and nothing live) in one headless Chrome, sets each picture up with dev/key-scene.js, and writes key/*.webp. Name pictures to draw only those: node web/dev/key.mjs ring post.

The Bluesky profile's pictures #

dev/brand/ draws the icon and header for the site's Bluesky account from the same CSS, fonts and SVGs, with a preview of each as Bluesky shows it:

node web/dev/brand/brand.mjs

Its README says what each picture is and how the board in one is filmed. dev/key.mjs and dev/brand/brand.mjs share dev/headless.mjs: web/ served on a port of its own and one headless Chrome driven over DevTools.