@rozek/nanoclaw 1.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +1 -0
- package/.claude/skills/add-compact/SKILL.md +135 -0
- package/.claude/skills/add-discord/SKILL.md +203 -0
- package/.claude/skills/add-gmail/SKILL.md +220 -0
- package/.claude/skills/add-image-vision/SKILL.md +94 -0
- package/.claude/skills/add-ollama-tool/SKILL.md +153 -0
- package/.claude/skills/add-parallel/SKILL.md +290 -0
- package/.claude/skills/add-pdf-reader/SKILL.md +104 -0
- package/.claude/skills/add-reactions/SKILL.md +117 -0
- package/.claude/skills/add-slack/SKILL.md +207 -0
- package/.claude/skills/add-telegram/SKILL.md +222 -0
- package/.claude/skills/add-telegram-swarm/SKILL.md +384 -0
- package/.claude/skills/add-voice-transcription/SKILL.md +148 -0
- package/.claude/skills/add-whatsapp/SKILL.md +372 -0
- package/.claude/skills/convert-to-apple-container/SKILL.md +175 -0
- package/.claude/skills/customize/SKILL.md +110 -0
- package/.claude/skills/debug/SKILL.md +349 -0
- package/.claude/skills/get-qodo-rules/SKILL.md +122 -0
- package/.claude/skills/get-qodo-rules/references/output-format.md +41 -0
- package/.claude/skills/get-qodo-rules/references/pagination.md +33 -0
- package/.claude/skills/get-qodo-rules/references/repository-scope.md +26 -0
- package/.claude/skills/qodo-pr-resolver/SKILL.md +326 -0
- package/.claude/skills/qodo-pr-resolver/resources/providers.md +329 -0
- package/.claude/skills/setup/SKILL.md +218 -0
- package/.claude/skills/update-nanoclaw/SKILL.md +235 -0
- package/.claude/skills/update-skills/SKILL.md +130 -0
- package/.claude/skills/use-local-whisper/SKILL.md +152 -0
- package/.claude/skills/x-integration/SKILL.md +417 -0
- package/.claude/skills/x-integration/agent.ts +243 -0
- package/.claude/skills/x-integration/host.ts +159 -0
- package/.claude/skills/x-integration/lib/browser.ts +148 -0
- package/.claude/skills/x-integration/lib/config.ts +62 -0
- package/.claude/skills/x-integration/scripts/like.ts +56 -0
- package/.claude/skills/x-integration/scripts/post.ts +66 -0
- package/.claude/skills/x-integration/scripts/quote.ts +80 -0
- package/.claude/skills/x-integration/scripts/reply.ts +74 -0
- package/.claude/skills/x-integration/scripts/retweet.ts +62 -0
- package/.claude/skills/x-integration/scripts/setup.ts +87 -0
- package/.env.example +1 -0
- package/.github/CODEOWNERS +10 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- package/.github/workflows/bump-version.yml +32 -0
- package/.github/workflows/ci.yml +25 -0
- package/.github/workflows/merge-forward-skills.yml +160 -0
- package/.github/workflows/update-tokens.yml +42 -0
- package/.husky/pre-commit +1 -0
- package/.mcp.json +3 -0
- package/.nvmrc +1 -0
- package/.prettierrc +3 -0
- package/CHANGELOG.md +8 -0
- package/CLAUDE.md +64 -0
- package/CONTRIBUTING.md +23 -0
- package/CONTRIBUTORS.md +15 -0
- package/LICENSE +21 -0
- package/NanoClaw_with_Web-Support.md +290 -0
- package/README.md +261 -0
- package/README_zh.md +200 -0
- package/assets/nanoclaw-favicon.png +0 -0
- package/assets/nanoclaw-icon.png +0 -0
- package/assets/nanoclaw-logo-dark.png +0 -0
- package/assets/nanoclaw-logo.png +0 -0
- package/assets/nanoclaw-profile.jpeg +0 -0
- package/assets/nanoclaw-sales.png +0 -0
- package/assets/social-preview.jpg +0 -0
- package/config-examples/mount-allowlist.json +25 -0
- package/container/Dockerfile +70 -0
- package/container/agent-runner/package-lock.json +1524 -0
- package/container/agent-runner/package.json +21 -0
- package/container/agent-runner/src/index.ts +558 -0
- package/container/agent-runner/src/ipc-mcp-stdio.ts +338 -0
- package/container/agent-runner/tsconfig.json +15 -0
- package/container/build.sh +23 -0
- package/container/skills/agent-browser/SKILL.md +159 -0
- package/container/skills/capabilities/SKILL.md +100 -0
- package/container/skills/status/SKILL.md +104 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +9 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/registry.d.ts +13 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +11 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/registry.test.d.ts +2 -0
- package/dist/channels/registry.test.d.ts.map +1 -0
- package/dist/channels/registry.test.js +32 -0
- package/dist/channels/registry.test.js.map +1 -0
- package/dist/channels/web.d.ts +2 -0
- package/dist/channels/web.d.ts.map +1 -0
- package/dist/channels/web.js +1738 -0
- package/dist/channels/web.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +182 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/container-runner.d.ts +44 -0
- package/dist/container-runner.d.ts.map +1 -0
- package/dist/container-runner.js +467 -0
- package/dist/container-runner.js.map +1 -0
- package/dist/container-runner.test.d.ts +2 -0
- package/dist/container-runner.test.d.ts.map +1 -0
- package/dist/container-runner.test.js +150 -0
- package/dist/container-runner.test.js.map +1 -0
- package/dist/container-runtime.d.ts +22 -0
- package/dist/container-runtime.d.ts.map +1 -0
- package/dist/container-runtime.js +96 -0
- package/dist/container-runtime.js.map +1 -0
- package/dist/container-runtime.test.d.ts +2 -0
- package/dist/container-runtime.test.d.ts.map +1 -0
- package/dist/container-runtime.test.js +93 -0
- package/dist/container-runtime.test.js.map +1 -0
- package/dist/credential-proxy.d.ts +21 -0
- package/dist/credential-proxy.d.ts.map +1 -0
- package/dist/credential-proxy.js +95 -0
- package/dist/credential-proxy.js.map +1 -0
- package/dist/credential-proxy.test.d.ts +2 -0
- package/dist/credential-proxy.test.d.ts.map +1 -0
- package/dist/credential-proxy.test.js +134 -0
- package/dist/credential-proxy.test.js.map +1 -0
- package/dist/db.d.ts +115 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +549 -0
- package/dist/db.js.map +1 -0
- package/dist/db.test.d.ts +2 -0
- package/dist/db.test.d.ts.map +1 -0
- package/dist/db.test.js +360 -0
- package/dist/db.test.js.map +1 -0
- package/dist/env.d.ts +8 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +42 -0
- package/dist/env.js.map +1 -0
- package/dist/formatting.test.d.ts +2 -0
- package/dist/formatting.test.d.ts.map +1 -0
- package/dist/formatting.test.js +183 -0
- package/dist/formatting.test.js.map +1 -0
- package/dist/group-folder.d.ts +5 -0
- package/dist/group-folder.d.ts.map +1 -0
- package/dist/group-folder.js +44 -0
- package/dist/group-folder.js.map +1 -0
- package/dist/group-folder.test.d.ts +2 -0
- package/dist/group-folder.test.d.ts.map +1 -0
- package/dist/group-folder.test.js +29 -0
- package/dist/group-folder.test.js.map +1 -0
- package/dist/group-queue.d.ts +34 -0
- package/dist/group-queue.d.ts.map +1 -0
- package/dist/group-queue.js +263 -0
- package/dist/group-queue.js.map +1 -0
- package/dist/group-queue.test.d.ts +2 -0
- package/dist/group-queue.test.d.ts.map +1 -0
- package/dist/group-queue.test.js +341 -0
- package/dist/group-queue.test.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +518 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc-auth.test.d.ts +2 -0
- package/dist/ipc-auth.test.d.ts.map +1 -0
- package/dist/ipc-auth.test.js +434 -0
- package/dist/ipc-auth.test.js.map +1 -0
- package/dist/ipc.d.ts +32 -0
- package/dist/ipc.d.ts.map +1 -0
- package/dist/ipc.js +311 -0
- package/dist/ipc.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +14 -0
- package/dist/logger.js.map +1 -0
- package/dist/mount-security.d.ts +34 -0
- package/dist/mount-security.d.ts.map +1 -0
- package/dist/mount-security.js +325 -0
- package/dist/mount-security.js.map +1 -0
- package/dist/remote-control.d.ts +32 -0
- package/dist/remote-control.d.ts.map +1 -0
- package/dist/remote-control.js +185 -0
- package/dist/remote-control.js.map +1 -0
- package/dist/remote-control.test.d.ts +2 -0
- package/dist/remote-control.test.d.ts.map +1 -0
- package/dist/remote-control.test.js +321 -0
- package/dist/remote-control.test.js.map +1 -0
- package/dist/router.d.ts +8 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +37 -0
- package/dist/router.js.map +1 -0
- package/dist/routing.test.d.ts +2 -0
- package/dist/routing.test.d.ts.map +1 -0
- package/dist/routing.test.js +81 -0
- package/dist/routing.test.js.map +1 -0
- package/dist/sender-allowlist.d.ts +14 -0
- package/dist/sender-allowlist.d.ts.map +1 -0
- package/dist/sender-allowlist.js +79 -0
- package/dist/sender-allowlist.js.map +1 -0
- package/dist/sender-allowlist.test.d.ts +2 -0
- package/dist/sender-allowlist.test.d.ts.map +1 -0
- package/dist/sender-allowlist.test.js +186 -0
- package/dist/sender-allowlist.test.js.map +1 -0
- package/dist/session-commands.d.ts +47 -0
- package/dist/session-commands.d.ts.map +1 -0
- package/dist/session-commands.js +102 -0
- package/dist/session-commands.js.map +1 -0
- package/dist/session-commands.test.d.ts +2 -0
- package/dist/session-commands.test.d.ts.map +1 -0
- package/dist/session-commands.test.js +190 -0
- package/dist/session-commands.test.js.map +1 -0
- package/dist/task-scheduler.d.ts +22 -0
- package/dist/task-scheduler.d.ts.map +1 -0
- package/dist/task-scheduler.js +210 -0
- package/dist/task-scheduler.js.map +1 -0
- package/dist/task-scheduler.test.d.ts +2 -0
- package/dist/task-scheduler.test.d.ts.map +1 -0
- package/dist/task-scheduler.test.js +107 -0
- package/dist/task-scheduler.test.js.map +1 -0
- package/dist/timezone.d.ts +6 -0
- package/dist/timezone.d.ts.map +1 -0
- package/dist/timezone.js +17 -0
- package/dist/timezone.js.map +1 -0
- package/dist/timezone.test.d.ts +2 -0
- package/dist/timezone.test.d.ts.map +1 -0
- package/dist/timezone.test.js +23 -0
- package/dist/timezone.test.js.map +1 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/APPLE-CONTAINER-NETWORKING.md +90 -0
- package/docs/DEBUG_CHECKLIST.md +143 -0
- package/docs/REQUIREMENTS.md +196 -0
- package/docs/SDK_DEEP_DIVE.md +643 -0
- package/docs/SECURITY.md +122 -0
- package/docs/SPEC.md +785 -0
- package/docs/docker-sandboxes.md +359 -0
- package/docs/nanoclaw-architecture-final.md +1063 -0
- package/docs/nanorepo-architecture.md +168 -0
- package/docs/skills-as-branches.md +662 -0
- package/groups/global/CLAUDE.md +58 -0
- package/groups/main/CLAUDE.md +246 -0
- package/launchd/com.nanoclaw.plist +32 -0
- package/package.json +45 -0
- package/repo-tokens/README.md +113 -0
- package/repo-tokens/action.yml +186 -0
- package/repo-tokens/badge.svg +23 -0
- package/repo-tokens/examples/green.svg +14 -0
- package/repo-tokens/examples/red.svg +14 -0
- package/repo-tokens/examples/yellow-green.svg +14 -0
- package/repo-tokens/examples/yellow.svg +14 -0
- package/scripts/run-migrations.ts +105 -0
- package/setup/container.ts +144 -0
- package/setup/environment.test.ts +121 -0
- package/setup/environment.ts +94 -0
- package/setup/groups.ts +229 -0
- package/setup/index.ts +58 -0
- package/setup/mounts.ts +115 -0
- package/setup/platform.test.ts +120 -0
- package/setup/platform.ts +132 -0
- package/setup/register.test.ts +257 -0
- package/setup/register.ts +177 -0
- package/setup/service.test.ts +187 -0
- package/setup/service.ts +362 -0
- package/setup/status.ts +16 -0
- package/setup/verify.ts +192 -0
- package/setup.sh +161 -0
- package/src/channels/index.ts +12 -0
- package/src/channels/registry.test.ts +42 -0
- package/src/channels/registry.ts +32 -0
- package/src/channels/web.ts +1856 -0
- package/src/cli.ts +209 -0
- package/src/config.ts +73 -0
- package/src/container-runner.test.ts +210 -0
- package/src/container-runner.ts +707 -0
- package/src/container-runtime.test.ts +149 -0
- package/src/container-runtime.ts +127 -0
- package/src/credential-proxy.test.ts +192 -0
- package/src/credential-proxy.ts +125 -0
- package/src/db.test.ts +484 -0
- package/src/db.ts +803 -0
- package/src/env.ts +42 -0
- package/src/formatting.test.ts +256 -0
- package/src/group-folder.test.ts +43 -0
- package/src/group-folder.ts +44 -0
- package/src/group-queue.test.ts +484 -0
- package/src/group-queue.ts +365 -0
- package/src/index.ts +731 -0
- package/src/ipc-auth.test.ts +679 -0
- package/src/ipc.ts +461 -0
- package/src/logger.ts +16 -0
- package/src/mount-security.ts +419 -0
- package/src/remote-control.test.ts +397 -0
- package/src/remote-control.ts +224 -0
- package/src/router.ts +52 -0
- package/src/routing.test.ts +170 -0
- package/src/sender-allowlist.test.ts +216 -0
- package/src/sender-allowlist.ts +128 -0
- package/src/session-commands.test.ts +247 -0
- package/src/session-commands.ts +163 -0
- package/src/task-scheduler.test.ts +129 -0
- package/src/task-scheduler.ts +295 -0
- package/src/timezone.test.ts +29 -0
- package/src/timezone.ts +16 -0
- package/src/types.ts +107 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +7 -0
- package/vitest.skills.config.ts +7 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# NanoClaw Debug Checklist
|
|
2
|
+
|
|
3
|
+
## Known Issues (2026-02-08)
|
|
4
|
+
|
|
5
|
+
### 1. [FIXED] Resume branches from stale tree position
|
|
6
|
+
When agent teams spawns subagent CLI processes, they write to the same session JSONL. On subsequent `query()` resumes, the CLI reads the JSONL but may pick a stale branch tip (from before the subagent activity), causing the agent's response to land on a branch the host never receives a `result` for. **Fix**: pass `resumeSessionAt` with the last assistant message UUID to explicitly anchor each resume.
|
|
7
|
+
|
|
8
|
+
### 2. IDLE_TIMEOUT == CONTAINER_TIMEOUT (both 30 min)
|
|
9
|
+
Both timers fire at the same time, so containers always exit via hard SIGKILL (code 137) instead of graceful `_close` sentinel shutdown. The idle timeout should be shorter (e.g., 5 min) so containers wind down between messages, while container timeout stays at 30 min as a safety net for stuck agents.
|
|
10
|
+
|
|
11
|
+
### 3. Cursor advanced before agent succeeds
|
|
12
|
+
`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.
|
|
13
|
+
|
|
14
|
+
## Quick Status Check
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 1. Is the service running?
|
|
18
|
+
launchctl list | grep nanoclaw
|
|
19
|
+
# Expected: PID 0 com.nanoclaw (PID = running, "-" = not running, non-zero exit = crashed)
|
|
20
|
+
|
|
21
|
+
# 2. Any running containers?
|
|
22
|
+
container ls --format '{{.Names}} {{.Status}}' 2>/dev/null | grep nanoclaw
|
|
23
|
+
|
|
24
|
+
# 3. Any stopped/orphaned containers?
|
|
25
|
+
container ls -a --format '{{.Names}} {{.Status}}' 2>/dev/null | grep nanoclaw
|
|
26
|
+
|
|
27
|
+
# 4. Recent errors in service log?
|
|
28
|
+
grep -E 'ERROR|WARN' logs/nanoclaw.log | tail -20
|
|
29
|
+
|
|
30
|
+
# 5. Is WhatsApp connected? (look for last connection event)
|
|
31
|
+
grep -E 'Connected to WhatsApp|Connection closed|connection.*close' logs/nanoclaw.log | tail -5
|
|
32
|
+
|
|
33
|
+
# 6. Are groups loaded?
|
|
34
|
+
grep 'groupCount' logs/nanoclaw.log | tail -3
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Session Transcript Branching
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Check for concurrent CLI processes in session debug logs
|
|
41
|
+
ls -la data/sessions/<group>/.claude/debug/
|
|
42
|
+
|
|
43
|
+
# Count unique SDK processes that handled messages
|
|
44
|
+
# Each .txt file = one CLI subprocess. Multiple = concurrent queries.
|
|
45
|
+
|
|
46
|
+
# Check parentUuid branching in transcript
|
|
47
|
+
python3 -c "
|
|
48
|
+
import json, sys
|
|
49
|
+
lines = open('data/sessions/<group>/.claude/projects/-workspace-group/<session>.jsonl').read().strip().split('\n')
|
|
50
|
+
for i, line in enumerate(lines):
|
|
51
|
+
try:
|
|
52
|
+
d = json.loads(line)
|
|
53
|
+
if d.get('type') == 'user' and d.get('message'):
|
|
54
|
+
parent = d.get('parentUuid', 'ROOT')[:8]
|
|
55
|
+
content = str(d['message'].get('content', ''))[:60]
|
|
56
|
+
print(f'L{i+1} parent={parent} {content}')
|
|
57
|
+
except: pass
|
|
58
|
+
"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Container Timeout Investigation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Check for recent timeouts
|
|
65
|
+
grep -E 'Container timeout|timed out' logs/nanoclaw.log | tail -10
|
|
66
|
+
|
|
67
|
+
# Check container log files for the timed-out container
|
|
68
|
+
ls -lt groups/*/logs/container-*.log | head -10
|
|
69
|
+
|
|
70
|
+
# Read the most recent container log (replace path)
|
|
71
|
+
cat groups/<group>/logs/container-<timestamp>.log
|
|
72
|
+
|
|
73
|
+
# Check if retries were scheduled and what happened
|
|
74
|
+
grep -E 'Scheduling retry|retry|Max retries' logs/nanoclaw.log | tail -10
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Agent Not Responding
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Check if messages are being received from WhatsApp
|
|
81
|
+
grep 'New messages' logs/nanoclaw.log | tail -10
|
|
82
|
+
|
|
83
|
+
# Check if messages are being processed (container spawned)
|
|
84
|
+
grep -E 'Processing messages|Spawning container' logs/nanoclaw.log | tail -10
|
|
85
|
+
|
|
86
|
+
# Check if messages are being piped to active container
|
|
87
|
+
grep -E 'Piped messages|sendMessage' logs/nanoclaw.log | tail -10
|
|
88
|
+
|
|
89
|
+
# Check the queue state — any active containers?
|
|
90
|
+
grep -E 'Starting container|Container active|concurrency limit' logs/nanoclaw.log | tail -10
|
|
91
|
+
|
|
92
|
+
# Check lastAgentTimestamp vs latest message timestamp
|
|
93
|
+
sqlite3 store/messages.db "SELECT chat_jid, MAX(timestamp) as latest FROM messages GROUP BY chat_jid ORDER BY latest DESC LIMIT 5;"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Container Mount Issues
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Check mount validation logs (shows on container spawn)
|
|
100
|
+
grep -E 'Mount validated|Mount.*REJECTED|mount' logs/nanoclaw.log | tail -10
|
|
101
|
+
|
|
102
|
+
# Verify the mount allowlist is readable
|
|
103
|
+
cat ~/.config/nanoclaw/mount-allowlist.json
|
|
104
|
+
|
|
105
|
+
# Check group's container_config in DB
|
|
106
|
+
sqlite3 store/messages.db "SELECT name, container_config FROM registered_groups;"
|
|
107
|
+
|
|
108
|
+
# Test-run a container to check mounts (dry run)
|
|
109
|
+
# Replace <group-folder> with the group's folder name
|
|
110
|
+
container run -i --rm --entrypoint ls nanoclaw-agent:latest /workspace/extra/
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## WhatsApp Auth Issues
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Check if QR code was requested (means auth expired)
|
|
117
|
+
grep 'QR\|authentication required\|qr' logs/nanoclaw.log | tail -5
|
|
118
|
+
|
|
119
|
+
# Check auth files exist
|
|
120
|
+
ls -la store/auth/
|
|
121
|
+
|
|
122
|
+
# Re-authenticate if needed
|
|
123
|
+
npm run auth
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Service Management
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Restart the service
|
|
130
|
+
launchctl kickstart -k gui/$(id -u)/com.nanoclaw
|
|
131
|
+
|
|
132
|
+
# View live logs
|
|
133
|
+
tail -f logs/nanoclaw.log
|
|
134
|
+
|
|
135
|
+
# Stop the service (careful — running containers are detached, not killed)
|
|
136
|
+
launchctl bootout gui/$(id -u)/com.nanoclaw
|
|
137
|
+
|
|
138
|
+
# Start the service
|
|
139
|
+
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.nanoclaw.plist
|
|
140
|
+
|
|
141
|
+
# Rebuild after code changes
|
|
142
|
+
npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw
|
|
143
|
+
```
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# NanoClaw Requirements
|
|
2
|
+
|
|
3
|
+
Original requirements and design decisions from the project creator.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Why This Exists
|
|
8
|
+
|
|
9
|
+
This is a lightweight, secure alternative to OpenClaw (formerly ClawBot). That project became a monstrosity - 4-5 different processes running different gateways, endless configuration files, endless integrations. It's a security nightmare where agents don't run in isolated processes; there's all kinds of leaky workarounds trying to prevent them from accessing parts of the system they shouldn't. It's impossible for anyone to realistically understand the whole codebase. When you run it you're kind of just yoloing it.
|
|
10
|
+
|
|
11
|
+
NanoClaw gives you the core functionality without that mess.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Philosophy
|
|
16
|
+
|
|
17
|
+
### Small Enough to Understand
|
|
18
|
+
|
|
19
|
+
The entire codebase should be something you can read and understand. One Node.js process. A handful of source files. No microservices, no message queues, no abstraction layers.
|
|
20
|
+
|
|
21
|
+
### Security Through True Isolation
|
|
22
|
+
|
|
23
|
+
Instead of application-level permission systems trying to prevent agents from accessing things, agents run in actual Linux containers. The isolation is at the OS level. Agents can only see what's explicitly mounted. Bash access is safe because commands run inside the container, not on your Mac.
|
|
24
|
+
|
|
25
|
+
### Built for One User
|
|
26
|
+
|
|
27
|
+
This isn't a framework or a platform. It's working software for my specific needs. I use WhatsApp and Email, so it supports WhatsApp and Email. I don't use Telegram, so it doesn't support Telegram. I add the integrations I actually want, not every possible integration.
|
|
28
|
+
|
|
29
|
+
### Customization = Code Changes
|
|
30
|
+
|
|
31
|
+
No configuration sprawl. If you want different behavior, modify the code. The codebase is small enough that this is safe and practical. Very minimal things like the trigger word are in config. Everything else - just change the code to do what you want.
|
|
32
|
+
|
|
33
|
+
### AI-Native Development
|
|
34
|
+
|
|
35
|
+
I don't need an installation wizard - Claude Code guides the setup. I don't need a monitoring dashboard - I ask Claude Code what's happening. I don't need elaborate logging UIs - I ask Claude to read the logs. I don't need debugging tools - I describe the problem and Claude fixes it.
|
|
36
|
+
|
|
37
|
+
The codebase assumes you have an AI collaborator. It doesn't need to be excessively self-documenting or self-debugging because Claude is always there.
|
|
38
|
+
|
|
39
|
+
### Skills Over Features
|
|
40
|
+
|
|
41
|
+
When people contribute, they shouldn't add "Telegram support alongside WhatsApp." They should contribute a skill like `/add-telegram` that transforms the codebase. Users fork the repo, run skills to customize, and end up with clean code that does exactly what they need - not a bloated system trying to support everyone's use case simultaneously.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## RFS (Request for Skills)
|
|
46
|
+
|
|
47
|
+
Skills we'd love contributors to build:
|
|
48
|
+
|
|
49
|
+
### Communication Channels
|
|
50
|
+
Skills to add or switch to different messaging platforms:
|
|
51
|
+
- `/add-telegram` - Add Telegram as an input channel
|
|
52
|
+
- `/add-slack` - Add Slack as an input channel
|
|
53
|
+
- `/add-discord` - Add Discord as an input channel
|
|
54
|
+
- `/add-sms` - Add SMS via Twilio or similar
|
|
55
|
+
- `/convert-to-telegram` - Replace WhatsApp with Telegram entirely
|
|
56
|
+
|
|
57
|
+
### Container Runtime
|
|
58
|
+
The project uses Docker by default (cross-platform). For macOS users who prefer Apple Container:
|
|
59
|
+
- `/convert-to-apple-container` - Switch from Docker to Apple Container (macOS-only)
|
|
60
|
+
|
|
61
|
+
### Platform Support
|
|
62
|
+
- `/setup-linux` - Make the full setup work on Linux (depends on Docker conversion)
|
|
63
|
+
- `/setup-windows` - Windows support via WSL2 + Docker
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Vision
|
|
68
|
+
|
|
69
|
+
A personal Claude assistant accessible via WhatsApp, with minimal custom code.
|
|
70
|
+
|
|
71
|
+
**Core components:**
|
|
72
|
+
- **Claude Agent SDK** as the core agent
|
|
73
|
+
- **Containers** for isolated agent execution (Linux VMs)
|
|
74
|
+
- **WhatsApp** as the primary I/O channel
|
|
75
|
+
- **Persistent memory** per conversation and globally
|
|
76
|
+
- **Scheduled tasks** that run Claude and can message back
|
|
77
|
+
- **Web access** for search and browsing
|
|
78
|
+
- **Browser automation** via agent-browser
|
|
79
|
+
|
|
80
|
+
**Implementation approach:**
|
|
81
|
+
- Use existing tools (WhatsApp connector, Claude Agent SDK, MCP servers)
|
|
82
|
+
- Minimal glue code
|
|
83
|
+
- File-based systems where possible (CLAUDE.md for memory, folders for groups)
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Architecture Decisions
|
|
88
|
+
|
|
89
|
+
### Message Routing
|
|
90
|
+
- A router listens to WhatsApp and routes messages based on configuration
|
|
91
|
+
- Only messages from registered groups are processed
|
|
92
|
+
- Trigger: `@Andy` prefix (case insensitive), configurable via `ASSISTANT_NAME` env var
|
|
93
|
+
- Unregistered groups are ignored completely
|
|
94
|
+
|
|
95
|
+
### Memory System
|
|
96
|
+
- **Per-group memory**: Each group has a folder with its own `CLAUDE.md`
|
|
97
|
+
- **Global memory**: Root `CLAUDE.md` is read by all groups, but only writable from "main" (self-chat)
|
|
98
|
+
- **Files**: Groups can create/read files in their folder and reference them
|
|
99
|
+
- Agent runs in the group's folder, automatically inherits both CLAUDE.md files
|
|
100
|
+
|
|
101
|
+
### Session Management
|
|
102
|
+
- Each group maintains a conversation session (via Claude Agent SDK)
|
|
103
|
+
- Sessions auto-compact when context gets too long, preserving critical information
|
|
104
|
+
|
|
105
|
+
### Container Isolation
|
|
106
|
+
- All agents run inside containers (lightweight Linux VMs)
|
|
107
|
+
- Each agent invocation spawns a container with mounted directories
|
|
108
|
+
- Containers provide filesystem isolation - agents can only see mounted paths
|
|
109
|
+
- Bash access is safe because commands run inside the container, not on the host
|
|
110
|
+
- Browser automation via agent-browser with Chromium in the container
|
|
111
|
+
|
|
112
|
+
### Scheduled Tasks
|
|
113
|
+
- Users can ask Claude to schedule recurring or one-time tasks from any group
|
|
114
|
+
- Tasks run as full agents in the context of the group that created them
|
|
115
|
+
- Tasks have access to all tools including Bash (safe in container)
|
|
116
|
+
- Tasks can optionally send messages to their group via `send_message` tool, or complete silently
|
|
117
|
+
- Task runs are logged to the database with duration and result
|
|
118
|
+
- Schedule types: cron expressions, intervals (ms), or one-time (ISO timestamp)
|
|
119
|
+
- From main: can schedule tasks for any group, view/manage all tasks
|
|
120
|
+
- From other groups: can only manage that group's tasks
|
|
121
|
+
|
|
122
|
+
### Group Management
|
|
123
|
+
- New groups are added explicitly via the main channel
|
|
124
|
+
- Groups are registered in SQLite (via the main channel or IPC `register_group` command)
|
|
125
|
+
- Each group gets a dedicated folder under `groups/`
|
|
126
|
+
- Groups can have additional directories mounted via `containerConfig`
|
|
127
|
+
|
|
128
|
+
### Main Channel Privileges
|
|
129
|
+
- Main channel is the admin/control group (typically self-chat)
|
|
130
|
+
- Can write to global memory (`groups/CLAUDE.md`)
|
|
131
|
+
- Can schedule tasks for any group
|
|
132
|
+
- Can view and manage tasks from all groups
|
|
133
|
+
- Can configure additional directory mounts for any group
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Integration Points
|
|
138
|
+
|
|
139
|
+
### WhatsApp
|
|
140
|
+
- Using baileys library for WhatsApp Web connection
|
|
141
|
+
- Messages stored in SQLite, polled by router
|
|
142
|
+
- QR code authentication during setup
|
|
143
|
+
|
|
144
|
+
### Scheduler
|
|
145
|
+
- Built-in scheduler runs on the host, spawns containers for task execution
|
|
146
|
+
- Custom `nanoclaw` MCP server (inside container) provides scheduling tools
|
|
147
|
+
- Tools: `schedule_task`, `list_tasks`, `pause_task`, `resume_task`, `cancel_task`, `send_message`
|
|
148
|
+
- Tasks stored in SQLite with run history
|
|
149
|
+
- Scheduler loop checks for due tasks every minute
|
|
150
|
+
- Tasks execute Claude Agent SDK in containerized group context
|
|
151
|
+
|
|
152
|
+
### Web Access
|
|
153
|
+
- Built-in WebSearch and WebFetch tools
|
|
154
|
+
- Standard Claude Agent SDK capabilities
|
|
155
|
+
|
|
156
|
+
### Browser Automation
|
|
157
|
+
- agent-browser CLI with Chromium in container
|
|
158
|
+
- Snapshot-based interaction with element references (@e1, @e2, etc.)
|
|
159
|
+
- Screenshots, PDFs, video recording
|
|
160
|
+
- Authentication state persistence
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Setup & Customization
|
|
165
|
+
|
|
166
|
+
### Philosophy
|
|
167
|
+
- Minimal configuration files
|
|
168
|
+
- Setup and customization done via Claude Code
|
|
169
|
+
- Users clone the repo and run Claude Code to configure
|
|
170
|
+
- Each user gets a custom setup matching their exact needs
|
|
171
|
+
|
|
172
|
+
### Skills
|
|
173
|
+
- `/setup` - Install dependencies, authenticate WhatsApp, configure scheduler, start services
|
|
174
|
+
- `/customize` - General-purpose skill for adding capabilities (new channels like Telegram, new integrations, behavior changes)
|
|
175
|
+
- `/update` - Pull upstream changes, merge with customizations, run migrations
|
|
176
|
+
|
|
177
|
+
### Deployment
|
|
178
|
+
- Runs on local Mac via launchd
|
|
179
|
+
- Single Node.js process handles everything
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Personal Configuration (Reference)
|
|
184
|
+
|
|
185
|
+
These are the creator's settings, stored here for reference:
|
|
186
|
+
|
|
187
|
+
- **Trigger**: `@Andy` (case insensitive)
|
|
188
|
+
- **Response prefix**: `Andy:`
|
|
189
|
+
- **Persona**: Default Claude (no custom personality)
|
|
190
|
+
- **Main channel**: Self-chat (messaging yourself in WhatsApp)
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Project Name
|
|
195
|
+
|
|
196
|
+
**NanoClaw** - A reference to Clawdbot (now OpenClaw).
|