reuniverse-runner
v0.1.5
Published
Local runner for Reuniverse — runs the venture build agent on YOUR machine under YOUR Claude subscription via the Claude Agent SDK, so venture content stays between you and Anthropic. Loopback-only, pairing-phrase auth, one-way-door supervision gate.
Maintainers
Readme
Reuniverse runner (Method B)
Runs the venture build agent on your own machine, under your own Claude subscription, and streams progress to the Reuniverse web app over loopback. Venture content (your code, specs, build output) never touches a Reuniverse server — only your machine and Anthropic.
Why local? Anthropic's terms forbid a third-party site from running agentic work server-side on your consumer Pro/Max subscription. The sanctioned shape is: you run the agent on your machine with your
claude /login; the website only pairs with it and visualizes the result. Seedocs/DECISIONS.md→ "ToS red line" / "Method B".
Run it
cd apps/runner
npm install # pulls @anthropic-ai/claude-agent-sdk (bundles the Claude Code binary)
claude /login # one time — log in with your Claude Pro/Max account (NOT an API key)
npm start # or: npx reuniverse-runner / node index.mjsOn start it prints a pairing code. In the web app → Supervision → Local runner, enter that code once; the browser receives a bearer token (the runner stores only its hash) and reconnects automatically after that. Re-pair by deleting ~/.reuniverse/runner.json.
To use an API key instead of the subscription (BYOK / Method A), keep ANTHROPIC_API_KEY set and pass byok: true on the run — the runner will not strip it.
How it runs (one build)
- Web app
POST /runs { repoPath, prompt }→{ runId }.repoPathis your venture repo; it's the agent's working directory and the write jail. - Web app opens the SSE stream
GET /runs/:id/stream(bearer-auth) and renders events live. - The runner calls the Agent SDK
query()withpermissionMode: 'default'+ acanUseToolhandler:- Reversible / local tool calls (Read, Glob, Grep, Write/Edit inside the repo,
git add/commit, builds, tests) → auto-allowed instantly, no prompt. - One-way doors (
git push,npm publish,vercel deploy,rm -rf, force-push, outbound webhooks, purchases) → the runner emits agateevent and waits; the build pauses until you approve in the web app (POST /runs/:id/gate/:gateId { allow }). - Writes outside
repoPathare denied.
- Reversible / local tool calls (Read, Glob, Grep, Write/Edit inside the repo,
- Budget: every run is capped by
maxBudgetUsd(default 14) andmaxTurns(default 40). The finalresultevent carriescostUsd+numTurns.
Endpoints
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /healthz | none | { ok, version, paired, sdk, loggedIn } (discovery + status) |
| POST | /pair | code | exchange the pairing code for a bearer token |
| POST | /runs | bearer | start a build → { runId } |
| GET | /runs/:id/stream | bearer | SSE stream of run events |
| POST | /runs/:id/gate/:gateId | bearer | approve/reject a one-way-door action |
| POST | /runs/:id/abort | bearer | cancel a run |
Security model (CORS is not auth)
- Binds to 127.0.0.1 only.
- Host header validated (DNS-rebinding defense).
- Origin allowlisted (web app origins; extend via
REUNIVERSE_ORIGINS). - A one-time pairing code → bearer token (only the token hash is stored on disk).
- The runner never reads or copies your Claude credentials — the SDK resolves your
claude /loginitself. - It identifies itself to Anthropic as
reuniverse-runner/<version>(never spoofs Claude Code).
Event shapes (SSE data:)
started · thought · tool · gate · gate_resolved · result · error. See agent.mjs for the exact fields and apps/web/src/lib/runner-client.ts for the typed client.
