Skip to content

Commit 1d37274

Browse files
chocoSpriteclaude
andcommitted
docs: rewrite README and prune upstream/WhatsApp/Docker debris from debug+security
README.md: - rewrite from scratch: remove OpenClaw comparison + upstream author first-person voice, "gh repo fork qwibitai" Quick Start, dead docs.nanoclaw.dev links, Docker/Linux/Windows support claims (runtime is hardcoded to Apple `container` CLI), "Agent Swarms" framing, and the upstream PR/contribution section - describe current reality: Slack pat/mat dual bots + Gmail, Claude+Codex dual SDK, Apple Container + OneCLI, whisper-cpp local transcription, per-group isolated memory - Key Files table reflects src/ as it is now (slack-mat.ts, container-runtime.ts, transcribe.ts) docs/DEBUG_CHECKLIST.md: - drop Issue nanocoai#4 (Kubernetes/Rancher Desktop image GC) — Docker-only problem, runtime is hardcoded to Apple container - docker ps/run → container list/run - delete Channel Auth Issues section (QR code, store/auth/, npm run auth — all WhatsApp-era dead weight) docs/SECURITY.md: - drop `store/auth/` NOT-Mounted bullet (WhatsApp session dir, unused in this fork) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dd597db commit 1d37274

3 files changed

Lines changed: 68 additions & 183 deletions

File tree

README.md

Lines changed: 63 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,110 @@
1-
<p align="center">
2-
<img src="assets/nanoclaw-logo.png" alt="NanoClaw" width="400">
3-
</p>
1+
# NanoClaw
42

5-
<p align="center">
6-
An AI assistant that runs agents securely in their own containers. Lightweight, built to be easily understood and completely customized for your needs.
7-
</p>
3+
A Claude-powered personal assistant that routes Slack and Gmail messages to agents running in isolated Apple Container sandboxes.
84

9-
---
5+
## What It Does
106

11-
## Why I Built NanoClaw
12-
13-
[OpenClaw](https://github.com/openclaw/openclaw) is an impressive project, but I wouldn't have been able to sleep if I had given complex software I didn't understand full access to my life. OpenClaw has nearly half a million lines of code, 53 config files, and 70+ dependencies. Its security is at the application level (allowlists, pairing codes) rather than true OS-level isolation. Everything runs in one Node process with shared memory.
14-
15-
NanoClaw provides that same core functionality, but in a codebase small enough to understand: one process and a handful of files. Claude agents run in their own Linux containers with filesystem isolation, not merely behind permission checks.
16-
17-
## Quick Start
18-
19-
```bash
20-
gh repo fork qwibitai/nanoclaw --clone
21-
cd nanoclaw
22-
claude
23-
```
24-
25-
<details>
26-
<summary>Without GitHub CLI</summary>
27-
28-
1. Fork [qwibitai/nanoclaw](https://github.com/qwibitai/nanoclaw) on GitHub (click the Fork button)
29-
2. `git clone https://github.com/<your-username>/nanoclaw.git`
30-
3. `cd nanoclaw`
31-
4. `claude`
32-
33-
</details>
34-
35-
Then run `/setup`. Claude Code handles everything: dependencies, authentication, container setup and service configuration.
36-
37-
> **Note:** Commands prefixed with `/` (like `/setup`, `/add-slack`) are [Claude Code skills](https://code.claude.com/docs/en/skills). Type them inside the `claude` CLI prompt, not in your regular terminal. If you don't have Claude Code installed, get it at [claude.com/product/claude-code](https://claude.com/product/claude-code).
7+
Messages arrive on a connected channel (Slack, Gmail). The orchestrator polls a SQLite queue, spawns an agent container with the group's memory and allowed mounts, streams the conversation into Claude Agent SDK (or Codex SDK), and sends the response back through the owning channel. Each group has isolated memory, sessions, and filesystem.
388

399
## Philosophy
4010

41-
**Small enough to understand.** One process, a few source files and no microservices. If you want to understand the full NanoClaw codebase, just ask Claude Code to walk you through it.
42-
43-
**Secure by isolation.** Agents run in Linux containers (Apple Container on macOS, or Docker) and they can only see what's explicitly mounted. Bash access is safe because commands run inside the container, not on your host.
44-
45-
**Built for the individual user.** NanoClaw isn't a monolithic framework; it's software that fits each user's exact needs. Instead of becoming bloatware, NanoClaw is designed to be bespoke. You make your own fork and have Claude Code modify it to match your needs.
46-
47-
**Customization = code changes.** No configuration sprawl. Want different behavior? Modify the code. The codebase is small enough that it's safe to make changes.
48-
49-
**AI-native.**
50-
- No installation wizard; Claude Code guides setup.
51-
- No monitoring dashboard; ask Claude what's happening.
52-
- No debugging tools; describe the problem and Claude fixes it.
53-
54-
**Skills over features.** Instead of adding features to the codebase, [claude code skills](https://code.claude.com/docs/en/skills) like `/add-slack` transform your fork. You end up with clean code that does exactly what you need.
55-
56-
**Best harness, best model.** NanoClaw runs on the Claude Agent SDK, which means you're running Claude Code directly. Claude Code is highly capable and its coding and problem-solving capabilities allow it to modify and expand NanoClaw and tailor it to each user.
11+
- **Small enough to understand.** One Node.js process, a handful of source files under `src/`. Read the file you're curious about — that's the authoritative spec.
12+
- **Secure by isolation.** Agents run inside Apple Container VMs with only explicitly mounted directories visible. Bash is safe because it runs inside the container, not on the host.
13+
- **Credentials never reach the container.** [OneCLI's Agent Vault](https://github.com/onecli/onecli) intercepts outbound HTTPS and injects credentials at the gateway — agents can't read real tokens from env, files, or `/proc`.
14+
- **Customization = code changes.** No configuration sprawl. Want different behavior? Edit the code. The codebase is small enough to make changes safely.
15+
- **Skills over features.** Operational workflows (`/setup`, `/debug`, `/customize`) are [Claude Code skills](https://code.claude.com/docs/en/skills) that guide tasks rather than being hardcoded.
5716

5817
## What It Supports
5918

60-
- **Multi-channel messaging** - Talk to your assistant from Slack or Gmail. Add channels with skills like `/add-slack` or `/add-gmail`.
61-
- **Isolated group context** - Each group has its own `CLAUDE.md` memory, isolated filesystem, and runs in its own container sandbox with only that filesystem mounted to it.
62-
- **Main channel** - Your private channel (self-chat) for admin control; every group is completely isolated
63-
- **Scheduled tasks** - Recurring jobs that run Claude and can message you back
64-
- **Web access** - Search and fetch content from the Web
65-
- **Container isolation** - Agents are sandboxed in Apple Container (macOS) or Docker (macOS/Linux)
66-
- **Credential security** - Agents never hold raw API keys. Outbound requests route through [OneCLI's Agent Vault](https://github.com/onecli/onecli), which injects credentials at request time and enforces per-agent policies and rate limits.
67-
- **Agent Swarms** - Spin up teams of specialized agents that collaborate on complex tasks
68-
- **Optional integrations** - Add Gmail (`/add-gmail`) and more via skills
19+
- **Slack channels** — Dual-bot setup (`@패트` / `@매트`) via Socket Mode. Add with `/add-slack`.
20+
- **Gmail** — As a tool (read/send/search/draft) or a full channel (emails can trigger the agent). Add with `/add-gmail`.
21+
- **Dual SDK** — Claude Agent SDK and Codex SDK side by side, selectable per bot identity.
22+
- **Isolated group context** — Each group has its own `CLAUDE.md` memory, sessions, and filesystem, mounted into a fresh container per invocation.
23+
- **Main channel admin** — Your private channel (self-chat) registers/removes groups and schedules cross-group tasks.
24+
- **Scheduled tasks** — Cron, interval, and one-time jobs that run a full Claude/Codex agent in the group's context.
25+
- **Web access**`WebSearch` and `WebFetch` tools inside the container.
26+
- **Local audio transcription** — Slack voice messages are transcribed locally via `whisper-cpp` before reaching the agent.
27+
- **Ollama MCP** — Optional local-model MCP server via `/add-ollama-tool`.
28+
- **Context compaction**`/compact` forwards the SDK's built-in compaction for long sessions.
6929

7030
## Usage
7131

72-
Talk to your assistant with the trigger word (default: `@패트`):
32+
Talk to the assistant with the trigger word (default `@패트` or `@매트`):
7333

7434
```
75-
@패트 send an overview of the sales pipeline every weekday morning at 9am (has access to my Obsidian vault folder)
76-
@패트 review the git history for the past week each Friday and update the README if there's drift
77-
@패트 every Monday at 8am, compile news on AI developments from Hacker News and TechCrunch and message me a briefing
35+
@패트 send me an overview of today's work calendar every weekday morning at 9am
36+
@패트 review the git history for the past week each Friday and summarize drift
37+
@매트 매일 오전 8시에 HN AI 뉴스 큐레이션해줘
7838
```
7939

80-
From the main channel (your self-chat), you can manage groups and tasks:
40+
From the main channel you can manage groups and tasks:
41+
8142
```
8243
@패트 list all scheduled tasks across groups
8344
@패트 pause the Monday briefing task
84-
@패트 join the Family Chat group
45+
@패트 add group "Family Chat"
8546
```
8647

8748
## Customizing
8849

89-
NanoClaw doesn't use configuration files. To make changes, just tell Claude Code what you want:
50+
NanoClaw has almost no configuration files. Tell Claude Code what you want and it modifies the source:
9051

91-
- "Change the trigger word to @Bob"
92-
- "Remember in the future to make responses shorter and more direct"
93-
- "Add a custom greeting when I say good morning"
94-
- "Store conversation summaries weekly"
52+
- "Change the trigger word to `@Bob`"
53+
- "Keep responses under three sentences"
54+
- "Add a greeting when I say good morning"
9555

9656
Or run `/customize` for guided changes.
9757

98-
The codebase is small enough that Claude can safely modify it.
99-
10058
## Requirements
10159

102-
- macOS, Linux, or Windows (via WSL2)
60+
- macOS with [Apple Container](https://github.com/apple/container) (the runtime is hardcoded to the `container` CLI)
10361
- Node.js 20+
10462
- [Claude Code](https://claude.ai/download)
105-
- [Apple Container](https://github.com/apple/container) (macOS) or [Docker](https://docker.com/products/docker-desktop) (macOS/Linux)
63+
- [OneCLI](https://github.com/onecli/onecli) for credential vaulting
64+
- `whisper-cpp` + `ggml-large-v3-turbo.bin` (for Slack audio transcription)
65+
- Slack Socket Mode app with bot + app-level tokens
66+
- GCP OAuth credentials for Gmail
10667

107-
## Architecture
108-
109-
```
110-
Channels --> SQLite --> Polling loop --> Container (Claude Agent SDK) --> Response
111-
```
112-
113-
Single Node.js process. Channels are added via skills and self-register at startup — the orchestrator connects whichever ones have credentials present. Agents execute in isolated Linux containers with filesystem isolation. Only mounted directories are accessible. Per-group message queue with concurrency control. IPC via filesystem.
114-
115-
For the full architecture details, see the [documentation site](https://docs.nanoclaw.dev/concepts/architecture).
116-
117-
Key files:
118-
- `src/index.ts` - Orchestrator: state, message loop, agent invocation
119-
- `src/channels/registry.ts` - Channel registry (self-registration at startup)
120-
- `src/ipc.ts` - IPC watcher and task processing
121-
- `src/router.ts` - Message formatting and outbound routing
122-
- `src/group-queue.ts` - Per-group queue with global concurrency limit
123-
- `src/container-runner.ts` - Spawns streaming agent containers
124-
- `src/task-scheduler.ts` - Runs scheduled tasks
125-
- `src/db.ts` - SQLite operations (messages, groups, sessions, state)
126-
- `groups/*/CLAUDE.md` - Per-group memory
127-
128-
## FAQ
129-
130-
**Why Docker?**
131-
132-
Docker provides cross-platform support (macOS, Linux and even Windows via WSL2) and a mature ecosystem. This fork uses Apple Container on macOS as the default runtime.
133-
134-
**Can I run this on Linux or Windows?**
135-
136-
Yes. Docker is the default runtime and works on macOS, Linux, and Windows (via WSL2). Just run `/setup`.
137-
138-
**Is this secure?**
139-
140-
Agents run in containers, not behind application-level permission checks. They can only access explicitly mounted directories. Credentials never enter the container — outbound API requests route through [OneCLI's Agent Vault](https://github.com/onecli/onecli), which injects authentication at the proxy level and supports rate limits and access policies. You should still review what you're running, but the codebase is small enough that you actually can. See the [security documentation](https://docs.nanoclaw.dev/concepts/security) for the full security model.
141-
142-
**Why no configuration files?**
143-
144-
We don't want configuration sprawl. Every user should customize NanoClaw so that the code does exactly what they want, rather than configuring a generic system. If you prefer having config files, you can tell Claude to add them.
145-
146-
**Can I use third-party or open-source models?**
147-
148-
Yes. NanoClaw supports any Claude API-compatible model endpoint. Set these environment variables in your `.env` file:
68+
## Getting Started
14969

15070
```bash
151-
ANTHROPIC_BASE_URL=https://your-api-endpoint.com
152-
ANTHROPIC_AUTH_TOKEN=your-token-here
71+
cd nanoclaw
72+
claude
15373
```
15474

155-
This allows you to use:
156-
- Local models via [Ollama](https://ollama.ai) with an API proxy
157-
- Open-source models hosted on [Together AI](https://together.ai), [Fireworks](https://fireworks.ai), etc.
158-
- Custom model deployments with Anthropic-compatible APIs
159-
160-
Note: The model must support the Anthropic API format for best compatibility.
75+
Inside the Claude Code prompt, run `/setup`. It walks through Node.js, Apple Container, OneCLI, channel skills (`/add-slack`, `/add-gmail`), launchd service install, and verification.
16176

162-
**How do I debug issues?**
77+
## Architecture
16378

164-
Ask Claude Code. "Why isn't the scheduler running?" "What's in the recent logs?" "Why did this message not get a response?" That's the AI-native approach that underlies NanoClaw.
79+
```
80+
Channels → SQLite → Polling loop → Apple Container (Claude/Codex SDK) → Response
81+
```
16582

166-
**Why isn't the setup working for me?**
83+
Single Node.js process. Channels self-register at startup — the orchestrator connects whichever have credentials. Agents execute in fresh Apple Container VMs with filesystem isolation. Only mounted directories are accessible. Per-group message queue with global concurrency control. IPC via filesystem.
16784

168-
If you have issues, during setup, Claude will try to dynamically fix them. If that doesn't work, run `claude`, then run `/debug`. If Claude finds an issue that is likely affecting other users, open a PR to modify the setup SKILL.md.
85+
### Key Files
16986

170-
**What changes will be accepted into the codebase?**
87+
| File | Purpose |
88+
|------|---------|
89+
| `src/index.ts` | Orchestrator: state, message loop, agent invocation |
90+
| `src/channels/registry.ts` | Channel self-registration registry |
91+
| `src/channels/slack.ts`, `slack-mat.ts` | Slack pat/mat bots |
92+
| `src/router.ts` | Resolves owning channel for a JID |
93+
| `src/ipc.ts` | IPC watcher and task processing |
94+
| `src/group-queue.ts` | Per-group queue with global concurrency |
95+
| `src/container-runner.ts` | Spawns agents in Apple Container |
96+
| `src/container-runtime.ts` | Container runtime bindings |
97+
| `src/task-scheduler.ts` | Runs scheduled tasks |
98+
| `src/transcribe.ts` | whisper-cpp audio transcription |
99+
| `src/db.ts` | SQLite operations |
100+
| `groups/{folder}/CLAUDE.md` | Per-group memory (isolated) |
101+
| `container/skills/` | Skills loaded inside agent containers |
171102

172-
Only security fixes, bug fixes, and clear improvements will be accepted to the base configuration. That's all.
103+
See [docs/SPEC.md](docs/SPEC.md) for full architecture details, [docs/SECURITY.md](docs/SECURITY.md) for the security model, [docs/SDK_DEEP_DIVE.md](docs/SDK_DEEP_DIVE.md) for Agent SDK internals, and [docs/APPLE-CONTAINER-NETWORKING.md](docs/APPLE-CONTAINER-NETWORKING.md) for macOS 26 vmnet setup.
173104

174-
Everything else (new capabilities, OS compatibility, hardware support, enhancements) should be contributed as skills.
105+
## Debugging
175106

176-
This keeps the base system minimal and lets every user customize their installation without inheriting features they don't want.
107+
Ask Claude Code directly: "Why isn't the scheduler running?" "What's in the recent logs?" That's the AI-native approach. Or run `/debug` for a guided checklist, or skim [docs/DEBUG_CHECKLIST.md](docs/DEBUG_CHECKLIST.md).
177108

178109
## License
179110

docs/DEBUG_CHECKLIST.md

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,6 @@ Both timers fire at the same time, so containers always exit via hard SIGKILL (c
1111
### 3. Cursor advanced before agent succeeds
1212
`processGroupMessages` advances `lastAgentTimestamp` before the agent runs. If the container times out, retries find no messages (cursor already past them). Messages are permanently lost on timeout.
1313

14-
### 4. Kubernetes image garbage collection deletes nanoclaw-agent image
15-
16-
**Symptoms**: `Container exited with code 125: pull access denied for nanoclaw-agent` — the container image disappears overnight or after a few hours, even though you just built it.
17-
18-
**Cause**: If your container runtime has Kubernetes enabled (Rancher Desktop enables it by default), the kubelet runs image garbage collection when disk usage exceeds 85%. NanoClaw containers are ephemeral (run and exit), so `nanoclaw-agent:latest` is never protected by a running container. The kubelet sees it as unused and deletes it — often overnight when no messages are being processed. Other images (docker-compose services) survive because they have long-running containers referencing them.
19-
20-
**Fix**: Disable Kubernetes if you don't need it:
21-
```bash
22-
# Rancher Desktop
23-
rdctl set --kubernetes-enabled=false
24-
25-
# Then rebuild the container image
26-
./container/build.sh
27-
```
28-
29-
**Diagnosis**: Check the k3s log for image GC activity:
30-
```bash
31-
grep -i "nanoclaw" ~/Library/Logs/rancher-desktop/k3s.log
32-
# Look for: "Removing image to free bytes" with the nanoclaw-agent image ID
33-
```
34-
35-
Check NanoClaw logs for image status:
36-
```bash
37-
grep -E "image found|image NOT found|image missing" logs/nanoclaw.log
38-
```
39-
40-
If you need Kubernetes enabled, set `CONTAINER_IMAGE` to an image stored in a registry that the kubelet won't GC, or raise the GC thresholds.
41-
4214
## Quick Status Check
4315

4416
```bash
@@ -47,18 +19,15 @@ launchctl list | grep nanoclaw
4719
# Expected: PID 0 com.nanoclaw (PID = running, "-" = not running, non-zero exit = crashed)
4820

4921
# 2. Any running containers?
50-
docker ps --format '{{.Names}} {{.Status}}' 2>/dev/null | grep nanoclaw
22+
container list 2>/dev/null | grep nanoclaw
5123

52-
# 3. Any stopped/orphaned containers?
53-
docker ps -a --format '{{.Names}} {{.Status}}' 2>/dev/null | grep nanoclaw
54-
55-
# 4. Recent errors in service log?
24+
# 3. Recent errors in service log?
5625
grep -E 'ERROR|WARN' logs/nanoclaw.log | tail -20
5726

58-
# 5. Are channels connected? (look for last connection event)
27+
# 4. Are channels connected? (look for last connection event)
5928
grep -E 'Connected|Connection closed|connection.*close|channel.*ready' logs/nanoclaw.log | tail -5
6029

61-
# 6. Are groups loaded?
30+
# 5. Are groups loaded?
6231
grep 'groupCount' logs/nanoclaw.log | tail -3
6332
```
6433

@@ -134,21 +103,7 @@ cat ~/.config/nanoclaw/mount-allowlist.json
134103
sqlite3 store/messages.db "SELECT name, container_config FROM registered_groups;"
135104

136105
# Test-run a container to check mounts (dry run)
137-
# Replace <group-folder> with the group's folder name
138-
docker run -i --rm --entrypoint ls nanoclaw-agent:latest /workspace/extra/
139-
```
140-
141-
## Channel Auth Issues
142-
143-
```bash
144-
# Check if QR code was requested (means auth expired)
145-
grep 'QR\|authentication required\|qr' logs/nanoclaw.log | tail -5
146-
147-
# Check auth files exist
148-
ls -la store/auth/
149-
150-
# Re-authenticate if needed
151-
npm run auth
106+
container run --rm --entrypoint ls nanoclaw-agent:latest /workspace/extra/
152107
```
153108

154109
## Service Management

docs/SECURITY.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ Real API credentials **never enter containers**. NanoClaw uses [OneCLI's Agent V
7878
Each NanoClaw group gets its own OneCLI agent identity. This allows different credential policies per group (e.g. your sales agent vs. support agent). OneCLI supports rate limits, and time-bound access and approval flows are on the roadmap.
7979

8080
**NOT Mounted:**
81-
- Channel auth sessions (`store/auth/`) — host only
8281
- Mount allowlist — external, never mounted
8382
- Any credentials matching blocked patterns
8483
- `.env` is shadowed with `/dev/null` in the project root mount

0 commit comments

Comments
 (0)