Personal AI assistant with multi-channel messaging (WhatsApp + Discord) and multi-runtime backends (Claude Agent SDK + OpenCode). Lightweight, secure, runs agents in containers.
中文 •
## What Is Regolith
Regolith is a fork of [NanoClaw](https://github.com/gavrielc/nanoclaw) extended with:
- **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
The core philosophy remains the same: small enough to understand, secure by container isolation, built for one user.
## Quick Start
```bash
git clone http://10.0.0.59:3051/tanmay/Regolith.git
cd Regolith/nanoclaw
npm install
npm run build
regolith onboard
```
The onboard wizard walks you through everything: dependency checks, `.env` configuration, WhatsApp authentication, and optional daemon installation.
To install as a background service in one shot:
```bash
regolith onboard --install-daemon
```
For non-interactive setup (CI/scripting):
```bash
regolith onboard --non-interactive --install-daemon
```
### Onboard CLI Flags
| Flag | Description |
|------|-------------|
| `--install-daemon` | Install as launchd (macOS) or systemd (Linux) service |
| `--non-interactive` | Run without prompts, use defaults |
| `--pairing-code` | Use pairing code instead of QR for WhatsApp |
| `--json` | Output JSON summary instead of text |
| `--skip-deps` | Skip dependency checks |
| `--skip-env` | Skip .env configuration |
| `--skip-whatsapp` | Skip WhatsApp authentication |
| `--skip-health` | Skip health check |
### Manual Setup
If you prefer to configure manually instead of using the wizard:
Configure your `.env`:
```bash
# WhatsApp (enabled by default)
ASSISTANT_NAME=Andy
# Discord (optional — set token to enable)
DISCORD_BOT_TOKEN=your-discord-bot-token
DISCORD_ONLY=false # set to true to disable WhatsApp
# Agent backend: "container" (Claude Agent SDK) or "opencode"
AGENT_BACKEND=container
# OpenCode runtime (optional, used when AGENT_BACKEND=opencode)
OPENCODE_MODE=cli # or "sdk"
OPENCODE_MODEL=claude # model name
OPENCODE_TIMEOUT=120 # seconds
OPENCODE_SESSION_TTL_HOURS=24
```
Then run:
```bash
npm run dev
```
## Architecture
```
WhatsApp (baileys) ──┐
├──> SQLite ──> Polling loop ──> Container (Claude Agent SDK) ──> Response
Discord (discord.js)─┘ └──> OpenCode Runtime (CLI/SDK) ──> Response
```
Single Node.js process. Multiple messaging channels route through a shared pipeline. Agents execute in isolated Linux containers or via OpenCode subprocess/HTTP.
### Channel Routing
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/cli/index.ts` | CLI entry point (`regolith onboard`) |
| `src/cli/wizard-runner.ts` | Onboard wizard step orchestrator |
| `src/cli/steps/*.ts` | Individual wizard steps (deps, env, whatsapp, daemon, health) |
| `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 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
@Andy review the git history for the past week each Friday
@Andy every Monday at 8am, compile AI news from Hacker News
```
On Discord, @mention the bot:
```
@YourBot what's the status of the project?
@YourBot summarize the last 10 messages in this channel
```
## Customizing
Tell Claude Code what you want:
- "Change the trigger word to @Bob"
- "Make responses shorter and more direct"
- "Add a custom greeting when I say good morning"
Or run `/customize` for guided changes.
## Requirements
- macOS or Linux (Windows via WSL2)
- Node.js 20+
- [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
MIT