* refactor: implement channel architecture and dynamic setup - Introduced ChannelRegistry for dynamic channel loading - Decoupled WhatsApp from core index.ts and config.ts - Updated setup wizard to support ENABLED_CHANNELS selection - Refactored IPC and group registration to be channel-aware - Verified with 359 passing tests and clean typecheck * style: fix formatting in config.ts to pass CI * refactor(setup): full platform-agnostic transformation - Harmonized all instructional text and help prompts - Implemented conditional guards for WhatsApp-specific steps - Normalized CLI terminology across all 4 initial channels - Unified troubleshooting and verification logic - Verified 369 tests pass with clean typecheck * feat(skills): transform WhatsApp into a pluggable skill - Created .claude/skills/add-whatsapp with full 5-phase interactive setup - Fixed TS7006 'implicit any' error in IpcDeps - Added auto-creation of STORE_DIR to prevent crashes on fresh installs - Verified with 369 passing tests and clean typecheck * refactor(skills): move WhatsApp from core to pluggable skill - Move src/channels/whatsapp.ts to add-whatsapp skill add/ folder - Move src/channels/whatsapp.test.ts to skill add/ folder - Move src/whatsapp-auth.ts to skill add/ folder - Create modify/ for barrel file (src/channels/index.ts) - Create tests/ with skill package validation test - Update manifest with adds/modifies lists - Remove WhatsApp deps from core package.json (now skill-managed) - Remove WhatsApp-specific ghost language from types.ts - Update SKILL.md to reflect skill-apply workflow Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(skills): move setup/whatsapp-auth.ts into WhatsApp skill The WhatsApp auth setup step is channel-specific — move it from core to the add-whatsapp skill so core stays minimal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(skills): convert Telegram skill to pluggable channel pattern Replace the old direct-integration approach (modifying src/index.ts, src/config.ts, src/routing.test.ts) with self-registration via the channel registry, matching the WhatsApp skill pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(skills): fix add-whatsapp build failure and improve auth flow - Add missing @types/qrcode-terminal to manifest npm_dependencies (build failed after skill apply without it) - Make QR-browser the recommended auth method (terminal QR too small, pairing codes expire too fast) - Remove "replace vs alongside" question — channels are additive - Add pairing code retry guidance and QR-browser fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove hardcoded WhatsApp default and stale Baileys comment - ENABLED_CHANNELS now defaults to empty (fresh installs must configure channels explicitly via /setup; existing installs already have .env) - Remove Baileys-specific comment from storeMessageDirect() in db.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(skills): convert Discord, Slack, Gmail skills to pluggable channel pattern All channel skills now use the same self-registration pattern: - registerChannel() factory at module load time - Barrel file append (src/channels/index.ts) instead of orchestrator modifications - No more *_ONLY flags (DISCORD_ONLY, SLACK_ONLY) — use ENABLED_CHANNELS instead - Removed ~2500 lines of old modify/ files (src/index.ts, src/config.ts, src/routing.test.ts) Gmail retains its container-runner.ts and agent-runner modifications (MCP mount + server config) since those are independent of channel wiring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: use getRegisteredChannels instead of ENABLED_CHANNELS Remove the ENABLED_CHANNELS env var entirely. The orchestrator now iterates getRegisteredChannelNames() from the channel registry — channels self-register via barrel imports and their factories return null when credentials are missing, so unconfigured channels are skipped automatically. Deleted setup/channels.ts (and its tests) since its sole purpose was writing ENABLED_CHANNELS to .env. Refactored verify, groups, and environment setup steps to detect channels by credential presence instead of reading ENABLED_CHANNELS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add breaking change notice and whatsapp migration instructions CHANGELOG.md documents the pluggable channel architecture shift and provides migration steps for existing WhatsApp users. CLAUDE.md updated: Quick Context reflects multi-channel architecture, Key Files lists registry.ts instead of whatsapp.ts, and a new Troubleshooting section directs users to /add-whatsapp if WhatsApp stops connecting after upgrade. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: rewrite READMEs for pluggable multi-channel architecture Reflects the architectural shift from a hardcoded WhatsApp bot to a pluggable channel platform. Adds upgrading notice, Mermaid architecture diagram, CI/License/TypeScript/PRs badges, and clarifies that slash commands run inside the Claude Code CLI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: move pluggable channel architecture details to SPEC.md Revert READMEs to original tone with only two targeted changes: - Add upgrading notice for WhatsApp breaking change - Mention pluggable channels in "What It Supports" Move Mermaid diagram, channel registry internals, factory pattern explanation, and self-registration walkthrough into docs/SPEC.md. Update stale WhatsApp-specific references in SPEC.md to be channel-agnostic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: move upgrading notice to CHANGELOG, add changelog link Remove the "Upgrading from Pre-Pluggable Versions" section from README.md — breaking change details belong in the CHANGELOG. Add a Changelog section linking to CHANGELOG.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: expand CHANGELOG with full PR #500 changes Cover all changes: channel registry, WhatsApp moved to skill, removed core dependencies, all 5 skills simplified, orchestrator refactored, setup decoupled. Use Claude Code CLI instructions for migration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: bump version to 1.2.0 for pluggable channel architecture Minor version bump — new functionality (pluggable channels) with a managed migration path for existing WhatsApp users. Update version references in CHANGELOG and update skill. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix skill application * fix: use slotted barrel file to prevent channel merge conflicts Pre-allocate a named comment slot for each channel in src/channels/index.ts, separated by blank lines. Each skill's modify file only touches its own slot, so three-way merges never conflict when applying multiple channels. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve real chat ID during setup for token-based channels Instead of registering with `pending@telegram` (which never matches incoming messages), the setup skill now runs an inline bot that waits for the user to send /chatid, capturing the real chat ID before registration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: setup delegates to channel skills, fix group sync and Discord metadata - Restructure setup SKILL.md to delegate channel setup to individual channel skills (/add-whatsapp, /add-telegram, etc.) instead of reimplementing auth/registration inline with broken placeholder JIDs - Move channel selection to step 5 where it's immediately acted on - Fix setup/groups.ts: write sync script to temp file instead of passing via node -e which broke on shell escaping of newlines - Fix Discord onChatMetadata missing channel and isGroup parameters - Add .tmp-* to .gitignore for temp sync script cleanup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: align add-whatsapp skill with main setup patterns Add headless detection for auth method selection, structured inline error handling, dedicated number DM flow, and reorder questions to match main's trigger-first flow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add missing auth script to package.json The add-whatsapp skill adds src/whatsapp-auth.ts but doesn't add the corresponding npm script. Setup and SKILL.md reference `npm run auth` for WhatsApp QR terminal authentication. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update Discord skill tests to match onChatMetadata signature The onChatMetadata callback now takes 5 arguments (jid, timestamp, name, channel, isGroup) but the Discord skill tests only expected 3. This caused skill application to roll back on test failure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: replace 'pluggable' jargon with clearer language User-facing text now says "multi-channel" or describes what it does. Developer-facing text uses "self-registering" or "channel registry". Also removes extra badge row from README. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: align Chinese README with English version Remove extra badges, replace pluggable jargon, remove upgrade section (now in CHANGELOG), add missing intro line and changelog section, fix setup FAQ answer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: warn on installed-but-unconfigured channels instead of silent skip Channels with missing credentials now emit WARN logs naming the exact missing variable, so misconfigurations surface instead of being hidden. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: simplify changelog to one-liner with compare link Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add isMain flag and channel-prefixed group folders Replace MAIN_GROUP_FOLDER constant with explicit isMain boolean on RegisteredGroup. Group folders now use channel prefix convention (e.g., whatsapp_main, telegram_family-chat) to prevent cross-channel collisions. - Add isMain to RegisteredGroup type and SQLite schema (with migration) - Replace all folder-based main group checks with group.isMain - Add --is-main flag to setup/register.ts - Strip isMain from IPC payload (defense in depth) - Update MCP tool description for channel-prefixed naming - Update all channel SKILL.md files and documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: gavrielc <gabicohen22@yahoo.com> Co-authored-by: Koshkoshinski <daniel.milliner@gmail.com>
204 lines
10 KiB
Markdown
204 lines
10 KiB
Markdown
<p align="center">
|
|
<img src="assets/nanoclaw-logo.png" alt="NanoClaw" width="400">
|
|
</p>
|
|
|
|
<p align="center">
|
|
An AI assistant that runs agents securely in their own containers. Lightweight, built to be easily understood and completely customized for your needs.
|
|
</p>
|
|
|
|
<p align="center">
|
|
<a href="https://nanoclaw.dev">nanoclaw.dev</a> •
|
|
<a href="README_zh.md">中文</a> •
|
|
<a href="https://discord.gg/VDdww8qS42"><img src="https://img.shields.io/discord/1470188214710046894?label=Discord&logo=discord&v=2" alt="Discord" valign="middle"></a> •
|
|
<a href="repo-tokens"><img src="repo-tokens/badge.svg" alt="34.9k tokens, 17% of context window" valign="middle"></a>
|
|
</p>
|
|
Using Claude Code, NanoClaw can dynamically rewrite its code to customize its feature set for your needs.
|
|
|
|
**New:** First AI assistant to support [Agent Swarms](https://code.claude.com/docs/en/agent-teams). Spin up teams of agents that collaborate in your chat.
|
|
|
|
## Why I Built NanoClaw
|
|
|
|
[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.
|
|
|
|
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.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
git clone https://github.com/qwibitai/NanoClaw.git
|
|
cd NanoClaw
|
|
claude
|
|
```
|
|
|
|
Then run `/setup`. Claude Code handles everything: dependencies, authentication, container setup and service configuration.
|
|
|
|
> **Note:** Commands prefixed with `/` (like `/setup`, `/add-whatsapp`) are [Claude Code skills](https://code.claude.com/docs/en/skills). Type them inside the `claude` CLI prompt, not in your regular terminal.
|
|
|
|
## Philosophy
|
|
|
|
**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.
|
|
|
|
**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.
|
|
|
|
**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.
|
|
|
|
**Customization = code changes.** No configuration sprawl. Want different behavior? Modify the code. The codebase is small enough that it's safe to make changes.
|
|
|
|
**AI-native.**
|
|
- No installation wizard; Claude Code guides setup.
|
|
- No monitoring dashboard; ask Claude what's happening.
|
|
- No debugging tools; describe the problem and Claude fixes it.
|
|
|
|
**Skills over features.** Instead of adding features (e.g. support for Telegram) to the codebase, contributors submit [claude code skills](https://code.claude.com/docs/en/skills) like `/add-telegram` that transform your fork. You end up with clean code that does exactly what you need.
|
|
|
|
**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.
|
|
|
|
## What It Supports
|
|
|
|
- **Multi-channel messaging** - Talk to your assistant from WhatsApp, Telegram, Discord, Slack, or Gmail. Add channels with skills like `/add-whatsapp` or `/add-telegram`. Run one or many at the same time.
|
|
- **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.
|
|
- **Main channel** - Your private channel (self-chat) for admin control; every group is completely isolated
|
|
- **Scheduled tasks** - Recurring jobs that run Claude and can message you back
|
|
- **Web access** - Search and fetch content from the Web
|
|
- **Container isolation** - Agents are sandboxed in Apple Container (macOS) or Docker (macOS/Linux)
|
|
- **Agent Swarms** - Spin up teams of specialized agents that collaborate on complex tasks. NanoClaw is the first personal AI assistant to support agent swarms.
|
|
- **Optional integrations** - Add Gmail (`/add-gmail`) and more via skills
|
|
|
|
## Usage
|
|
|
|
Talk to your assistant with the trigger word (default: `@Andy`):
|
|
|
|
```
|
|
@Andy send an overview of the sales pipeline every weekday morning at 9am (has access to my Obsidian vault folder)
|
|
@Andy review the git history for the past week each Friday and update the README if there's drift
|
|
@Andy every Monday at 8am, compile news on AI developments from Hacker News and TechCrunch and message me a briefing
|
|
```
|
|
|
|
From the main channel (your self-chat), you can manage groups and tasks:
|
|
```
|
|
@Andy list all scheduled tasks across groups
|
|
@Andy pause the Monday briefing task
|
|
@Andy join the Family Chat group
|
|
```
|
|
|
|
## Customizing
|
|
|
|
NanoClaw doesn't use configuration files. To make changes, just tell Claude Code what you want:
|
|
|
|
- "Change the trigger word to @Bob"
|
|
- "Remember in the future to make responses shorter and more direct"
|
|
- "Add a custom greeting when I say good morning"
|
|
- "Store conversation summaries weekly"
|
|
|
|
Or run `/customize` for guided changes.
|
|
|
|
The codebase is small enough that Claude can safely modify it.
|
|
|
|
## Contributing
|
|
|
|
**Don't add features. Add skills.**
|
|
|
|
If you want to add Telegram support, don't create a PR that adds Telegram alongside WhatsApp. Instead, contribute a skill file (`.claude/skills/add-telegram/SKILL.md`) that teaches Claude Code how to transform a NanoClaw installation to use Telegram.
|
|
|
|
Users then run `/add-telegram` on their fork and get clean code that does exactly what they need, not a bloated system trying to support every use case.
|
|
|
|
### RFS (Request for Skills)
|
|
|
|
Skills we'd like to see:
|
|
|
|
**Communication Channels**
|
|
- `/add-signal` - Add Signal as a channel
|
|
|
|
**Session Management**
|
|
- `/clear` - Add a `/clear` command that compacts the conversation (summarizes context while preserving critical information in the same session). Requires figuring out how to trigger compaction programmatically via the Claude Agent SDK.
|
|
|
|
## Requirements
|
|
|
|
- macOS or Linux
|
|
- Node.js 20+
|
|
- [Claude Code](https://claude.ai/download)
|
|
- [Apple Container](https://github.com/apple/container) (macOS) or [Docker](https://docker.com/products/docker-desktop) (macOS/Linux)
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Channels --> SQLite --> Polling loop --> Container (Claude Agent SDK) --> Response
|
|
```
|
|
|
|
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.
|
|
|
|
For the full architecture details, see [docs/SPEC.md](docs/SPEC.md).
|
|
|
|
Key files:
|
|
- `src/index.ts` - Orchestrator: state, message loop, agent invocation
|
|
- `src/channels/registry.ts` - Channel registry (self-registration at startup)
|
|
- `src/ipc.ts` - IPC watcher and task processing
|
|
- `src/router.ts` - Message formatting and outbound routing
|
|
- `src/group-queue.ts` - Per-group queue with global concurrency limit
|
|
- `src/container-runner.ts` - Spawns streaming agent containers
|
|
- `src/task-scheduler.ts` - Runs scheduled tasks
|
|
- `src/db.ts` - SQLite operations (messages, groups, sessions, state)
|
|
- `groups/*/CLAUDE.md` - Per-group memory
|
|
|
|
## FAQ
|
|
|
|
**Why Docker?**
|
|
|
|
Docker provides cross-platform support (macOS, Linux and even Windows via WSL2) and a mature ecosystem. On macOS, you can optionally switch to Apple Container via `/convert-to-apple-container` for a lighter-weight native runtime.
|
|
|
|
**Can I run this on Linux?**
|
|
|
|
Yes. Docker is the default runtime and works on both macOS and Linux. Just run `/setup`.
|
|
|
|
**Is this secure?**
|
|
|
|
Agents run in containers, not behind application-level permission checks. They can only access explicitly mounted directories. You should still review what you're running, but the codebase is small enough that you actually can. See [docs/SECURITY.md](docs/SECURITY.md) for the full security model.
|
|
|
|
**Why no configuration files?**
|
|
|
|
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.
|
|
|
|
**Can I use third-party or open-source models?**
|
|
|
|
Yes. NanoClaw supports any API-compatible model endpoint. Set these environment variables in your `.env` file:
|
|
|
|
```bash
|
|
ANTHROPIC_BASE_URL=https://your-api-endpoint.com
|
|
ANTHROPIC_AUTH_TOKEN=your-token-here
|
|
```
|
|
|
|
This allows you to use:
|
|
- Local models via [Ollama](https://ollama.ai) with an API proxy
|
|
- Open-source models hosted on [Together AI](https://together.ai), [Fireworks](https://fireworks.ai), etc.
|
|
- Custom model deployments with Anthropic-compatible APIs
|
|
|
|
Note: The model must support the Anthropic API format for best compatibility.
|
|
|
|
**How do I debug issues?**
|
|
|
|
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.
|
|
|
|
**Why isn't the setup working for me?**
|
|
|
|
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.
|
|
|
|
**What changes will be accepted into the codebase?**
|
|
|
|
Only security fixes, bug fixes, and clear improvements will be accepted to the base configuration. That's all.
|
|
|
|
Everything else (new capabilities, OS compatibility, hardware support, enhancements) should be contributed as skills.
|
|
|
|
This keeps the base system minimal and lets every user customize their installation without inheriting features they don't want.
|
|
|
|
## Community
|
|
|
|
Questions? Ideas? [Join the Discord](https://discord.gg/VDdww8qS42).
|
|
|
|
## Changelog
|
|
|
|
See [CHANGELOG.md](CHANGELOG.md) for breaking changes and migration notes.
|
|
|
|
## License
|
|
|
|
MIT
|