Releases: lntvan166/paddock
Release list
v0.8.1
What's Changed
- fix: a page you visit should not be able to type into your agents by @lntvan166 in #8
Full Changelog: v0.8.0...v0.8.1
v0.8.0
What's Changed
- feat: the terminal answers what the operator came to ask by @lntvan166 in #7
Full Changelog: v0.7.0...v0.8.0
v0.7.0
What's Changed
- feat: paddock tunnel — a quick tunnel gated by a pairing code by @lntvan166 in #5
- fix: herdr protocol drift is directional, and fields are the real contract by @lntvan166 in #6
Full Changelog: v0.6.1...v0.7.0
v0.6.1
v0.6.0
v0.5.0
What's Changed
- paddock start / stop / status by @lntvan166 in #2
- Explain a taken port and a missing herdr, instead of throwing by @lntvan166 in #3
- paddock --help printed nothing and started a dashboard by @lntvan166 in #4
Full Changelog: v0.4.0...v0.5.0
v0.4.0
What's Changed
- Install with one command, upgrade with another by @lntvan166 in #1
New Contributors
- @lntvan166 made their first contribution in #1
Full Changelog: v0.3.0...v0.4.0
v0.3.0 — settings, and a phone that tells you
paddock could show you a blocked agent, but only while you were looking at it. This release closes that: your phone now tells you.
Telegram notifications
A message when an agent becomes blocked or done, carrying its name, its state, and a link straight to that agent.
Telegram rather than Web Push, decided deliberately. Web Push needs a service worker, a VAPID keypair, a permission prompt and — on iOS — a Home Screen install before a single notification can arrive. Telegram needs a bot token and one HTTPS POST, works on any device already running it, and is unaffected by an expired Cloudflare Access session.
The cost is recorded rather than glossed: bot messages are not end-to-end encrypted. So the message carries a name, a state and a link, and never terminal output or the agent's task line — the task line is live agent-authored text that can carry pasted secrets. That last point was a real defect caught in final review, after surviving every per-task review because the implementation plan itself contradicted the design.
Notification policy is deliberate about the failures that make an alert channel worth ignoring:
- keyed on the transition, not the state, so an agent that stays blocked does not repeat
- first sight after boot is silent, or restarting paddock would ping once per already-blocked agent
- quiet hours drop rather than queue — a pile delivered at 08:00 describes agents unblocked five hours earlier
- a failed send does not consume the transition, so the next update retries; the per-agent cooldown is what bounds that, and it is floored at 1s so it cannot be disarmed
Settings, at #/settings
Reachable from a ⚙ button in the header, and split into two clearly-labelled scopes, because conflating them misleads:
| This device | Theme, refresh rate (Live / Balanced / Frugal), terminal font size, line wrap |
| All devices | Telegram token and chat, notifications on/off, triggers, quiet hours, cooldown, public URL |
Sending happens on the server, so a switch tapped on your phone also silences your laptop. The view says so in words rather than leaving you to find out.
The bot token is write-only. paddock has no authentication of its own — Cloudflare Access is the only gate — so anything an endpoint returns is readable by whatever passes that gate. The token goes in and never comes back: the API reports only configured and a four-character hint, and it is stored at ~/.config/paddock/settings.json, written atomically at mode 0600 with an fsync before the rename.
Also
- The header now shows the mark and paddock instead of
local, the default host id. A real host id still shows, dimmed. - Terminal font size defaults to Automatic, restoring the responsive clamp a fixed default had been silently overriding — worth roughly 14 columns on a 390px phone.
- Theme changes apply immediately instead of on the next page load.
Notes
Behind an authenticating tunnel this needs no extra configuration — see docs/deploy-cloudflare.md, which also now records the ordering that matters: create the Access application before publishing the hostname.
418 tests. One known gap is recorded in docs/roadmap.md: no test guards the composition root's fan-out call site, so an edit bypassing it would pass the suite while silently disabling notifications.
v0.2.0 — a terminal you can read and answer from a phone
v0.1.0 could show an agent's screen. This one can be read on a phone, answered safely, and watched without burning data.
Every number below was measured against a live herdr on a 390×844 viewport, not estimated.
Reading
Prose reflows; structure doesn't. Of the lines too wide for a phone, 57% are structural (tables, boxes, progress bars) and 43% are prose. Neither "wrap everything" nor "wrap nothing" is right, so each run of structure gets its own horizontal scroll strip while prose reflows around it. Plain separators are clipped rather than handed a scrollbar. Wrap / Exact is the operator's choice and persists per device.
Scrollback, reconstructed. Up to 4000 lines per agent, revealed by Show earlier. It is rebuilt from live reads by detecting what scrolled off the top — because herdr refuses every scrollback source while an agent is blocked, which is precisely when you want to re-read an analysis before answering. Nothing renders until you ask, so the pane costs what it always did (38 DOM nodes before, 75 after).
Answering
You can see what Enter will commit. The keypad cursor wraps from the last option back to the first, and the middle option of a permission prompt is routinely "and don't ask again" — a standing grant. The wrap was never the hazard; the wrap being invisible was.
Real option buttons carry the agent's own labels verbatim — no reordering, no generic "Approve" — so committing one cannot be off by one.
The reply box works in every state. It previously returned 409 in three states out of four, because it pointed at a route that only answers prompts.
Watching
| v0.1.0 | v0.2.0 | |
|---|---|---|
| refresh floor | 1000 ms | 250 ms, backing off to 10 s |
| bytes per update | full screen (~2 KB gzipped) | only changed lines (~322 B) |
| projected data | ~30 MB/hour | ~4.5 MB/hour |
A thinking agent redraws one line of 63 — the spinner and its token counter — so sending the whole screen was ~90% waste. The spinner still updates every 250 ms; only the bytes carrying it shrank.
An open tab now knows when it's stale. no-cache on index.html fixes a fresh load and does nothing for a tab left open for days. A newer build now surfaces a reload prompt within one heartbeat.
Known limits, all measured
- herdr exposes no output-changed event and no byte stream, so output is pulled and cannot stream the way a chat UI streams tokens.
- History covers only what a tab watched. An agent nobody watched has none, and closing that gap would mean recording every agent continuously — a recorder, not a viewer.
- Reconstruction records a gap rather than guessing when the screen scrolls more than half a viewport between polls.
- No DOM test environment. Component effects and wiring are unverified, and several defects reached the browser this cycle for exactly that reason. It's the next thing worth fixing.
Full changelog: v0.1.0...v0.2.0
v0.1.0 — mobile terminal view
The first version that could show an agent's terminal on a phone. Tagged as a rollback point before the transport and rendering work that became v0.2.0.
What worked here: a full-screen terminal per agent at its own URL, ANSI colour, a nav keypad usable in every agent state, adaptive refresh with digest revalidation, and index.html served no-cache so a deploy could actually reach a phone.
Known limits recorded at the time, all measured rather than assumed: herdr exposes no output-changed event and no byte stream, so output is pulled; scrollback exists but cost 11–14s and was unreachable from the UI; and the option cursor wrapped from last to first with nothing on screen to show it.
Published after the fact, so the releases page reflects the actual history.