This commit is contained in:
Davendra Patel 2026-01-29 19:56:03 +01:00 committed by GitHub
commit c83ef2b0f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 85 additions and 3 deletions

View File

@ -1,7 +1,25 @@
# Repository Guidelines # CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Repo: https://github.com/moltbot/moltbot - Repo: https://github.com/moltbot/moltbot
- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n". - GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n".
## Architecture Overview
Moltbot is a local-first personal AI assistant that bridges messaging channels to AI agents.
**Message flow:** Inbound message (WhatsApp, Telegram, Slack, etc.) → Gateway WebSocket server (`src/gateway/server.ts`) → Channel plugin routes message → Pi agent runtime (`src/agents/pi-embedded-runner.ts`) executes tools (browser, bash, canvas, etc.) via gateway RPC → Final reply sent back through channel's outbound adapter.
**Key subsystems:**
- **Gateway** (`src/gateway/`): WebSocket control plane. Hosts sessions, routes messages, serves the Control UI, and exposes RPC methods for agent tool calls. Config is YAML-based (`~/.clawdbot/config.yaml`), hot-reloaded via chokidar.
- **Agents** (`src/agents/`): Pi agent runtime. Manages LLM provider config, auth profiles, tool definitions, sandbox execution, and skill loading. Sessions are isolated per-agent/group as JSONL files under `~/.clawdbot/sessions/`.
- **Channel plugins** (`src/channels/plugins/`): Unified `ChannelPlugin` interface with `inbound` (receive) and `outbound` (send) adapters. Core channels live in `src/` (discord, telegram, slack, signal, imessage, web/WhatsApp). Extension channels live in `extensions/*` as workspace packages.
- **Dependency injection** (`src/cli/deps.ts`): `createDefaultDeps()` wires all channel send functions and services. Used throughout for testability.
- **Plugin registry** (`src/plugins/runtime.ts`): Channels and extensions are runtime-registered (not statically imported). Access via `getActivePluginRegistry()`.
**Apps:** macOS menu bar (SwiftUI, `apps/macos/`), iOS (`apps/ios/`), Android (Kotlin, `apps/android/`), shared Swift code in `apps/shared/MoltbotKit/`.
## Project Structure & Module Organization ## Project Structure & Module Organization
- Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`). - Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`).
- Tests: colocated `*.test.ts`. - Tests: colocated `*.test.ts`.
@ -47,6 +65,7 @@
- Type-check/build: `pnpm build` (tsc) - Type-check/build: `pnpm build` (tsc)
- Lint/format: `pnpm lint` (oxlint), `pnpm format` (oxfmt) - Lint/format: `pnpm lint` (oxlint), `pnpm format` (oxfmt)
- Tests: `pnpm test` (vitest); coverage: `pnpm test:coverage` - Tests: `pnpm test` (vitest); coverage: `pnpm test:coverage`
- Run a single test file: `pnpm test -- src/path/to/file.test.ts`
## Coding Style & Naming Conventions ## Coding Style & Naming Conventions
- Language: TypeScript (ESM). Prefer strict typing; avoid `any`. - Language: TypeScript (ESM). Prefer strict typing; avoid `any`.

View File

@ -1,7 +1,7 @@
# 🦞 Moltbot — Personal AI Assistant # 🦞 Moltbot — Personal AI Assistant
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/moltbot/moltbot/main/docs/whatsapp-clawd.jpg" alt="Clawdbot" width="400"> <img src="https://raw.githubusercontent.com/davendra/moltbot/main/docs/images/diagrams/30-hero-banner.png" alt="Moltbot — Your AI Agent, Everywhere You Message" width="800">
</p> </p>
<p align="center"> <p align="center">
@ -52,6 +52,8 @@ moltbot onboard --install-daemon
The wizard installs the Gateway daemon (launchd/systemd user service) so it stays running. The wizard installs the Gateway daemon (launchd/systemd user service) so it stays running.
Legacy note: `clawdbot` remains available as a compatibility shim. Legacy note: `clawdbot` remains available as a compatibility shim.
![Moltbot Architecture Overview](https://raw.githubusercontent.com/davendra/moltbot/main/docs/images/diagrams/27-readme-architecture.png)
## Quick start (TL;DR) ## Quick start (TL;DR)
Runtime: **Node ≥22**. Runtime: **Node ≥22**.

View File

@ -15,6 +15,8 @@ the right time, and can optionally deliver output back to a chat.
If you want *“run this every morning”* or *“poke the agent in 20 minutes”*, If you want *“run this every morning”* or *“poke the agent in 20 minutes”*,
cron is the mechanism. cron is the mechanism.
![Cron Job Execution Paths](/images/diagrams/09-cron-jobs.png)
## TL;DR ## TL;DR
- Cron runs **inside the Gateway** (not inside the model). - Cron runs **inside the Gateway** (not inside the model).
- Jobs persist under `~/.clawdbot/cron/` so restarts dont lose schedules. - Jobs persist under `~/.clawdbot/cron/` so restarts dont lose schedules.

View File

@ -9,6 +9,8 @@ read_when:
Gateway can expose a small HTTP webhook endpoint for external triggers. Gateway can expose a small HTTP webhook endpoint for external triggers.
![Webhook Processing Flow](/images/diagrams/10-webhook.png)
## Enable ## Enable
```json5 ```json5

View File

@ -17,6 +17,8 @@ Broadcast Groups enable multiple agents to process and respond to the same messa
Current scope: **WhatsApp only** (web channel). Current scope: **WhatsApp only** (web channel).
![Broadcast Group Flow](/images/diagrams/14-broadcast.png)
Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, this means broadcasts happen when Moltbot would normally reply (for example: on mention, depending on your group settings). Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, this means broadcasts happen when Moltbot would normally reply (for example: on mention, depending on your group settings).
## Use Cases ## Use Cases

View File

@ -13,6 +13,8 @@ In Moltbot, a loop is a single, serialized run per session that emits lifecycle
as the model thinks, calls tools, and streams output. This doc explains how that authentic loop is as the model thinks, calls tools, and streams output. This doc explains how that authentic loop is
wired end-to-end. wired end-to-end.
![Agent Loop Lifecycle](/images/diagrams/02-agent-loop.png)
## Entry points ## Entry points
- Gateway RPC: `agent` and `agent.wait`. - Gateway RPC: `agent` and `agent.wait`.
- CLI: `agent` command. - CLI: `agent` command.
@ -80,6 +82,8 @@ These run inside the agent loop or gateway pipeline:
See [Plugins](/plugin#plugin-hooks) for the hook API and registration details. See [Plugins](/plugin#plugin-hooks) for the hook API and registration details.
![Plugin Hooks Lifecycle](/images/diagrams/20-plugin-hooks.png)
## Streaming + partial replies ## Streaming + partial replies
- Assistant deltas are streamed from pi-agent-core and emitted as `assistant` events. - Assistant deltas are streamed from pi-agent-core and emitted as `assistant` events.
- Block streaming can emit partial replies either on `text_end` or `message_end`. - Block streaming can emit partial replies either on `text_end` or `message_end`.

View File

@ -9,6 +9,8 @@ read_when:
The workspace is the agent's home. It is the only working directory used for The workspace is the agent's home. It is the only working directory used for
file tools and for workspace context. Keep it private and treat it as memory. file tools and for workspace context. Keep it private and treat it as memory.
![Agent Workspace Structure](/images/diagrams/26-workspace.png)
This is separate from `~/.clawdbot/`, which stores config, credentials, and This is separate from `~/.clawdbot/`, which stores config, credentials, and
sessions. sessions.

View File

@ -21,6 +21,8 @@ Last updated: 2026-01-22
## Components and flows ## Components and flows
![Architecture Overview](/images/diagrams/01-architecture.png)
### Gateway (daemon) ### Gateway (daemon)
- Maintains provider connections. - Maintains provider connections.
- Exposes a typed WS API (requests, responses, serverpush events). - Exposes a typed WS API (requests, responses, serverpush events).

View File

@ -51,6 +51,8 @@ Routing picks **one agent** for each inbound message:
The matched agent determines which workspace and session store are used. The matched agent determines which workspace and session store are used.
![Channel Routing Priority Cascade](/images/diagrams/05-channel-routing.png)
## Broadcast groups (run multiple agents) ## Broadcast groups (run multiple agents)
Broadcast groups let you run **multiple agents** for the same peer **when Moltbot would normally reply** (for example: in WhatsApp groups, after mention/activation gating). Broadcast groups let you run **multiple agents** for the same peer **when Moltbot would normally reply** (for example: in WhatsApp groups, after mention/activation gating).
@ -69,6 +71,8 @@ Config:
See: [Broadcast Groups](/broadcast-groups). See: [Broadcast Groups](/broadcast-groups).
![Broadcast vs Normal Routing](/images/diagrams/29-broadcast-vs-normal.png)
## Config overview ## Config overview
- `agents.list`: named agent definitions (workspace, model, etc.). - `agents.list`: named agent definitions (workspace, model, etc.).

View File

@ -8,6 +8,8 @@ read_when:
Every model has a **context window** (max tokens it can see). Long-running chats accumulate messages and tool results; once the window is tight, Moltbot **compacts** older history to stay within limits. Every model has a **context window** (max tokens it can see). Long-running chats accumulate messages and tool results; once the window is tight, Moltbot **compacts** older history to stay within limits.
![Context Compaction Flow](/images/diagrams/11-compaction.png)
## What compaction is ## What compaction is
Compaction **summarizes older conversation** into a compact summary entry and keeps recent messages intact. The summary is stored in the session history, so future requests use: Compaction **summarizes older conversation** into a compact summary entry and keeps recent messages intact. The summary is stored in the session history, so future requests use:
- The compaction summary - The compaction summary

View File

@ -9,6 +9,8 @@ read_when:
Moltbot memory is **plain Markdown in the agent workspace**. The files are the Moltbot memory is **plain Markdown in the agent workspace**. The files are the
source of truth; the model only "remembers" what gets written to disk. source of truth; the model only "remembers" what gets written to disk.
![Memory Organization](/images/diagrams/12-memory.png)
Memory search tools are provided by the active memory plugin (default: Memory search tools are provided by the active memory plugin (default:
`memory-core`). Disable memory plugins with `plugins.slots.memory = "none"`. `memory-core`). Disable memory plugins with `plugins.slots.memory = "none"`.

View File

@ -20,6 +20,8 @@ Inbound message
-> outbound replies (channel limits + chunking) -> outbound replies (channel limits + chunking)
``` ```
![Message Processing Flow](/images/diagrams/03-message-flow.png)
Key knobs live in configuration: Key knobs live in configuration:
- `messages.*` for prefixes, queueing, and group behavior. - `messages.*` for prefixes, queueing, and group behavior.
- `agents.defaults.*` for block streaming and chunking defaults. - `agents.defaults.*` for block streaming and chunking defaults.

View File

@ -13,6 +13,8 @@ Moltbot handles failures in two stages:
This doc explains the runtime rules and the data that backs them. This doc explains the runtime rules and the data that backs them.
![Model Failover Decision Tree](/images/diagrams/17-model-failover.png)
## Auth storage (keys + OAuth) ## Auth storage (keys + OAuth)
Moltbot uses **auth profiles** for both API keys and OAuth tokens. Moltbot uses **auth profiles** for both API keys and OAuth tokens.

View File

@ -9,7 +9,9 @@ status: active
Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple channel accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings. Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple channel accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings.
## What is “one agent”? ![Multi-Agent Isolation](/images/diagrams/06-multi-agent.png)
## What is "one agent"?
An **agent** is a fully scoped brain with its own: An **agent** is a fully scoped brain with its own:

View File

@ -7,6 +7,8 @@ read_when:
We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions. We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions.
![Lane-Aware FIFO Queue](/images/diagrams/07-queue-lanes.png)
## Why ## Why
- Auto-reply runs can be expensive (LLM calls) and can collide when multiple inbound messages arrive close together. - Auto-reply runs can be expensive (LLM calls) and can collide when multiple inbound messages arrive close together.
- Serializing avoids competing for shared resources (session files, logs, CLI stdin) and reduces the chance of upstream rate limits. - Serializing avoids competing for shared resources (session files, logs, CLI stdin) and reduces the chance of upstream rate limits.
@ -27,6 +29,8 @@ Inbound messages can steer the current run, wait for a followup turn, or do both
- `interrupt` (legacy): abort the active run for that session, then run the newest message. - `interrupt` (legacy): abort the active run for that session, then run the newest message.
- `queue` (legacy alias): same as `steer`. - `queue` (legacy alias): same as `steer`.
![Queue Modes State Machine](/images/diagrams/08-queue-modes.png)
Steer-backlog means you can get a followup response after the steered run, so Steer-backlog means you can get a followup response after the steered run, so
streaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want streaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want
one response per inbound message. one response per inbound message.

View File

@ -7,6 +7,8 @@ read_when:
Moltbot treats **one direct-chat session per agent** as primary. Direct chats collapse to `agent:<agentId>:<mainKey>` (default `main`), while group/channel chats get their own keys. `session.mainKey` is honored. Moltbot treats **one direct-chat session per agent** as primary. Direct chats collapse to `agent:<agentId>:<mainKey>` (default `main`), while group/channel chats get their own keys. `session.mainKey` is honored.
![Session Lifecycle](/images/diagrams/28-session-lifecycle.png)
Use `session.dmScope` to control how **direct messages** are grouped: Use `session.dmScope` to control how **direct messages** are grouped:
- `main` (default): all DMs share the main session for continuity. - `main` (default): all DMs share the main session for continuity.
- `per-peer`: isolate by sender id across channels. - `per-peer`: isolate by sender id across channels.

View File

@ -13,6 +13,8 @@ Moltbot has two separate “streaming” layers:
There is **no real token streaming** to external channel messages today. Telegram draft streaming is the only partial-stream surface. There is **no real token streaming** to external channel messages today. Telegram draft streaming is the only partial-stream surface.
![Streaming Delivery Paths](/images/diagrams/13-streaming.png)
## Block streaming (channel messages) ## Block streaming (channel messages)
Block streaming sends assistant output in coarse chunks as it becomes available. Block streaming sends assistant output in coarse chunks as it becomes available.

View File

@ -9,6 +9,9 @@ Last updated: 2025-12-09
## What it is ## What it is
- The always-on process that owns the single Baileys/Telegram connection and the control/event plane. - The always-on process that owns the single Baileys/Telegram connection and the control/event plane.
![Gateway Lifecycle States](/images/diagrams/23-gateway-lifecycle.png)
- Replaces the legacy `gateway` command. CLI entry point: `moltbot gateway`. - Replaces the legacy `gateway` command. CLI entry point: `moltbot gateway`.
- Runs until stopped; exits non-zero on fatal errors so the supervisor restarts it. - Runs until stopped; exits non-zero on fatal errors so the supervisor restarts it.
@ -22,6 +25,8 @@ moltbot gateway --force
# dev loop (auto-reload on TS changes): # dev loop (auto-reload on TS changes):
pnpm gateway:watch pnpm gateway:watch
``` ```
![Config Hot-Reload](/images/diagrams/24-hot-reload.png)
- Config hot reload watches `~/.clawdbot/moltbot.json` (or `CLAWDBOT_CONFIG_PATH`). - Config hot reload watches `~/.clawdbot/moltbot.json` (or `CLAWDBOT_CONFIG_PATH`).
- Default mode: `gateway.reload.mode="hybrid"` (hot-apply safe changes, restart on critical). - Default mode: `gateway.reload.mode="hybrid"` (hot-apply safe changes, restart on critical).
- Hot reload uses in-process restart via **SIGUSR1** when needed. - Hot reload uses in-process restart via **SIGUSR1** when needed.

View File

@ -18,6 +18,8 @@ handshake time.
- WebSocket, text frames with JSON payloads. - WebSocket, text frames with JSON payloads.
- First frame **must** be a `connect` request. - First frame **must** be a `connect` request.
![Gateway WebSocket Protocol](/images/diagrams/04-ws-protocol.png)
## Handshake (connect) ## Handshake (connect)
Gateway → Client (pre-connect challenge): Gateway → Client (pre-connect challenge):

View File

@ -5,6 +5,8 @@ read_when:
--- ---
# Security 🔒 # Security 🔒
![Security Trust Hierarchy](/images/diagrams/31-security-threat-model.png)
## Quick check: `moltbot security audit` (formerly `clawdbot security audit`) ## Quick check: `moltbot security audit` (formerly `clawdbot security audit`)
See also: [Formal Verification (Security Models)](/security/formal-verification/) See also: [Formal Verification (Security Models)](/security/formal-verification/)
@ -35,6 +37,8 @@ Moltbot is both a product and an experiment: youre wiring frontier-model beha
Start with the smallest access that still works, then widen it as you gain confidence. Start with the smallest access that still works, then widen it as you gain confidence.
![Three-Layer Security Model](/images/diagrams/15-security.png)
### What the audit checks (high level) ### What the audit checks (high level)
- **Inbound access** (DM policies, group policies, allowlists): can strangers trigger the bot? - **Inbound access** (DM policies, group policies, allowlists): can strangers trigger the bot?

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

View File

@ -9,6 +9,8 @@ read_when:
Use the installer unless you have a reason not to. It sets up the CLI and runs onboarding. Use the installer unless you have a reason not to. It sets up the CLI and runs onboarding.
![Installation Decision Tree](/images/diagrams/25-install.png)
## Quick install (recommended) ## Quick install (recommended)
```bash ```bash

View File

@ -112,6 +112,8 @@ manifest.
If multiple plugins resolve to the same id, the first match in the order above If multiple plugins resolve to the same id, the first match in the order above
wins and lower-precedence copies are ignored. wins and lower-precedence copies are ignored.
![Plugin Discovery Precedence](/images/diagrams/19-plugin-discovery.png)
### Package packs ### Package packs
A plugin directory may include a `package.json` with `moltbot.extensions`: A plugin directory may include a `package.json` with `moltbot.extensions`:

View File

@ -7,8 +7,12 @@ read_when:
# Getting Started # Getting Started
![5 Minutes to First Message](/images/diagrams/32-getting-started-timeline.png)
Goal: go from **zero****first working chat** (with sane defaults) as quickly as possible. Goal: go from **zero****first working chat** (with sane defaults) as quickly as possible.
![Getting Started: Onboarding Wizard](/images/diagrams/22-onboarding.png)
Fastest chat: open the Control UI (no channel setup needed). Run `moltbot dashboard` Fastest chat: open the Control UI (no channel setup needed). Run `moltbot dashboard`
and chat in the browser, or open `http://127.0.0.1:18789/` on the gateway host. and chat in the browser, or open `http://127.0.0.1:18789/` on the gateway host.
Docs: [Dashboard](/web/dashboard) and [Control UI](/web/control-ui). Docs: [Dashboard](/web/dashboard) and [Control UI](/web/control-ui).

View File

@ -14,6 +14,8 @@ It is used in two places:
1) **DM pairing** (who is allowed to talk to the bot) 1) **DM pairing** (who is allowed to talk to the bot)
2) **Node pairing** (which devices/nodes are allowed to join the gateway network) 2) **Node pairing** (which devices/nodes are allowed to join the gateway network)
![Pairing Flows](/images/diagrams/16-pairing.png)
Security context: [Security](/gateway/security) Security context: [Security](/gateway/security)
## 1) DM pairing (inbound chat access) ## 1) DM pairing (inbound chat access)

View File

@ -321,6 +321,8 @@ High-level flow:
This design keeps the agent on a stable, deterministic interface while letting This design keeps the agent on a stable, deterministic interface while letting
you swap local/remote browsers and profiles. you swap local/remote browsers and profiles.
![Browser Automation Flow](/images/diagrams/21-browser.png)
## CLI quick reference ## CLI quick reference
All commands accept `--browser-profile <name>` to target a specific profile. All commands accept `--browser-profile <name>` to target a specific profile.

View File

@ -11,6 +11,8 @@ Moltbot exposes **first-class agent tools** for browser, canvas, nodes, and cron
These replace the old `moltbot-*` skills: the tools are typed, no shelling, These replace the old `moltbot-*` skills: the tools are typed, no shelling,
and the agent should rely on them directly. and the agent should rely on them directly.
![Tool Groups](/images/diagrams/18-tool-groups.png)
## Disabling tools ## Disabling tools
You can globally allow/deny tools via `tools.allow` / `tools.deny` in `moltbot.json` You can globally allow/deny tools via `tools.allow` / `tools.deny` in `moltbot.json`