Skip to content
Merged
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
56 changes: 26 additions & 30 deletions .claude/skills/debug/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ This guide covers debugging the containerized agent execution system.
## Architecture Overview

```
Host (macOS) Container (Linux VM)
Host (macOS/Linux) Container (Docker)
─────────────────────────────────────────────────────────────
src/container-runner.ts container/agent-runner/
│ │
│ spawns Apple Container │ runs Claude Agent SDK
│ spawns Docker container │ runs Claude Agent SDK
│ with volume mounts │ with MCP servers
│ │
├── data/env/env ──────────────> /workspace/env-dir/env
Expand Down Expand Up @@ -80,34 +80,30 @@ cat .env # Should show one of:

### 2. Environment Variables Not Passing

**Apple Container Bug:** Environment variables passed via `-e` are lost when using `-i` (interactive/piped stdin).

**Workaround:** The system extracts only authentication variables (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`) from `.env` and mounts them for sourcing inside the container. Other env vars are not exposed.
The system extracts only authentication variables (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`) from `.env` and mounts them for sourcing inside the container. Other env vars are not exposed.

To verify env vars are reaching the container:
```bash
echo '{}' | container run -i \
--mount type=bind,source=$(pwd)/data/env,target=/workspace/env-dir,readonly \
echo '{}' | docker run -i \
-v $(pwd)/data/env:/workspace/env-dir:ro \
--entrypoint /bin/bash nanoclaw-agent:latest \
-c 'export $(cat /workspace/env-dir/env | xargs); echo "OAuth: ${#CLAUDE_CODE_OAUTH_TOKEN} chars, API: ${#ANTHROPIC_API_KEY} chars"'
```

### 3. Mount Issues

**Apple Container quirks:**
- Only mounts directories, not individual files
- `-v` syntax does NOT support `:ro` suffix - use `--mount` for readonly:
```bash
# Readonly: use --mount
--mount "type=bind,source=/path,target=/container/path,readonly"
Docker volume mount syntax:
```bash
# Readonly
-v /path:/container/path:ro

# Read-write: use -v
-v /path:/container/path
```
# Read-write
-v /path:/container/path
```

To check what's mounted inside a container:
```bash
container run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c 'ls -la /workspace/'
docker run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c 'ls -la /workspace/'
```

Expected structure:
Expand All @@ -129,7 +125,7 @@ Expected structure:

The container runs as user `node` (uid 1000). Check ownership:
```bash
container run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c '
docker run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c '
whoami
ls -la /workspace/
ls -la /app/
Expand All @@ -152,7 +148,7 @@ grep -A3 "Claude sessions" src/container-runner.ts

**Verify sessions are accessible:**
```bash
container run --rm --entrypoint /bin/bash \
docker run --rm --entrypoint /bin/bash \
-v ~/.claude:/home/node/.claude \
nanoclaw-agent:latest -c '
echo "HOME=$HOME"
Expand Down Expand Up @@ -183,17 +179,17 @@ cp .env data/env/env

# Run test query
echo '{"prompt":"What is 2+2?","groupFolder":"test","chatJid":"test@g.us","isMain":false}' | \
container run -i \
--mount "type=bind,source=$(pwd)/data/env,target=/workspace/env-dir,readonly" \
docker run -i \
-v $(pwd)/data/env:/workspace/env-dir:ro \
-v $(pwd)/groups/test:/workspace/group \
-v $(pwd)/data/ipc:/workspace/ipc \
nanoclaw-agent:latest
```

### Test Claude Code directly:
```bash
container run --rm --entrypoint /bin/bash \
--mount "type=bind,source=$(pwd)/data/env,target=/workspace/env-dir,readonly" \
docker run --rm --entrypoint /bin/bash \
-v $(pwd)/data/env:/workspace/env-dir:ro \
nanoclaw-agent:latest -c '
export $(cat /workspace/env-dir/env | xargs)
claude -p "Say hello" --dangerously-skip-permissions --allowedTools ""
Expand All @@ -202,7 +198,7 @@ container run --rm --entrypoint /bin/bash \

### Interactive shell in container:
```bash
container run --rm -it --entrypoint /bin/bash nanoclaw-agent:latest
docker run --rm -it --entrypoint /bin/bash nanoclaw-agent:latest
```

## SDK Options Reference
Expand Down Expand Up @@ -235,18 +231,18 @@ npm run build
./container/build.sh

# Or force full rebuild
container builder prune -af
docker builder prune -af
./container/build.sh
```

## Checking Container Image

```bash
# List images
container images
docker images

# Check what's in the image
container run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c '
docker run --rm --entrypoint /bin/bash nanoclaw-agent:latest -c '
echo "=== Node version ==="
node --version

Expand Down Expand Up @@ -326,11 +322,11 @@ echo -e "\n1. Authentication configured?"
echo -e "\n2. Env file copied for container?"
[ -f data/env/env ] && echo "OK" || echo "MISSING - will be created on first run"

echo -e "\n3. Apple Container system running?"
container system status &>/dev/null && echo "OK" || echo "NOT RUNNING - NanoClaw should auto-start it; check logs"
echo -e "\n3. Docker running?"
docker info &>/dev/null && echo "OK" || echo "NOT RUNNING - start Docker Desktop (macOS) or sudo systemctl start docker (Linux)"

echo -e "\n4. Container image exists?"
echo '{}' | container run -i --entrypoint /bin/echo nanoclaw-agent:latest "OK" 2>/dev/null || echo "MISSING - run ./container/build.sh"
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "OK" 2>/dev/null || echo "MISSING - run ./container/build.sh"

echo -e "\n5. Session mount path correct?"
grep -q "/home/node/.claude" src/container-runner.ts 2>/dev/null && echo "OK" || echo "WRONG - should mount to /home/node/.claude/, not /root/.claude/"
Expand Down
Loading