Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 22 additions & 42 deletions nanoclaw/README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,39 @@
# nanoclaw

A standalone agent kit (`kind: agent`) for
[nanoclaw](https://github.com/qwibitai/nanoclaw) — a lightweight
AI assistant runtime driven by Claude Code. The kit clones and
builds the upstream repo at sandbox creation time and runs Claude
Code from inside the checkout as the entrypoint, so the project's
`CLAUDE.md` and `.claude/skills/` are loaded on attach.

> [!NOTE]
> Upstream nanoclaw trunk only ships the **CLI channel**. Chat-platform
> adapters (WhatsApp, Telegram, Discord, Slack, …) live on the
> upstream `channels` branch and are installed via `/add-<channel>`
> skills run from inside Claude Code. This kit installs trunk and
> lets you drive the rest from the shipped `claude` CLI.
[nanoclaw](https://github.com/nanocoai/nanoclaw) — a lightweight
AI assistant runtime. The kit clones and builds the upstream repo at
sandbox creation time and boots directly into the nanoclaw service.

## Usage

```console
$ sbx run --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=nanoclaw" nanoclaw
```

Or with a local clone of this repo:
The first `sbx create` clones the upstream repo to `/home/agent/nanoclaw`,
runs `npm install`, rebuilds native modules, and compiles TypeScript (~2
minutes). Subsequent attaches are immediate.

```console
$ sbx run --kit ./nanoclaw/ nanoclaw
```
On attach you land in the nanoclaw interface. Chat platform adapters
(WhatsApp, Telegram, Discord, Slack, …) are installed via `/add-<channel>`
skills from inside the session.

The first `sbx create` clones the upstream repo to
`/home/agent/nanoclaw`, runs `npm install`, rebuilds native modules,
and runs the TypeScript build (~2 minutes). Subsequent attaches
are immediate.
## How auth works

`sbx run` drops you into a Claude Code session whose working
directory is the nanoclaw checkout, with its `CLAUDE.md` already
loaded — exactly as upstream's
[install guide](https://nanoclaws.io/install) recommends. From
there, `/setup`, `/add-whatsapp`, `/customize`, etc. work as
documented.
The kit uses the standard Anthropic auth wiring: `serviceDomains`/`serviceAuth`
for `api.anthropic.com`, the OAuth flow against `platform.claude.com`, and the
`proxy-managed` sentinel pattern. Credentials never enter the container — the
sandbox proxy substitutes the real value on egress.

If you'd rather launch the daemon directly than enter Claude Code,
exec a shell into the sandbox from another terminal and run:
Set `ANTHROPIC_API_KEY` in your environment to skip OAuth and use an API key
directly.

```console
$ nanoclaw
```
## Debugging the install

## How auth works

The kit declares the same Anthropic auth wiring as the built-in
`claude` agent kit: `serviceDomains`/`serviceAuth` for
`api.anthropic.com`, the OAuth flow against `platform.claude.com`,
and the `proxy-managed` sentinel pattern. Credentials never enter
the container — the sandbox proxy substitutes the real value on
egress.
If the sandbox starts before the build completes, it waits. To follow the
build log:

The kit's `allowedDomains` adds `registry.npmjs.org` (for the
install), the WhatsApp hosts the bridge connects to (when the
WhatsApp adapter is later added), and `nanoclaw.dev`.
```console
$ sbx exec <sandbox> -- tail -f /home/agent/nanoclaw-install.log
```
44 changes: 34 additions & 10 deletions nanoclaw/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ schemaVersion: "1"
kind: agent
name: nanoclaw
displayName: NanoClaw
description: "Lightweight AI assistant runtime driven by Claude Code; ships the CLI channel — chat platforms (WhatsApp, Telegram, Discord, …) add via upstream skills"
description: "Lightweight AI assistant runtime; ships the CLI channel — chat platforms (WhatsApp, Telegram, Discord, …) add via upstream skills"

agent:
image: "docker/sandbox-templates:claude-code-docker"
persistence: persistent
aiFilename: CLAUDE.md
entrypoint:
run: ["/usr/local/bin/nanoclaw-start"]
Expand All @@ -29,6 +30,19 @@ network:
- nanoclaw.dev
- "github.com:443"
- "objects.githubusercontent.com:443"
- "nodejs.org:443"
- "onecli.sh:443"
- "www.onecli.sh:443"
- "raw.githubusercontent.com:443"
- "release-assets.githubusercontent.com:443"
- "ghcr.io:443"
- "registry-1.docker.io:443"
- "auth.docker.io:443"
- "production.cloudflare.docker.com:443"
- "checkpoint.prisma.io:443"
- "api.onecli.sh:443"
- "deb.debian.org:443"
- "security.debian.org:443"

credentials:
sources:
Expand All @@ -39,25 +53,35 @@ credentials:
environment:
variables:
IS_SANDBOX: "1"

settings:
containerSettings:
claude: true
NODE_NO_WARNINGS: "1"
ONECLI_BIND_HOST: "0.0.0.0"
ONECLI_URL: "http://127.0.0.1:10254"
NO_PROXY: "localhost,127.0.0.1,::1,0.0.0.0,gateway.docker.internal"
no_proxy: "localhost,127.0.0.1,::1,0.0.0.0,gateway.docker.internal"

commands:
install:
- command: "npm config set proxy $HTTP_PROXY && npm config set https-proxy $HTTP_PROXY"
user: "1000"
description: Configure npm to use the sandbox proxy
- command: "printf '#!/bin/sh\\nif ! [ -f /home/agent/nanoclaw/.installed ] || ! [ -f /home/agent/.claude/settings.json ]; then\\n echo \"Waiting for nanoclaw installation to complete...\" >&2\\n until [ -f /home/agent/nanoclaw/.installed ] && [ -f /home/agent/.claude/settings.json ]; do sleep 2; done\\nfi\\nexec claude --dangerously-skip-permissions\\n' > /usr/local/bin/nanoclaw-start && chmod +x /usr/local/bin/nanoclaw-start"
- command: "npm install -g n && n 22"
user: "0"
description: Upgrade Node.js to v22 (required by pnpm v10 and nanoclaw)
- command: "echo 'export PATH=\"/home/agent/.local/bin:$PATH\"' >> /etc/sandbox-persistent.sh"
user: "0"
description: Persist ~/.local/bin in PATH for all shell contexts (required for OneCLI post-install check)
- command: "npm install -g pnpm"
user: "0"
description: Install pnpm globally (required by nanoclaw setup wizard)
- command: "printf '#!/bin/sh\\nsudo -n chmod 666 /var/run/docker.sock 2>/dev/null || true\\nif ! [ -f /home/agent/nanoclaw/.installed ]; then\\n echo \"Waiting for nanoclaw installation to complete (first boot builds host + agent image, 5-12 min)...\" >&2\\n tail -f /home/agent/nanoclaw-install.log >&2 &\\n TAIL_PID=$!\\n until [ -f /home/agent/nanoclaw/.installed ]; do sleep 2; done\\n kill $TAIL_PID 2>/dev/null\\nfi\\ncd /home/agent/nanoclaw\\nmkdir -p logs\\nnode dist/index.js > logs/nanoclaw.log 2> logs/nanoclaw.error.log &\\necho \"Starting NanoClaw service...\" >&2\\ni=0\\nuntil [ -S data/cli.sock ]; do\\n sleep 1\\n i=$((i+1))\\n if [ $i -ge 60 ]; then\\n echo \"Timed out after 60s waiting for data/cli.sock. Service logs follow:\" >&2\\n echo \"--- nanoclaw.error.log ---\" >&2\\n cat logs/nanoclaw.error.log >&2 2>/dev/null\\n echo \"--- nanoclaw.log ---\" >&2\\n cat logs/nanoclaw.log >&2 2>/dev/null\\n exit 1\\n fi\\ndone\\nexport PATH=\"$HOME/.local/bin:$PATH\"\\nexec env NANOCLAW_SKIP=service,container npm run --silent setup:auto\\n' > /usr/local/bin/nanoclaw-start && chmod +x /usr/local/bin/nanoclaw-start"
user: "0"
description: Create agent entrypoint early; waits for nanoclaw install and claude settings before starting
- command: "printf '#!/bin/sh\\ngit clone --depth 1 https://github.com/qwibitai/nanoclaw.git /home/agent/nanoclaw && cd /home/agent/nanoclaw && npm install --maxsockets=1 --fetch-timeout=600000 && npm rebuild better-sqlite3 && npm run build && touch /home/agent/nanoclaw/.installed\\n' > /home/agent/nanoclaw-install.sh && chmod +x /home/agent/nanoclaw-install.sh && setsid /home/agent/nanoclaw-install.sh > /home/agent/nanoclaw-install.log 2>&1 &"
description: Create agent entrypoint; chmods docker socket (sbx restarts daemon each boot, resetting perms), tails install log while waiting, starts nanoclaw service in background (logs to logs/nanoclaw.log + logs/nanoclaw.error.log), waits up to 60s for CLI socket (dumps service logs on timeout), then runs nanoclaw setup wizard (skipping service registration and container build — both handled elsewhere)
- command: "printf '#!/bin/sh\\nset -e\\ngit clone --depth 1 https://github.com/nanocoai/nanoclaw.git /home/agent/nanoclaw && cd /home/agent/nanoclaw && pnpm install --network-concurrency=1 && pnpm rebuild better-sqlite3 && pnpm run build && sudo -n chmod 666 /var/run/docker.sock && ./container/build.sh && touch /home/agent/nanoclaw/.installed\\n' > /home/agent/nanoclaw-install.sh && chmod +x /home/agent/nanoclaw-install.sh && setsid /home/agent/nanoclaw-install.sh > /home/agent/nanoclaw-install.log 2>&1 &"
user: "1000"
description: Clone and build nanoclaw in detached background session (~2 minutes; .installed flag written on completion)
description: Clone and build nanoclaw (host + agent container image) in detached background session (~5-12 minutes; .installed flag written on completion, set -e ensures partial installs don't unblock entrypoint)
- command: "cat > /usr/local/bin/nanoclaw << 'SCRIPT'\n#!/bin/sh\ncd /home/agent/nanoclaw\nexec node dist/index.js \"$@\"\nSCRIPT\nchmod +x /usr/local/bin/nanoclaw"
user: "0"
description: Create nanoclaw launcher (root-owned path)
description: Create nanoclaw launcher for manual invocation

oauth:
service: anthropic
Expand Down
Loading