Skip to content

Feature/Docker Sandbox#4

Open
gabi-simons wants to merge 51 commits into
mainfrom
feature/sandbox-setup-script
Open

Feature/Docker Sandbox#4
gabi-simons wants to merge 51 commits into
mainfrom
feature/sandbox-setup-script

Conversation

@gabi-simons

Copy link
Copy Markdown
Owner

Docker Sandbox /setup

gabi-simons and others added 30 commits March 9, 2026 08:44
One-command script to create a Docker AI Sandbox with NanoClaw ready
to go. Users can curl the script, then enter the sandbox and run
claude + /setup for channel configuration.

Includes sandbox-patch.sh for proxy/DinD compatibility patches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Dockerfile for gabinanoclaw/nanoclaw-sandbox:latest (amd64 + arm64)
- nanoclaw-init.sh: auto-setup on first login (clone, install, patch, build)
- Simplified setup-sandbox.sh: just creates sandbox from template
- Users curl the script, enter sandbox, auto-setup runs, then claude + /setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Telegram/WhatsApp HttpsProxyAgent code patches with Docker
Sandbox plugin system (docker-plugin/network.json bypassDomains).
Keeps NanoClaw codebase clean — networking handled at sandbox layer.

- Add docker-plugin/ with manifest.json and network.json
- Remove patches nanocoai#7 and nanocoai#8 from sandbox-patch.sh
- Update setup-sandbox.sh to pass --plugin flag
- Include plugin files in Docker image

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clone repo on host before creating sandbox, mount as workspace.
Simplified Dockerfile to system deps only (no auto-init scripts).
New init.sh replaces nanoclaw-init.sh — runs npm install, patches,
build, and Claude Code install from the already-mounted repo.
Added setup/sandbox.ts for skill-driven sandbox management.
Updated README with init step instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch from custom shell+template to built-in claude agent type
- No custom Docker image needed — Claude Code comes pre-installed
- Use docker sandbox network proxy --bypass-host instead of --plugin
- Add IS_SANDBOX detection in environment.ts
- Update /setup skill: sandbox-aware auth, runtime, and service steps
- Clone from feature branch for testing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
/setup now detects sandbox environment and runs sandbox/init.sh
automatically. User flow: curl|bash → docker sandbox run → /setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .gitattributes to force LF for *.sh (fixes Windows CRLF in sandbox)
- Configure npm proxy in init.sh for sandbox MITM proxy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .gitattributes to force LF for *.sh on Windows clones
- Replace sed -i with virtiofs-safe sedi() in sandbox-patch.sh
- Fix CRLF with tr instead of sed -i in init.sh
- Configure npm proxy in init.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
/setup now explains how to configure the Anthropic API key in
Docker Desktop settings and verifies the proxy injects it correctly
with a test API call before proceeding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Explains how to get an Anthropic API key from console.anthropic.com,
how to configure it in Docker Desktop, and how to verify the proxy
injects it. Also clarifies OAuth token option for Claude Pro/Max users.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both sandbox and normal setup now explain how to get an API key
from console.anthropic.com and offer Claude subscription as option.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep auth flow simple — no curl test. If key is wrong, errors
will show when NanoClaw runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same .env approach for sandbox and non-sandbox. Two options:
Claude subscription (OAuth) or Anthropic API key. No proxy-managed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ainers

Core sandbox support for Docker AI Sandbox (DinD microVM):

- src/config.ts: IS_SANDBOX detection (checks ~/.nanoclaw-workspace or proxy URL)
- src/container-runner.ts: sandboxRunContainerAgent() — full DinD execution strategy:
  docker run -d --entrypoint sleep (tmpfs mounts) → tar pipe copy-in →
  docker exec /app/entrypoint.sh → tar pipe copy-out → docker rm -f
  Includes NO_PROXY for credential proxy, NANOCLAW_SINGLE_TURN env var,
  proxy env forwarding, 5-sec kill timer after first output
- src/credential-proxy.ts: dynamic HttpsProxyAgent for sandbox MITM proxy
- src/index.ts: skip session resume in sandbox (tmpfs doesn't persist)
- container/agent-runner: process.exit(0) on NANOCLAW_SINGLE_TURN=1
  (Claude SDK keeps event loop alive, break alone doesn't work)
- sandbox-patch.sh: cleaned up — only env-specific patches (Dockerfile proxy,
  build.sh proxy, CA cert, .env.empty, Telegram grammy proxy)
- tsconfig.json: exclude test files from build

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
One setup skill handles everything. /setup Step 0 detects the sandbox
environment and runs init.sh automatically. No separate skill needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- init.sh: commit sandbox patches after applying (step 5/5) so channel
  fork merges don't require stash/pop and cause conflicts
- verify.ts: treat SERVICE=not_found as OK in sandbox mode (no
  background service, NanoClaw runs in foreground)
- sandbox-patch.sh: fix telegram proxy patch — use undici ProxyAgent
  with dispatcher (correct for Node 20+ fetch/grammy) instead of
  HttpsProxyAgent with agent (doesn't work with fetch())
- SKILL.md: re-run sandbox-patch.sh after channel merges, update
  timeout guidance to 5-30min, fix verify step for sandbox

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add </dev/null redirects to all docker and git commands that read stdin,
preventing them from consuming the piped script content when run via
curl | bash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pipe 'y' to docker sandbox create so it auto-confirms the workspace
creation prompt instead of silently failing with </dev/null.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Desktop on Windows can't mount WSL filesystem paths (/home/...).
Detect WSL and use /mnt/c/Users/<user>/nanoclaw-workspace instead, which
Docker Desktop can access via the Windows filesystem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add </dev/null to cmd.exe call so it doesn't read piped stdin
when the setup script is run via curl|bash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Desktop treats WSL paths (/mnt/c/...) literally, resulting in
wrong mount paths. Use wslpath -w to convert to Windows-native path
for the docker command while keeping the WSL path for git/file ops.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of skipping when nanoclaw-workspace exists, fetch and pull
the correct branch to ensure the sandbox runs up-to-date code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use git reset --hard before pulling to clear merge conflicts or
dirty state. Falls back to rm + re-clone if pull still fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gabi-simons and others added 21 commits March 11, 2026 03:47
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Redirect stdin from /dev/tty so the interactive sandbox session
can attach properly when the script is piped via curl|bash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
docker sandbox run needs a proper interactive TTY which isn't
available in a curl|bash pipeline. Print the command for the
user to run directly in their terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use cmd.exe /c start to open a new console window for the
interactive sandbox session, avoiding the frozen TTY issue
in curl|bash pipelines. Non-WSL uses exec with /dev/tty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of a 279-line sandbox-patch.sh that patches files at runtime,
apply the 3 essential proxy changes directly in source code:
- container/Dockerfile: proxy ARGs + strict-ssl for npm
- container/build.sh: forward proxy build args
- setup/container.ts: proxy build args for setup builds

This eliminates:
- sandbox/sandbox-patch.sh (279 lines)
- sandbox/Dockerfile (unused)
- sandbox/docker-plugin/ (handled by setup-sandbox.sh)
- Patch step in init.sh (now 3 steps instead of 5)
- Re-patching after channel merges in setup skill

Also adds API key prompt to setup-sandbox.sh (avoids UTF-16 .env
issue from Windows) and auto-starts npm at end of /setup.

Net: +39 lines, -345 lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove setup/sandbox.ts (436 lines) — all sandbox lifecycle logic is
now handled by setup-sandbox.sh. Remove its dead entry from setup/index.ts.
Add missing https-proxy-agent install to sandbox/init.sh needed by
credential-proxy.ts for MITM proxy routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-script

# Conflicts:
#	.claude/skills/setup/SKILL.md
Add src/proxy-bootstrap.ts that sets https.globalAgent (for node-fetch/
Grammy/Baileys) and undici global dispatcher (for built-in fetch) at
startup. This means any channel merged in via skill branches works
through the sandbox MITM proxy automatically — no per-channel proxy
code needed.

Remove 20 lines of per-request proxy agent from credential-proxy.ts.
Install undici alongside https-proxy-agent in sandbox init.sh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Setup skill now writes .env directly via printf instead of telling
  the user to echo (Windows echo produces UTF-16 which breaks grep)
- Add merge=theirs strategy for repo-tokens/badge.svg to avoid
  conflicts when merging channel skill branches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
init.sh already installs dependencies, build tools, and native modules.
Running setup.sh again causes virtiofs I/O errors on stale node_modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Grammy needs baseFetchConfig: { agent: https.globalAgent } in its Bot
constructor — this goes in the telegram skill branch, not in core.
proxy-bootstrap.ts just sets https.globalAgent which is picked up by
well-behaved libraries and by Grammy when configured to use it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After npm install https-proxy-agent undici, commit the package.json
changes so the working tree is clean when channel skill branches are
merged later during /setup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove npm run build and container/build.sh from init.sh — these are
duplicated by setup steps 3c and 5. init.sh now only does what /setup
can't: proxy config, CRLF fixes, npm install with proxy packages, and
committing sandbox deps. Saves ~8 minutes on sandbox init.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The entrypoint was running npx tsc on every container start, adding
~5-10s to every message. Now TypeScript is compiled once during
docker build and the entrypoint just runs node directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- init.sh: install deps in /tmp (ext4), tar-pipe node_modules back,
  create shell wrappers for .bin/ (virtiofs doesn't support symlinks)
- init.sh: gate strict-ssl=false on proxy presence, remove apt-get
- config.ts: hardcode IS_SANDBOX=true (sandbox-only fork)
- container-runner.ts: always use sandbox runner (remove IS_SANDBOX check)
- Delete setup-sandbox.sh (hosted script is source of truth)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- container-runtime: skip own sandbox container in orphan cleanup
- container-runner: forward proxy/CA env vars into agent containers,
  use empty file instead of /dev/null for .env shadow mount
- credential-proxy: route upstream HTTPS through proxy agent
- Add https-proxy-agent dependency

Cherry-picked from gavrielc/nanoclaw-1@c4ffa2a and bb85088.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- init.sh: copy esbuild binary to .bin/ (JS runtime check needs it)
- container-runtime: skip own sandbox container in orphan cleanup
- container-runner: forward proxy/CA env vars, empty-env shadow mount
- credential-proxy: route upstream HTTPS through proxy agent
- setup skill: use --no-bin-links for post-merge npm install

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
git add -A instead of just package files, so .env.example, badge.svg,
and other modified files don't block channel skill merges on virtiofs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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