Releases: javimosch/roam
Release list
v0.6.0 — cli-specs conformance (update, feedback, shutdown)
New in v0.6.0
cli-update-spec conformance
roam update [--check] [--force]— downloads latest release, verifies SHA256, smoke-tests, atomically swaps (current → .bak)roam install [--path <dir>]— relocates binary to ~/.local/bin (idempotent)roam uninstall [--path <dir>]— removes the installed binary
cli-feedback-spec conformance
roam feedback "<message>" [--kind bug|idea|praise] [--context "..."]— dual-writes to feedback relay, never fails the caller
cli-daemon-spec conformance (panel + hub)
POST /_shutdownwithX-Shutdown-Tokenheader — token-gated shutdown on roam-panel and roam-hub
Already conformant (unchanged)
- cli-output-spec: JSON stdout, typed errors, semantic exit codes (80-119), help-json
- cli-guide-spec: embedded guide (JSON + --human), no external docs needed
- cli-telemetry-spec: opt-in, DO_NOT_TRACK, inspectable payload
Download
curl -fsSL https://github.com/javimosch/roam/releases/latest/download/roam-x86_64-linux -o roam
chmod +x roam
./roam versionroam v0.5.0
roam v0.5.0
Agent-first CLI contract hardening:
- embedded
roam guide/guide --human - machine-readable
roam help-json - typed semantic controller errors on stderr
- strict stdout/stderr separation for help and remote one-shot commands
- local lifecycle smoke coverage and safer worker cleanup
v0.4.0 — actual billed cost from OpenRouter
v0.4.0 — actual billed cost, not just tokens
roam status only ever reported token counts, forcing every caller to
estimate EUR/USD cost from a static rate table. OpenRouter actually returns
the real per-request cost when asked (usage.include:true), so roam now
asks for it whenever --api-base names OpenRouter, accumulates it across
iterations, and reports it as cost_usd in status.
Anthropic and OpenAI direct have no equivalent field — cost_usd stays 0
there, and callers should keep using their own token-rate estimate for those
providers. This makes that gap explicit instead of silently wrong.
Verified live: a 668-token deepseek-v4-flash-latest run reported
5.85732e-05 USD, matching the model's published per-token price.
roam v0.3.0 — roam version
Adds a version command, and fixes what its absence was hiding.
$ roam version
{"ok":true,"tool":"roam","version":"0.3.0","providers":["anthropic","openai","debri"]}--version and -v work too. A binary you scp onto a machine you may not own has to be able to say what it is — without this the only way to check a deployed roam was to run strings on it.
Which is how this slipped: roam_version() still returned 0.2.0 after v0.2.1 shipped, so every telemetry ping under-reported the binary and nothing noticed. make release now refuses to build when the Makefile's VERSION and the constant in telemetry.src disagree, verified in both directions.
curl -fsSL https://github.com/javimosch/roam/releases/latest/download/roam-x86_64-linux -o roam
chmod +x roam && ./roam versionroam v0.2.1 — a binary tool result no longer kills the run
One fix, but a fatal one for any agent that touches a filesystem.
`jstr` escaped five characters and passed every other byte through raw. A JSON string cannot carry a raw control byte, and the request body must be valid UTF-8 — so a single tool result containing either produced a malformed request and the API answered 400 JSON parsing failed. The job died with an error that named nothing about the cause.
One cat on a binary was enough. It surfaced on a live disk-audit run whose agent ran cat on a symlink to /usr/bin/du.
Two changes:
jstrescapes control bytes as\u00XXand replaces any byte sequence that is not well-formed UTF-8 withU+FFFD. It can no longer emit anything JSON cannot carry — including a multi-byte character sliced in half by truncation.run_shellandread_filedetect non-text output and return a note naming the size and suggestingfile,strings | head,xxd | headorwc -c, instead of the bytes. Escaping alone would be legal JSON but would spend the whole token budget describing an ELF header one\u00XXat a time.
Reproduced deterministically before, green after: cat /usr/bin/du, head -c 200 /usr/bin/ls, and a command emitting raw \377\376 — plus a plain task as a regression check. With the note in place the agent read it and reached for xxd | head on its own.
curl -fsSL https://github.com/javimosch/roam/releases/latest/download/roam-x86_64-linux -o roam
chmod +x roam && ./roam helpThis release also rolls a changelog that had drifted: everything previously under [Unreleased] had already shipped in v0.2.0, whose own headline (opt-in telemetry) was documented only in its release notes.
roam v0.2.0 — opt-in telemetry (off by default)
roam reports nothing unless you run roam telemetry --telemetry-on. A fresh install makes zero outbound connections beyond the work you asked for — verified with strace.
That is stricter than the rest of my tools on purpose: you scp roam onto a VM and leave it running unattended, often on a machine you do not own. A binary someone copied to a third-party server that quietly contacts the network is exactly what destroys trust in an agent runtime.
If you enable it: version, os/arch, which verb ran, whether it failed. Never prompts, keys, command output, hostnames or paths. roam telemetry prints the exact payload.
cli-telemetry-spec §2.4.
roam v0.1.0 — leave a working agent on a remote box
First release. Dispatch a self-replicating autonomous agent to a VM, walk away, and attach back to steer it — one static binary, no Python on the target.
Install
curl -fsSL https://github.com/javimosch/roam/releases/latest/download/roam-x86_64-linux -o roam
chmod +x roam && ./roam helproam-x86_64-linux is fully static (bundled SQLite + static OpenSSL + CA store) — runs FROM scratch on any x86-64 Linux, no deps. Verify with roam-x86_64-linux.sha256.
Highlights
- Remote dispatch + self-replication over ssh; control (
status/attach/steer/stop) against the remote journal. - Real LLM tool-loop (read/write/shell/finish), written in machin — no SDK. Providers: Anthropic and OpenAI-compatible (OpenRouter, …).
- Trust layer: hard token/iteration budgets, workdir sandbox, gated shell, full journal.
- Confirm-gate — destructive commands park for async approval (
approve/deny/stop), with a deny budget. Live-proven (caught asudo rmescalation). - Goal-verify — an independent judge checks completion against real evidence; fail-open.
Docs + changelog: https://javimosch.github.io/roam/ · Full notes: CHANGELOG.md