Beckon
beckoncli.com · live since October 2026
A remote inbox for terminal agents and long-running jobs. Beckon lets you see when a process needs attention and respond from a paired device.
- Role: product discovery, specification, design and engineering.
- Product: a Go CLI that wraps terminal programs, plus a live web inbox and installable phone app with notifications.
- Status: live in production at beckoncli.com since October 2026. No external user results yet.
Finding the problem
I reviewed the Hacker News front page and its discussion threads for needs that appeared independently. Four stories pointed to the same gap: developers run agents and long jobs on machines they are not always watching, then miss the moment those processes need a decision.
That became the product hypothesis: one inbox across machines, with a phone notification when a job is blocked. I wrote the product spec before building, including the main user flows, a security model, acceptance criteria and explicit non-goals. The first version focuses on status and safe responses; it does not stream a remote terminal or allow arbitrary typing.
Making remote responses safe
A one-tap approval is useful only if the server cannot turn it into an arbitrary command. I designed the response flow so the phone selects an option, while the host keeps the actual keystrokes and decides whether the response is still valid.
- Message contents are encrypted from the host to paired devices; the service routes ciphertext.
- Pairing compares a six-word safety code derived from both devices' public keys. The host stores its own trusted-device list locally.
- The phone signs and encrypts an option choice. The helper verifies the signature, trust, record revision and offered option before writing anything to the terminal.
- Stale prompts, replayed responses and read-only sessions are rejected. Response outcomes are audited in the app.
This changed the initial design: devices never send keystrokes, and the service never receives them. It narrows what a compromised service can do.
Building the whole path
The Go helper runs a command in a pseudo-terminal, passes terminal input and output through, and reads OSC 7501 status reports. For tools without status support, configurable prompt detection can identify known permission prompts. The service uses Next.js, WebSockets and Postgres to keep sessions live; the web app handles pairing, decryption and Web Push.
I built the product as connected milestones: terminal reporting, live inbox, encryption and pairing, push notifications, signed responses, prompt detection, then plans, billing and deployment work. Tests cover terminal pass-through, crypto interoperability, server tampering, response handling and end-to-end flows.
Running it in production
Staging first ran on Cloud Run with a database that scales to zero. It worked, but it showed why that is the wrong shape for this product. A running helper holds a connection open for as long as its command runs, so with real users the service is rarely idle and costs about the same as an always-on machine. Cloud Run also cuts every connection after an hour, and the first helper after a quiet spell waits for a cold start. An agent blocked at 3 a.m. should not wait for a server to wake up before it can notify anyone.
So production runs on one small VM: the app, Postgres and a web server in containers, for a few euros a month. I wrote down each step before taking it, then checked it on the live server.
- Deploys ship a release over SSH, migrate, restart and wait for the health check. A rollback is the previous release and takes about 20 seconds.
- Hardening: key-only SSH that is closed between sessions, only ports 80 and 443 open, containers with no privileges and read-only file systems, and an app database user that can read and write rows and nothing else.
- Backups run nightly, encrypted before they leave the server, to storage the server's own key cannot delete. I rehearsed a restore before launch.
- Monitoring: an outside uptime check on the health endpoint, plus a five-minute check of disk, memory and containers on the server. That check is a dead man's switch: if it stops reporting, I get an alert.
Payments still run in Stripe's test mode, and the repository is about to go public.
What remains to learn
Beckon is live, but no developers outside my own machines use it yet, so there are no adoption or reliability results to claim. The next step is to put it in front of developers who run agents across machines, watch where setup and trust break down, and decide from that evidence whether the problem is frequent enough to pay for.