You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Assert run.mjs's CLI flags and document the empty-env gotcha
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
onOutput: ({ data }) =>process.stdout.write(decoder.decode(data)), // data is a Uint8Array
36
38
});
@@ -47,20 +49,22 @@ The last line is the point: a unified diff against a real upstream checkout, pro
47
49
npm install
48
50
export TENKI_AUTH_TOKEN=... # from `tenki login` (~/.config/tenki/config.yaml)
49
51
export TENKI_WORKSPACE_ID=...
50
-
export ANTHROPIC_API_KEY=... #the agent turn; ANTHROPIC_MODEL is optional
52
+
export ANTHROPIC_API_KEY=... #ANTHROPIC_BASE_URL and ANTHROPIC_MODEL pass through too, if set
51
53
node run.mjs # streams the agent's turn, then prints the diff
52
54
```
53
55
56
+
`run.mjs` uses top-level `await using`, which needs Node 24+.
57
+
54
58
Verify the Tenki half without a model key — this is what CI runs:
55
59
56
60
```bash
57
-
node verify.mjs # create + clone → install the CLI → read its version → edit → git diff
61
+
node verify.mjs # create + clone → install the CLI → check its version and flags → edit → git diff
58
62
```
59
63
60
64
## Notes
61
65
62
66
-**`sandbox.git.*` runs at the sandbox workdir (`/home/tenki`), but `cloneRepoUrl` checks out one level down into `./repo`** — so `sandbox.git.diff()` fails with "not a git repository". Read the checkout with `sandbox.exec("git", { args: ["-C", "repo", "diff"] })`, or clone at the workdir root if you want the helpers.
63
67
- The default image already ships Node 24, npm 11, and git 2.43, and outbound network is on for a bare `create`. `npm i -g @anthropic-ai/claude-code` finishes in about five seconds — no `allowOutbound`, no custom image, no baked-in CLI.
64
68
-`--dangerously-skip-permissions` refuses to run as root; the sandbox user is `tenki`, so it works as written. It is the right flag *here* precisely because the blast radius is one microVM.
65
-
-`exec(command, { args })` runs a bare binary and its args with no shell splitting, so the whole task prompt goes through as a single argument. `ExecOptions.env` is scoped to that one process — the model key never lands in the repo or the image.
69
+
-`exec(command, { args })` runs a bare binary and its args with no shell splitting, so the whole task prompt goes through as a single argument. `ExecOptions.env` is scoped to that one process — the model key never lands in the repo or the image. A key whose value is `undefined` arrives as an *empty string* rather than unset, which is why `run.mjs` filters before building the env.
66
70
- Secrets in, diffs out: nothing else from your shell crosses into the VM, and `await using` terminates it when the scope ends (`Session` is an `AsyncDisposable`). Top-level `await using` needs **Node 24+** — Node 22 fails to parse it. `verify.mjs` uses `try`/`finally` instead, so CI runs fine on Node 20.
0 commit comments