boxd-fix — or drop a /boxd-fix (or /boxd-preview --fix) comment — and you get back Claude’s fix: a new PR with a live preview URL for issues, or a commit pushed straight to the existing PR for PRs. Each run gets its own fork, destroyed on PR close.
How it works
Fix builds on the preview platform: it reuses the same on-golden listener, fork, branch-sync, and teardown, and adds the Claude + PR step on top. No GitHub Actions, no runner queue, noBOXD_API_KEY repo secret.
| Trigger | Fires on | Result |
|---|---|---|
/boxd-fix or /boxd-preview --fix comment | issue_comment | Fork golden → Claude → new PR (issue) or push to PR branch (PR) |
boxd-fix label on an issue | issues.labeled | Fork golden → Claude → new PR off the default branch |
boxd-fix label on a PR | pull_request.labeled | Fork golden → Claude → push to the PR branch |
| PR closed | pull_request.closed | Destroy the matching fork (shared with preview) |
boxd destroy.
The whole thing is wired up by a single Claude Code slash command.
Set it up
Fix is the agent layer, so set up the chain first:/boxd-setup-golden → /boxd-setup-preview → /boxd-setup-fix. With those done, wire fix on top — two ways:
- From your laptop
- Inside the golden (in-VM)
Install the boxd CLI on your laptop (this also drops the skill):Then run the skill in the repo:
Claude Code only for now — reach out for Codex, OpenCode, or any other agent.
/boxd-setup-fix stages the fix handler, registers the three fix webhooks (reusing the preview platform’s HMAC secret), creates the boxd-fix label, and sets up a headless-browser MCP for screenshot verification. It needs no Claude token — every boxd VM ships logged into Claude, and a fork is a full copy of the golden, so Claude runs in the fork already authenticated.
What you’ll be asked for, once:
| Step | What | How |
|---|---|---|
| 1 | Confirm the plan | One short message listing the golden, the fix webhooks, and what’s already present vs. missing |
boxd-fix and the loop runs.
Optional — run fixes under a different Claude identity. By default the fork uses the golden’s own inherited Claude login. To use a different account (e.g. a dedicated service identity, or a headless golden with no login), run
claude setup-token in your terminal and paste the printed token into the one-liner the skill prints — it lands at /etc/boxd-fix/claude.token and takes precedence over the inherited login. The value never appears in chat.Patterns
What the bot actually does
The agent reads the issue/PR body, the linked files, and the project’sAGENTS.md / CLAUDE.md. The app is already running on the forked golden (forks inherit the running state), so for UI changes it takes a “before” screenshot at https://<fork>.boxd.sh, makes its changes, verifies them via chrome-devtools-mcp (navigate_page → wait_for → evaluate_script), takes an “after” screenshot, commits, and exits.
The handler on the golden then pushes the result:
- Issue trigger: force-push to a fresh
boxd-fix/issue-<N>branch and open a new PR with the preview URL pinned to the top. - PR comment / PR label trigger: push commits directly onto the PR’s existing head branch — Claude appears as a co-author on the PR.
Customizing the prompt
The skill ships a default prompt at/opt/boxd-platform/claude-prompt.md on the golden. To override it per-repo, commit .github/claude-prompts/fix-issue.md to your repo — the handler picks it up automatically on each trigger after a git fetch. Bias the prompt toward your conventions: which tests to run, which files to avoid, which style guide to follow.
Triggering from a PR comment
/boxd-fix on a PR comment runs Claude against that PR’s branch (not main), then pushes commits straight onto the PR. Useful for “hey Claude, the heading should be smaller” review feedback.
Triggering by label on a PR
Labeling a PRboxd-fix works the same as a /boxd-fix comment — fork → Claude → push to the PR branch.
The PR is opened (or commits are pushed) by your user account using a
gh token persisted on the golden during /boxd-setup-golden. No “Allow Actions to create PRs” org toggle needed.Trust caveat
A fork is a full copy of the golden, so it inherits the golden’s Claude login (and itsgh auth) — the same login every boxd VM ships with. If your app on the fork is reachable by untrusted parties, treat those credentials as exposed on it; the cleanup hook destroys forks promptly on PR close, which is the main mitigation. (An optional override token at /etc/boxd-fix/claude.token, if you set one, is inherited the same way.) The trade-off vs. the prior GHA-based design: no BOXD_API_KEY round-trip, no GHA queue, no runner minutes — Claude auth lives on your own VM instead of GitHub Secrets.
FAQ
What happens when the agent gets stuck?
What happens when the agent gets stuck?
The fork stays alive until you close the PR. SSH in with
boxd ssh <fork-name>, tail /var/log/golden-preview/<fork-name>.log for the full Claude transcript, then run claude --resume <session_id> to take over interactively.How much does each run cost in compute?
How much does each run cost in compute?
A fork is ~160ms, then you pay for the time the VM is up. Auto-suspend kicks in after 30s of idle, so a typical fix run is a few minutes of active VM time. End-to-end (label → PR opened) we’ve measured ~2 minutes for a small change.
What do I need set up first?
What do I need set up first?
A golden (
/boxd-setup-golden) with the preview platform on it (/boxd-setup-preview). Fix layers on that — it reuses the preview platform’s fork/sync/teardown and adds only the Claude run. A preview-only golden stays free of the Claude token until you run /boxd-setup-fix.What if the trigger fires but nothing happens?
What if the trigger fires but nothing happens?
Tail the global handler log:
boxd exec <golden> -- 'tail -f /var/log/golden-preview.log'. The HMAC check is the most common failure — webhook(8) returns 200 with body Hook rules were not satisfied on HMAC mismatch (it intentionally doesn’t 401, so attackers can’t probe for the URL). Re-run /boxd-setup-fix to rotate the secret.What if I want a different agent?
What if I want a different agent?
Today the slash command targets Claude Code. For Codex, Cursor, or OpenCode wiring, email
contact@boxd.sh and we’ll prioritize.Next
Agent sandboxes
The primitive underneath the loop. Hand an agent a full VM.
Fork from a golden
Where the warm copy comes from. ~160ms per fork.