- Interactive setup wizard: deps check, env config, WhatsApp auth, daemon install, health check - CLI entry point via yargs with bin registration (regolith onboard) - Flags: --install-daemon, --non-interactive, --pairing-code, --json, --skip-* - launchd (macOS) and systemd (Linux) service installation - Refactored whatsapp-auth.ts to export authenticate() for programmatic use - 72 tests across 6 test files - Updated README.md and CLAUDE.md with onboard CLI docs
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 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
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:
regolith onboard --install-daemon
For non-interactive setup (CI/scripting):
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:
# 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:
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
- Create a Discord bot at discord.com/developers
- Enable the following intents: Guilds, Guild Messages, Message Content, Direct Messages
- Set
DISCORD_BOT_TOKENin your.env - Invite the bot to your server with message read/write permissions
- 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 runsubprocesses with model, session, and system prompt args - SDK mode: Sends HTTP requests to an
opencode serveendpoint
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 (macOS) or Docker
- Discord bot token (for Discord channel)
- OpenCode binary (for OpenCode runtime, optional)
License
MIT
