Skip to content

Add claude-code-sandbox example - #20

Draft
opencolin wants to merge 3 commits into
mainfrom
examples/claude-code-sandbox
Draft

Add claude-code-sandbox example#20
opencolin wants to merge 3 commits into
mainfrom
examples/claude-code-sandbox

Conversation

@opencolin

@opencolin opencolin commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Claude Code running headless against a real Git checkout inside a disposable Tenki microVM. The last line of run.mjs prints git diff — the agent changed a real upstream repo in a machine that gets deleted a second later.

Shape: createAndWait({ cloneRepoUrl })npm i -g @anthropic-ai/claude-codeclaude -p "<task>" --dangerously-skip-permissions with the model key passed through ExecOptions.env and the turn streamed via onOutputgit -C repo diff.

The task given to the agent is concrete (add a toArray() method to yocto-queue, declare it in index.d.ts, add a test), so the diff spans three real files rather than demonstrating nothing.

Verification

Ran node verify.mjs locally against the live API:

✓ claude-code-sandbox: create + clone → npm i -g claude-code → 2.1.209 (Claude Code) → edit → git diff → dispose

Exit code 0. Per CONTRIBUTING, it proves the Tenki-facing half with no model key (the langchain-code-interpreter pattern), asserting real values rather than truthiness:

  • the sandbox boots with the repo cloned, and repo/package.json really is yocto-queue
  • npm i -g @anthropic-ai/claude-code exits 0
  • claude --version matches \d+\.\d+\.\d+ (Claude Code)
  • claude --help still lists -p, --print and --dangerously-skip-permissions — npm installs whatever is latest at run time, so the flags run.mjs depends on are checked rather than assumed
  • a diff round-trips on a file the script writes itself

Not exercised: the agent turn in run.mjs needs an ANTHROPIC_API_KEY, which this environment does not have, so the claude -p call itself was not run end to end. Everything around it was measured live inside a sandbox — CLI install (~5s), claude --version → 2.1.209, cwd: "repo" resolution, ExecOptions.env passthrough, and claude -p "hi" --dangerously-skip-permissions reaching Not logged in as user tenki, which confirms the flag parses and there is no root refusal.

Table placement

Added one row to Developer tools, next to the MCP server row. Claude Code is a CLI you point at a repo, not a framework you build an agent with — it belongs beside AgentBox and the MCP server rather than in Agent frameworks, which is for SDKs given a sandboxed execution tool.

Two gotchas worth a reviewer's eye

sandbox.git.diff() does not work here. sandbox.git.* executes at the sandbox workdir (/home/tenki), but cloneRepoUrl checks out one level down into /home/tenki/repo, so it fails with not a git repository. Confirmed live for both cloneRepoUrl and sandbox.git.clone(); git.diff({ path: "repo" }) fails the same way, and git.clone(url, { directory: "." }) fails because the workdir already has dotfiles. The example reads the diff with sandbox.exec("git", { args: ["-C", "repo", "diff"] }) and documents why in Notes.

Top-level await using needs Node 24+, not Node 20. Node 22.22.2 fails to parse it; 24.19.0 accepts it. run.mjs says so; verify.mjs uses try/finally, so CI on Node 20 is unaffected. Note this also applies to the already-shipped run.mjs files and the root README's "Node.js 20 or later" — out of scope for this PR, but worth a follow-up.

Touches only examples/claude-code-sandbox/ and the one README row.

claude added 2 commits August 17, 2026 03:58
Runs Claude Code headless against a real Git checkout inside a disposable
Tenki microVM, then reads back the diff the agent produced.

verify.mjs proves the Tenki-facing half with no model key: boot with
cloneRepoUrl, npm i -g the CLI, assert its version, edit a file in the
checkout, assert the diff round-trips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uz85xGA4zWSge1BtiDNnSN
Measured: Node 22.22.2 fails to parse `await using`, Node 24.19.0 accepts it.
verify.mjs uses try/finally, so CI on Node 20 is unaffected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uz85xGA4zWSge1BtiDNnSN
verify.mjs now checks `claude --help` still lists `-p, --print` and
`--dangerously-skip-permissions`, since npm installs whatever version is
latest at run time.

An ExecOptions.env value of undefined arrives in the guest as an empty
string rather than unset, which is why run.mjs filters the passthrough
list; measured, and now stated where it matters.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uz85xGA4zWSge1BtiDNnSN
This was referenced Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants