feat: add Discord channel, OpenCode runtime, rename to Regolith
Some checks failed
Update token count / update-tokens (push) Has been cancelled
Some checks failed
Update token count / update-tokens (push) Has been cancelled
- Discord channel integration (discord.js) with mention stripping, attachment tagging, reply context, message chunking - OpenCode runtime with CLI and SDK modes, SQLite session persistence, idle timeout cleanup - Multi-channel architecture: WhatsApp + Discord simultaneous or independent via DISCORD_ONLY/DISCORD_BOT_TOKEN - Config additions: DISCORD_BOT_TOKEN, DISCORD_ONLY, OPENCODE_MODE, OPENCODE_MODEL, OPENCODE_TIMEOUT, OPENCODE_SESSION_TTL_HOURS - Updated README and CLAUDE.md documentation - Renamed project to Regolith in package.json
This commit is contained in:
243
README.md
243
README.md
@@ -1,197 +1,156 @@
|
||||
<p align="center">
|
||||
<img src="assets/nanoclaw-logo.png" alt="NanoClaw" width="400">
|
||||
<img src="assets/nanoclaw-logo.png" alt="Regolith" width="400">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
My personal Claude assistant that runs securely in containers. Lightweight and built to be understood and customized for your own needs.
|
||||
Personal AI assistant with multi-channel messaging (WhatsApp + Discord) and multi-runtime backends (Claude Agent SDK + OpenCode). Lightweight, secure, runs agents in containers.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<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>
|
||||
<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>
|
||||
</p>
|
||||
|
||||
**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.
|
||||
## What Is Regolith
|
||||
|
||||
## Why I Built This
|
||||
Regolith is a fork of [NanoClaw](https://github.com/gavrielc/nanoclaw) extended with:
|
||||
|
||||
[OpenClaw](https://github.com/openclaw/openclaw) is an impressive project with a great vision. But I can't sleep well running software I don't understand with access to my life. OpenClaw has 52+ modules, 8 config management files, 45+ dependencies, and abstractions for 15 channel providers. Security is application-level (allowlists, pairing codes) rather than OS isolation. Everything runs in one Node process with shared memory.
|
||||
- **Discord channel support** — Talk to your AI assistant through Discord DMs and guild channels alongside WhatsApp
|
||||
- **OpenCode runtime** — Use OpenCode as an alternative AI agent backend (CLI or SDK mode) with persistent session management
|
||||
- **Multi-channel architecture** — Run WhatsApp-only, Discord-only, or both simultaneously via environment variables
|
||||
|
||||
NanoClaw gives you the same core functionality in a codebase you can understand in 8 minutes. One process. A handful of files. Agents run in actual Linux containers with filesystem isolation, not behind permission checks.
|
||||
The core philosophy remains the same: small enough to understand, secure by container isolation, built for one user.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
git clone https://github.com/gavrielc/nanoclaw.git
|
||||
cd nanoclaw
|
||||
claude
|
||||
git clone http://10.0.0.59:3051/tanmay/Regolith.git
|
||||
cd Regolith/nanoclaw
|
||||
npm install
|
||||
```
|
||||
|
||||
Then run `/setup`. Claude Code handles everything: dependencies, authentication, container setup, service configuration.
|
||||
Configure your `.env`:
|
||||
```bash
|
||||
# WhatsApp (enabled by default)
|
||||
ASSISTANT_NAME=Andy
|
||||
|
||||
## Philosophy
|
||||
# Discord (optional — set token to enable)
|
||||
DISCORD_BOT_TOKEN=your-discord-bot-token
|
||||
DISCORD_ONLY=false # set to true to disable WhatsApp
|
||||
|
||||
**Small enough to understand.** One process, a few source files. No microservices, no message queues, no abstraction layers. Have Claude Code walk you through it.
|
||||
# OpenCode runtime (optional)
|
||||
OPENCODE_MODE=cli # or "sdk"
|
||||
OPENCODE_MODEL=claude # model name
|
||||
OPENCODE_TIMEOUT=120 # seconds
|
||||
OPENCODE_SESSION_TTL_HOURS=24
|
||||
```
|
||||
|
||||
**Secure by isolation.** Agents run in Linux containers (Apple Container on macOS, or Docker). They can only see what's explicitly mounted. Bash access is safe because commands run inside the container, not on your host.
|
||||
Then run:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
**Built for one user.** This isn't a framework. It's working software that fits my exact needs. You fork it and have Claude Code make it match your exact needs.
|
||||
## Architecture
|
||||
|
||||
**Customization = code changes.** No configuration sprawl. Want different behavior? Modify the code. The codebase is small enough that this is safe.
|
||||
```
|
||||
WhatsApp (baileys) ──┐
|
||||
├──> SQLite ──> Polling loop ──> Container (Claude Agent SDK) ──> Response
|
||||
Discord (discord.js)─┘ └──> OpenCode Runtime (CLI/SDK) ──> Response
|
||||
```
|
||||
|
||||
**AI-native.** No installation wizard; Claude Code guides setup. No monitoring dashboard; ask Claude what's happening. No debugging tools; describe the problem, Claude fixes it.
|
||||
Single Node.js process. Multiple messaging channels route through a shared pipeline. Agents execute in isolated Linux containers or via OpenCode subprocess/HTTP.
|
||||
|
||||
**Skills over features.** Contributors shouldn't add features (e.g. support for Telegram) to the codebase. Instead, they contribute [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.
|
||||
### Channel Routing
|
||||
|
||||
**Best harness, best model.** This runs on Claude Agent SDK, which means you're running Claude Code directly. The harness matters. A bad harness makes even smart models seem dumb, a good harness gives them superpowers. Claude Code is (IMO) the best harness available.
|
||||
Messages are routed by JID prefix:
|
||||
- WhatsApp JIDs: phone-number format (e.g., `1234567890@s.whatsapp.net`)
|
||||
- Discord JIDs: `dc:` prefix (e.g., `dc:1234567890123456`)
|
||||
|
||||
The `findChannel(channels, jid)` function resolves which channel owns a given JID.
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/index.ts` | Orchestrator: multi-channel setup, state, message loop, agent invocation |
|
||||
| `src/channels/whatsapp.ts` | WhatsApp connection, auth, send/receive |
|
||||
| `src/channels/discord.ts` | Discord bot connection, mention handling, attachment tagging |
|
||||
| `src/channels/chunk-text.ts` | Message chunking utility (2000-char Discord limit) |
|
||||
| `src/router.ts` | Message formatting, outbound routing, `findChannel` |
|
||||
| `src/config.ts` | Environment config (trigger pattern, Discord token, paths) |
|
||||
| `src/opencode/runtime.ts` | OpenCode AI backend (CLI + SDK modes) |
|
||||
| `src/opencode/session-store.ts` | SQLite-backed session persistence |
|
||||
| `src/opencode/live-sessions.ts` | In-memory session manager with idle cleanup |
|
||||
| `src/opencode/types.ts` | OpenCode type definitions |
|
||||
| `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 (isolated) |
|
||||
|
||||
## Discord Setup
|
||||
|
||||
1. Create a Discord bot at [discord.com/developers](https://discord.com/developers/applications)
|
||||
2. Enable the following intents: Guilds, Guild Messages, Message Content, Direct Messages
|
||||
3. Set `DISCORD_BOT_TOKEN` in your `.env`
|
||||
4. Invite the bot to your server with message read/write permissions
|
||||
5. Register Discord channels the same way you register WhatsApp groups
|
||||
|
||||
The bot responds to @mentions in guild channels and all DMs. Messages with attachments include type-tagged placeholders (`[Image: name]`, `[Video: name]`, etc.). Reply context is preserved as `[Reply to AuthorName]`.
|
||||
|
||||
## OpenCode Runtime
|
||||
|
||||
The OpenCode runtime provides an alternative AI backend:
|
||||
|
||||
- **CLI mode** (default): Spawns `opencode run` subprocesses with model, session, and system prompt args
|
||||
- **SDK mode**: Sends HTTP requests to an `opencode serve` endpoint
|
||||
|
||||
Sessions are persisted in SQLite and tracked in memory with idle timeout cleanup (default 30 min). Empty/whitespace messages are rejected immediately. All errors are caught and returned as structured `AgentResponse` objects.
|
||||
|
||||
## What It Supports
|
||||
|
||||
- **WhatsApp I/O** - Message Claude from your phone
|
||||
- **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
|
||||
- **Main channel** - Your private channel (self-chat) for admin control; every other group is completely isolated
|
||||
- **Scheduled tasks** - Recurring jobs that run Claude and can message you back
|
||||
- **Web access** - Search and fetch content
|
||||
- **Container isolation** - Agents sandboxed in Apple Container (macOS) or Docker (macOS/Linux)
|
||||
- **Agent Swarms** - Spin up teams of specialized agents that collaborate on complex tasks (first personal AI assistant to support this)
|
||||
- **Optional integrations** - Add Gmail (`/add-gmail`) and more via skills
|
||||
- **WhatsApp I/O** — Message your assistant from your phone
|
||||
- **Discord I/O** — Message your assistant from Discord (DMs and guild channels)
|
||||
- **Multi-channel** — Run WhatsApp + Discord simultaneously, or either alone
|
||||
- **OpenCode backend** — Alternative AI runtime with CLI and SDK modes
|
||||
- **Isolated group context** — Each group has its own memory and container sandbox
|
||||
- **Scheduled tasks** — Recurring jobs that run agents and message you back
|
||||
- **Container isolation** — Agents sandboxed in Apple Container (macOS) or Docker
|
||||
- **Agent Swarms** — Teams of specialized agents that collaborate on tasks
|
||||
- **Skills system** — Add capabilities via Claude Code 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
|
||||
@Andy send an overview of the sales pipeline every weekday morning at 9am
|
||||
@Andy review the git history for the past week each Friday
|
||||
@Andy every Monday at 8am, compile AI news from Hacker News
|
||||
```
|
||||
|
||||
From the main channel (your self-chat), you can manage groups and tasks:
|
||||
On Discord, @mention the bot:
|
||||
```
|
||||
@Andy list all scheduled tasks across groups
|
||||
@Andy pause the Monday briefing task
|
||||
@Andy join the Family Chat group
|
||||
@YourBot what's the status of the project?
|
||||
@YourBot summarize the last 10 messages in this channel
|
||||
```
|
||||
|
||||
## Customizing
|
||||
|
||||
There are no configuration files to learn. Just tell Claude Code what you want:
|
||||
Tell Claude Code what you want:
|
||||
|
||||
- "Change the trigger word to @Bob"
|
||||
- "Remember in the future to make responses shorter and more direct"
|
||||
- "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.
|
||||
|
||||
## Skills System CLI (Experimental)
|
||||
|
||||
The new deterministic skills-system primitives are available as local commands:
|
||||
|
||||
```bash
|
||||
npm run skills:init -- --core-version 0.5.0 --base-source .
|
||||
npm run skills:apply -- --skill whatsapp --version 1.2.0 --files-modified src/server.ts
|
||||
npm run skills:update-preview
|
||||
npm run skills:update-stage -- --target-core-version 0.6.0 --base-source /path/to/new/core
|
||||
npm run skills:update-commit
|
||||
# or: npm run skills:update-rollback
|
||||
```
|
||||
|
||||
These commands operate on `.nanoclaw/state.yaml`, `.nanoclaw/state.next.yaml`, `.nanoclaw/base/`, `.nanoclaw/base.next/`, and `.nanoclaw/backup/`.
|
||||
|
||||
## 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 love to see:
|
||||
|
||||
**Communication Channels**
|
||||
- `/add-telegram` - Add Telegram as channel. Should give the user option to replace WhatsApp or add as additional channel. Also should be possible to add it as a control channel (where it can trigger actions) or just a channel that can be used in actions triggered elsewhere
|
||||
- `/add-slack` - Add Slack
|
||||
- `/add-discord` - Add Discord
|
||||
|
||||
**Platform Support**
|
||||
- `/setup-windows` - Windows via WSL2 + Docker
|
||||
|
||||
**Session Management**
|
||||
- `/add-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
|
||||
- macOS or Linux (Windows via WSL2)
|
||||
- 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
|
||||
|
||||
```
|
||||
WhatsApp (baileys) --> SQLite --> Polling loop --> Container (Claude Agent SDK) --> Response
|
||||
```
|
||||
|
||||
Single Node.js process. Agents execute in isolated Linux containers with mounted directories. Per-group message queue with concurrency control. IPC via filesystem.
|
||||
|
||||
Key files:
|
||||
- `src/index.ts` - Orchestrator: state, message loop, agent invocation
|
||||
- `src/channels/whatsapp.ts` - WhatsApp connection, auth, send/receive
|
||||
- `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 WhatsApp and not Telegram/Signal/etc?**
|
||||
|
||||
Because I use WhatsApp. Fork it and run a skill to change it. That's the whole point.
|
||||
|
||||
**Why Apple Container instead of Docker?**
|
||||
|
||||
On macOS, Apple Container is lightweight, fast, and optimized for Apple silicon. But Docker is also fully supported—during `/setup`, you can choose which runtime to use. On Linux, Docker is used automatically.
|
||||
|
||||
**Can I run this on Linux?**
|
||||
|
||||
Yes. Run `/setup` and it will automatically configure Docker as the container runtime. Thanks to [@dotsetgreg](https://github.com/dotsetgreg) for contributing the `/convert-to-docker` skill.
|
||||
|
||||
**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 it to so that the code matches exactly what they want rather than configuring a generic system. If you like having config files, tell Claude to add them.
|
||||
|
||||
**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.
|
||||
|
||||
**Why isn't the setup working for me?**
|
||||
|
||||
I don't know. 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?**
|
||||
|
||||
Security fixes, bug fixes, and clear improvements to the base configuration. That's it.
|
||||
|
||||
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).
|
||||
- [Apple Container](https://github.com/apple/container) (macOS) or [Docker](https://docker.com/products/docker-desktop)
|
||||
- Discord bot token (for Discord channel)
|
||||
- OpenCode binary (for OpenCode runtime, optional)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user