Merge branch 'main' into nanogpt

This commit is contained in:
0xGingi authored and GitHub committed 2026-01-28 05:15:36 -05:00
commit 124e0038d6
642 files changed
+2988 -979

No files matched your search

+1 -1
View File
@@ -42,7 +42,7 @@ moltbot acp client
moltbot acp client --server-args --url wss://gateway-host:18789 --token <token>
# Override the server command (default: moltbot)
moltbot acp client --server "node" --server-args dist/entry.js acp --url ws://127.0.0.1:19001
moltbot acp client --server "node" --server-args moltbot.mjs acp --url ws://127.0.0.1:19001
```
## How to use this
+1 -1
View File
@@ -20,5 +20,5 @@ moltbot security audit --deep
moltbot security audit --fix
```
The audit warns when multiple DM senders share the main session and recommends `session.dmScope="per-channel-peer"` for shared inboxes.
The audit warns when multiple DM senders share the main session and recommends `session.dmScope="per-channel-peer"` (or `per-account-channel-peer` for multi-account channels) for shared inboxes.
It also warns when small models (`<=300B`) are used without sandboxing and with web/browser tools enabled.
+4 -3
View File
@@ -130,9 +130,10 @@ Moonshot uses OpenAI-compatible endpoints, so configure it as a custom provider:
- Provider: `moonshot`
- Auth: `MOONSHOT_API_KEY`
- Example model: `moonshot/kimi-k2-0905-preview`
- Example model: `moonshot/kimi-k2.5`
- Kimi K2 model IDs:
{/* moonshot-kimi-k2-model-refs:start */}
- `moonshot/kimi-k2.5`
- `moonshot/kimi-k2-0905-preview`
- `moonshot/kimi-k2-turbo-preview`
- `moonshot/kimi-k2-thinking`
@@ -141,7 +142,7 @@ Moonshot uses OpenAI-compatible endpoints, so configure it as a custom provider:
```json5
{
agents: {
defaults: { model: { primary: "moonshot/kimi-k2-0905-preview" } }
defaults: { model: { primary: "moonshot/kimi-k2.5" } }
},
models: {
mode: "merge",
@@ -150,7 +151,7 @@ Moonshot uses OpenAI-compatible endpoints, so configure it as a custom provider:
baseUrl: "https://api.moonshot.ai/v1",
apiKey: "${MOONSHOT_API_KEY}",
api: "openai-completions",
models: [{ id: "kimi-k2-0905-preview", name: "Kimi K2 0905 Preview" }]
models: [{ id: "kimi-k2.5", name: "Kimi K2.5" }]
}
}
}
+4 -2
View File
@@ -11,7 +11,8 @@ Use `session.dmScope` to control how **direct messages** are grouped:
- `main` (default): all DMs share the main session for continuity.
- `per-peer`: isolate by sender id across channels.
- `per-channel-peer`: isolate by channel + sender (recommended for multi-user inboxes).
Use `session.identityLinks` to map provider-prefixed peer ids to a canonical identity so the same person shares a DM session across channels when using `per-peer` or `per-channel-peer`.
- `per-account-channel-peer`: isolate by account + channel + sender (recommended for multi-account inboxes).
Use `session.identityLinks` to map provider-prefixed peer ids to a canonical identity so the same person shares a DM session across channels when using `per-peer`, `per-channel-peer`, or `per-account-channel-peer`.
## Gateway is the source of truth
All session state is **owned by the gateway** (the “master” Moltbot). UI clients (macOS app, WebChat, etc.) must query the gateway for session lists and token counts instead of reading local files.
@@ -44,6 +45,7 @@ the workspace is writable. See [Memory](/concepts/memory) and
- Multiple phone numbers and channels can map to the same agent main key; they act as transports into one conversation.
- `per-peer`: `agent:<agentId>:dm:<peerId>`.
- `per-channel-peer`: `agent:<agentId>:<channel>:dm:<peerId>`.
- `per-account-channel-peer`: `agent:<agentId>:<channel>:<accountId>:dm:<peerId>` (accountId defaults to `default`).
- If `session.identityLinks` matches a provider-prefixed peer id (for example `telegram:123`), the canonical key replaces `<peerId>` so the same person shares a session across channels.
- Group chats isolate state: `agent:<agentId>:<channel>:group:<id>` (rooms/channels use `agent:<agentId>:<channel>:channel:<id>`).
- Telegram forum topics append `:topic:<threadId>` to the group id for isolation.
@@ -94,7 +96,7 @@ Send these as standalone messages so they register.
{
session: {
scope: "per-sender", // keep group keys separate
dmScope: "main", // DM continuity (set per-channel-peer for shared inboxes)
dmScope: "main", // DM continuity (set per-channel-peer/per-account-channel-peer for shared inboxes)
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"]
},
+1 -1
View File
@@ -58,7 +58,7 @@ Authoritative list lives in `src/gateway/server.ts` (`METHODS`, `EVENTS`).
- Server handshake + method dispatch: `src/gateway/server.ts`
- Node client: `src/gateway/client.ts`
- Generated JSON Schema: `dist/protocol.schema.json`
- Generated Swift models: `apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`
- Generated Swift models: `apps/macos/Sources/MoltbotProtocol/GatewayModels.swift`
## Current pipeline
+2 -2
View File
@@ -55,9 +55,9 @@ node --import tsx scripts/repro/tsx-name-repro.ts
- Use Node + tsc watch, then run compiled output:
```bash
pnpm exec tsc --watch --preserveWatchOutput
node --watch dist/entry.js status
node --watch moltbot.mjs status
```
- Confirmed locally: `pnpm exec tsc -p tsconfig.json` + `node dist/entry.js status` works on Node 25.
- Confirmed locally: `pnpm exec tsc -p tsconfig.json` + `node moltbot.mjs status` works on Node 25.
- Disable esbuild keepNames in the TS loader if possible (prevents `__name` helper insertion); tsx does not currently expose this.
- Test Node LTS (22/24) with `tsx` to see if the issue is Node 25–specific.
+7 -6
View File
@@ -2396,8 +2396,8 @@ Use Moonshot's OpenAI-compatible endpoint:
env: { MOONSHOT_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "moonshot/kimi-k2-0905-preview" },
models: { "moonshot/kimi-k2-0905-preview": { alias: "Kimi K2" } }
model: { primary: "moonshot/kimi-k2.5" },
models: { "moonshot/kimi-k2.5": { alias: "Kimi K2.5" } }
}
},
models: {
@@ -2409,8 +2409,8 @@ Use Moonshot's OpenAI-compatible endpoint:
api: "openai-completions",
models: [
{
id: "kimi-k2-0905-preview",
name: "Kimi K2 0905 Preview",
id: "kimi-k2.5",
name: "Kimi K2.5",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -2426,7 +2426,7 @@ Use Moonshot's OpenAI-compatible endpoint:
Notes:
- Set `MOONSHOT_API_KEY` in the environment or use `moltbot onboard --auth-choice moonshot-api-key`.
- Model ref: `moonshot/kimi-k2-0905-preview`.
- Model ref: `moonshot/kimi-k2.5`.
- Use `https://api.moonshot.cn/v1` if you need the China endpoint.
### Kimi Code
@@ -2657,7 +2657,8 @@ Fields:
- `main`: all DMs share the main session for continuity.
- `per-peer`: isolate DMs by sender id across channels.
- `per-channel-peer`: isolate DMs per channel + sender (recommended for multi-user inboxes).
- `identityLinks`: map canonical ids to provider-prefixed peers so the same person shares a DM session across channels when using `per-peer` or `per-channel-peer`.
- `per-account-channel-peer`: isolate DMs per account + channel + sender (recommended for multi-account inboxes).
- `identityLinks`: map canonical ids to provider-prefixed peers so the same person shares a DM session across channels when using `per-peer`, `per-channel-peer`, or `per-account-channel-peer`.
- Example: `alice: ["telegram:123456789", "discord:987654321012345678"]`.
- `reset`: primary reset policy. Defaults to daily resets at 4:00 AM local time on the gateway host.
- `mode`: `daily` or `idle` (default: `daily` when `reset` is present).
+7 -7
View File
@@ -56,7 +56,7 @@ Usually unnecessary: one Gateway can serve multiple messaging channels and agent
Supported if you isolate state + config and use unique ports. Full guide: [Multiple gateways](/gateway/multiple-gateways).
Service names are profile-aware:
- macOS: `com.clawdbot.<profile>`
- macOS: `bot.molt.<profile>` (legacy `com.clawdbot.*` may still exist)
- Linux: `moltbot-gateway-<profile>.service`
- Windows: `Moltbot Gateway (<profile>)`
@@ -181,8 +181,8 @@ See also: [Presence](/concepts/presence) for how presence is produced/deduped an
- StandardOut/Err: file paths or `syslog`
- On failure, launchd restarts; fatal misconfig should keep exiting so the operator notices.
- LaunchAgents are per-user and require a logged-in session; for headless setups use a custom LaunchDaemon (not shipped).
- `moltbot gateway install` writes `~/Library/LaunchAgents/com.clawdbot.gateway.plist`
(or `com.clawdbot.<profile>.plist`).
- `moltbot gateway install` writes `~/Library/LaunchAgents/bot.molt.gateway.plist`
(or `bot.molt.<profile>.plist`; legacy `com.clawdbot.*` is cleaned up).
- `moltbot doctor` audits the LaunchAgent config and can update it to current defaults.
## Gateway service management (CLI)
@@ -213,11 +213,11 @@ Notes:
Bundled mac app:
- Moltbot.app can bundle a Node-based gateway relay and install a per-user LaunchAgent labeled
`com.clawdbot.gateway` (or `com.clawdbot.<profile>`).
- To stop it cleanly, use `moltbot gateway stop` (or `launchctl bootout gui/$UID/com.clawdbot.gateway`).
- To restart, use `moltbot gateway restart` (or `launchctl kickstart -k gui/$UID/com.clawdbot.gateway`).
`bot.molt.gateway` (or `bot.molt.<profile>`; legacy `com.clawdbot.*` labels still unload cleanly).
- To stop it cleanly, use `moltbot gateway stop` (or `launchctl bootout gui/$UID/bot.molt.gateway`).
- To restart, use `moltbot gateway restart` (or `launchctl kickstart -k gui/$UID/bot.molt.gateway`).
- `launchctl` only works if the LaunchAgent is installed; otherwise use `moltbot gateway install` first.
- Replace the label with `com.clawdbot.<profile>` when running a named profile.
- Replace the label with `bot.molt.<profile>` when running a named profile.
## Supervision (systemd user unit)
Moltbot installs a **systemd user service** by default on Linux/WSL2. We
+7 -5
View File
@@ -82,7 +82,7 @@ To have the SSH tunnel start automatically when you log in, create a Launch Agen
### Create the PLIST file
Save this as `~/Library/LaunchAgents/com.clawdbot.ssh-tunnel.plist`:
Save this as `~/Library/LaunchAgents/bot.molt.ssh-tunnel.plist`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
@@ -90,7 +90,7 @@ Save this as `~/Library/LaunchAgents/com.clawdbot.ssh-tunnel.plist`:
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.clawdbot.ssh-tunnel</string>
<string>bot.molt.ssh-tunnel</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/ssh</string>
@@ -108,7 +108,7 @@ Save this as `~/Library/LaunchAgents/com.clawdbot.ssh-tunnel.plist`:
### Load the Launch Agent
```bash
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.clawdbot.ssh-tunnel.plist
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/bot.molt.ssh-tunnel.plist
```
The tunnel will now:
@@ -116,6 +116,8 @@ The tunnel will now:
- Restart if it crashes
- Keep running in the background
Legacy note: remove any leftover `com.clawdbot.ssh-tunnel` LaunchAgent if present.
---
## Troubleshooting
@@ -130,13 +132,13 @@ lsof -i :18789
**Restart the tunnel:**
```bash
launchctl kickstart -k gui/$UID/com.clawdbot.ssh-tunnel
launchctl kickstart -k gui/$UID/bot.molt.ssh-tunnel
```
**Stop the tunnel:**
```bash
launchctl bootout gui/$UID/com.clawdbot.ssh-tunnel
launchctl bootout gui/$UID/bot.molt.ssh-tunnel
```
---
+63 -10
View File
@@ -1,13 +1,15 @@
---
title: Formal Verification (Security Models)
summary: Machine-checked security models for Moltbot’s highest-risk paths.
permalink: /gateway/security/formal-verification/
permalink: /security/formal-verification/
---
# Formal Verification (Security Models)
This page tracks Moltbot’s **formal security models** (TLA+/TLC today; more as needed).
> Note: some older links may refer to the previous project name.
**Goal (north star):** provide a machine-checked argument that Moltbot enforces its
intended security policy (authorization, session isolation, tool gating, and
misconfiguration safety), under explicit assumptions.
@@ -20,7 +22,7 @@ misconfiguration safety), under explicit assumptions.
## Where the models live
Models are maintained in a separate repo: [vignesh07/moltbot-formal-models](https://github.com/vignesh07/moltbot-formal-models).
Models are maintained in a separate repo: [vignesh07/clawdbot-formal-models](https://github.com/vignesh07/clawdbot-formal-models).
## Important caveats
@@ -37,8 +39,8 @@ Today, results are reproduced by cloning the models repo locally and running TLC
Getting started:
```bash
git clone https://github.com/vignesh07/moltbot-formal-models
cd moltbot-formal-models
git clone https://github.com/vignesh07/clawdbot-formal-models
cd clawdbot-formal-models
# Java 11+ required (TLC runs on the JVM).
# The repo vendors a pinned `tla2tools.jar` (TLA+ tools) and provides `bin/tlc` + Make targets.
@@ -98,10 +100,61 @@ See also: `docs/gateway-exposure-matrix.md` in the models repo.
- Red (expected):
- `make routing-isolation-negative`
## Roadmap
Next models to deepen fidelity:
- Pairing store concurrency/locking/idempotency
- Provider-specific ingress preflight modeling
- Routing identity-links + dmScope variants + binding precedence
- Gateway auth conformance (proxy/tailscale specifics)
## v1++: additional bounded models (concurrency, retries, trace correctness)
These are follow-on models that tighten fidelity around real-world failure modes (non-atomic updates, retries, and message fan-out).
### Pairing store concurrency / idempotency
**Claim:** a pairing store should enforce `MaxPending` and idempotency even under interleavings (i.e., “check-then-write” must be atomic / locked; refresh shouldn’t create duplicates).
What it means:
- Under concurrent requests, you can’t exceed `MaxPending` for a channel.
- Repeated requests/refreshes for the same `(channel, sender)` should not create duplicate live pending rows.
- Green runs:
- `make pairing-race` (atomic/locked cap check)
- `make pairing-idempotency`
- `make pairing-refresh`
- `make pairing-refresh-race`
- Red (expected):
- `make pairing-race-negative` (non-atomic begin/commit cap race)
- `make pairing-idempotency-negative`
- `make pairing-refresh-negative`
- `make pairing-refresh-race-negative`
### Ingress trace correlation / idempotency
**Claim:** ingestion should preserve trace correlation across fan-out and be idempotent under provider retries.
What it means:
- When one external event becomes multiple internal messages, every part keeps the same trace/event identity.
- Retries do not result in double-processing.
- If provider event IDs are missing, dedupe falls back to a safe key (e.g., trace ID) to avoid dropping distinct events.
- Green:
- `make ingress-trace`
- `make ingress-trace2`
- `make ingress-idempotency`
- `make ingress-dedupe-fallback`
- Red (expected):
- `make ingress-trace-negative`
- `make ingress-trace2-negative`
- `make ingress-idempotency-negative`
- `make ingress-dedupe-fallback-negative`
### Routing dmScope precedence + identityLinks
**Claim:** routing must keep DM sessions isolated by default, and only collapse sessions when explicitly configured (channel precedence + identity links).
What it means:
- Channel-specific dmScope overrides must win over global defaults.
- identityLinks should collapse only within explicit linked groups, not across unrelated peers.
- Green:
- `make routing-precedence`
- `make routing-identitylinks`
- Red (expected):
- `make routing-precedence-negative`
- `make routing-identitylinks-negative`
+19 -20
View File
@@ -5,7 +5,7 @@ read_when:
---
# Security 🔒
## Quick check: `moltbot security audit`
## Quick check: `moltbot security audit` (formerly `clawdbot security audit`)
See also: [Formal Verification (Security Models)](/security/formal-verification/)
@@ -15,6 +15,8 @@ Run this regularly (especially after changing config or exposing network surface
moltbot security audit
moltbot security audit --deep
moltbot security audit --fix
# (On older installs, the command is `clawdbot ...`.)
```
It flags common footguns (Gateway auth exposure, browser control exposure, elevated allowlists, filesystem permissions).
@@ -22,7 +24,7 @@ It flags common footguns (Gateway auth exposure, browser control exposure, eleva
`--fix` applies safe guardrails:
- Tighten `groupPolicy="open"` to `groupPolicy="allowlist"` (and per-account variants) for common channels.
- Turn `logging.redactSensitive="off"` back to `"tools"`.
- Tighten local perms (`~/.clawdbot` → `700`, config file → `600`, plus common state files like `credentials/*.json`, `agents/*/agent/auth-profiles.json`, and `agents/*/sessions/sessions.json`).
- Tighten local perms (`~/.moltbot` → `700`, config file → `600`, plus common state files like `credentials/*.json`, `agents/*/agent/auth-profiles.json`, and `agents/*/sessions/sessions.json`).
Running an AI agent with shell access on your machine is... *spicy*. Here’s how to not get pwned.
@@ -49,13 +51,13 @@ If you run `--deep`, Moltbot also attempts a best-effort live Gateway probe.
Use this when auditing access or deciding what to back up:
- **WhatsApp**: `~/.clawdbot/credentials/whatsapp/<accountId>/creds.json`
- **WhatsApp**: `~/.moltbot/credentials/whatsapp/<accountId>/creds.json`
- **Telegram bot token**: config/env or `channels.telegram.tokenFile`
- **Discord bot token**: config/env (token file not yet supported)
- **Slack tokens**: config/env (`channels.slack.*`)
- **Pairing allowlists**: `~/.clawdbot/credentials/<channel>-allowFrom.json`
- **Model auth profiles**: `~/.clawdbot/agents/<agentId>/agent/auth-profiles.json`
- **Legacy OAuth import**: `~/.clawdbot/credentials/oauth.json`
- **Pairing allowlists**: `~/.moltbot/credentials/<channel>-allowFrom.json`
- **Model auth profiles**: `~/.moltbot/agents/<agentId>/agent/auth-profiles.json`
- **Legacy OAuth import**: `~/.moltbot/credentials/oauth.json`
## Security Audit Checklist
@@ -100,10 +102,10 @@ When `trustedProxies` is configured, the Gateway will use `X-Forwarded-For` head
## Local session logs live on disk
Moltbot stores session transcripts on disk under `~/.clawdbot/agents/<agentId>/sessions/*.jsonl`.
Moltbot stores session transcripts on disk under `~/.moltbot/agents/<agentId>/sessions/*.jsonl`.
This is required for session continuity and (optionally) session memory indexing, but it also means
**any process/user with filesystem access can read those logs**. Treat disk access as the trust
boundary and lock down permissions on `~/.clawdbot` (see the audit section below). If you need
boundary and lock down permissions on `~/.moltbot` (see the audit section below). If you need
stronger isolation between agents, run them under separate OS users or separate hosts.
## Node execution (system.run)
@@ -163,7 +165,7 @@ Plugins run **in-process** with the Gateway. Treat them as trusted code:
- Review plugin config before enabling.
- Restart the Gateway after plugin changes.
- If you install plugins from npm (`moltbot plugins install <npm-spec>`), treat it like running untrusted code:
- The install path is `~/.clawdbot/extensions/<pluginId>/` (or `$CLAWDBOT_STATE_DIR/extensions/<pluginId>/`).
- The install path is `~/.moltbot/extensions/<pluginId>/` (or `$CLAWDBOT_STATE_DIR/extensions/<pluginId>/`).
- Moltbot uses `npm pack` and then runs `npm install --omit=dev` in that directory (npm lifecycle scripts can execute code during install).
- Prefer pinned, exact versions (`@scope/pkg@1.2.3`), and inspect the unpacked code on disk before enabling.
@@ -197,14 +199,14 @@ By default, Moltbot routes **all DMs into the main session** so your assistant h
}
```
This prevents cross-user context leakage while keeping group chats isolated. If the same person contacts you on multiple channels, use `session.identityLinks` to collapse those DM sessions into one canonical identity. See [Session Management](/concepts/session) and [Configuration](/gateway/configuration).
This prevents cross-user context leakage while keeping group chats isolated. If you run multiple accounts on the same channel, use `per-account-channel-peer` instead. If the same person contacts you on multiple channels, use `session.identityLinks` to collapse those DM sessions into one canonical identity. See [Session Management](/concepts/session) and [Configuration](/gateway/configuration).
## Allowlists (DM + groups) — terminology
Moltbot has two separate “who can trigger me?” layers:
- **DM allowlist** (`allowFrom` / `channels.discord.dm.allowFrom` / `channels.slack.dm.allowFrom`): who is allowed to talk to the bot in direct messages.
- When `dmPolicy="pairing"`, approvals are written to `~/.clawdbot/credentials/<channel>-allowFrom.json` (merged with config allowlists).
- When `dmPolicy="pairing"`, approvals are written to `~/.moltbot/credentials/<channel>-allowFrom.json` (merged with config allowlists).
- **Group allowlist** (channel-specific): which groups/channels/guilds the bot will accept messages from at all.
- Common patterns:
- `channels.whatsapp.groups`, `channels.telegram.groups`, `channels.imessage.groups`: per-group defaults like `requireMention`; when set, it also acts as a group allowlist (include `"*"` to keep allow-all behavior).
@@ -231,7 +233,7 @@ Red flags to treat as untrusted:
- “Read this file/URL and do exactly what it says.”
- “Ignore your system prompt or safety rules.”
- “Reveal your hidden instructions or tool outputs.”
- “Paste the full contents of ~/.clawdbot or your logs.”
- “Paste the full contents of ~/.moltbot or your logs.”
### Prompt injection does not require public DMs
@@ -308,8 +310,8 @@ This is social engineering 101. Create distrust, encourage snooping.
### 0) File permissions
Keep config + state private on the gateway host:
- `~/.clawdbot/moltbot.json`: `600` (user read/write only)
- `~/.clawdbot`: `700` (user only)
- `~/.moltbot/moltbot.json`: `600` (user read/write only)
- `~/.moltbot`: `700` (user only)
`moltbot doctor` can warn and offer to tighten these permissions.
@@ -448,7 +450,7 @@ Avoid:
### 0.7) Secrets on disk (what’s sensitive)
Assume anything under `~/.clawdbot/` (or `$CLAWDBOT_STATE_DIR/`) may contain secrets or private data:
Assume anything under `~/.moltbot/` (or `$CLAWDBOT_STATE_DIR/`) may contain secrets or private data:
- `moltbot.json`: config may include tokens (gateway, remote gateway), provider settings, and allowlists.
- `credentials/**`: channel credentials (example: WhatsApp creds), pairing allowlists, legacy OAuth imports.
@@ -572,9 +574,6 @@ If that browser profile already contains logged-in sessions, the model can
access those accounts and data. Treat browser profiles as **sensitive state**:
- Prefer a dedicated profile for the agent (the default `clawd` profile).
- Avoid pointing the agent at your personal daily-driver profile.
- `act:evaluate` and `wait --fn` run arbitrary JavaScript in the page context.
Prompt injection can steer the model into calling them. If you do not need
them, set `browser.evaluateEnabled=false` (see [Configuration](/gateway/configuration#browser-clawd-managed-browser)).
- Keep host browser control disabled for sandboxed agents unless you trust them.
- Treat browser downloads as untrusted input; prefer an isolated downloads directory.
- Disable browser sync/password managers in the agent profile if possible (reduces blast radius).
@@ -691,7 +690,7 @@ If your AI does something bad:
### Audit
1. Check Gateway logs: `/tmp/moltbot/moltbot-YYYY-MM-DD.log` (or `logging.file`).
2. Review the relevant transcript(s): `~/.clawdbot/agents/<agentId>/sessions/*.jsonl`.
2. Review the relevant transcript(s): `~/.moltbot/agents/<agentId>/sessions/*.jsonl`.
3. Review recent config changes (anything that could have widened access: `gateway.bind`, `gateway.auth`, dm/group policies, `tools.elevated`, plugin changes).
### Collect for a report
@@ -750,7 +749,7 @@ Mario asking for find ~
Found a vulnerability in Moltbot? Please report responsibly:
1. Email: security@molt.bot
1. Email: security@clawd.bot
2. Don't post publicly until fixed
3. We'll credit you (unless you prefer anonymity)
+2 -2
View File
@@ -576,7 +576,7 @@ If the app disappears or shows "Abort trap 6" when you click "Allow" on a privac
**Fix 1: Reset TCC Cache**
```bash
tccutil reset All com.clawdbot.mac.debug
tccutil reset All bot.molt.mac.debug
```
**Fix 2: Force New Bundle ID**
@@ -591,7 +591,7 @@ If the gateway is supervised by launchd, killing the PID will just respawn it. S
```bash
moltbot gateway status
moltbot gateway stop
# Or: launchctl bootout gui/$UID/com.clawdbot.gateway (replace with com.clawdbot.<profile> if needed)
# Or: launchctl bootout gui/$UID/bot.molt.gateway (replace with bot.molt.<profile>; legacy com.clawdbot.* still works)
```
**Fix 2: Port is busy (find the listener)**
+2 -2
View File
@@ -1026,7 +1026,7 @@ Docs: [Cron jobs](/automation/cron-jobs), [Cron vs Heartbeat](/automation/cron-v
**Can I run Apple macOS only skills from Linux**
Not directly. macOS skills are gated by `metadata.clawdbot.os` plus required binaries, and skills only appear in the system prompt when they are eligible on the **Gateway host**. On Linux, `darwin`-only skills (like `imsg`, `apple-notes`, `apple-reminders`) will not load unless you override the gating.
Not directly. macOS skills are gated by `metadata.moltbot.os` plus required binaries, and skills only appear in the system prompt when they are eligible on the **Gateway host**. On Linux, `darwin`-only skills (like `imsg`, `apple-notes`, `apple-reminders`) will not load unless you override the gating.
You have three supported patterns:
@@ -2328,7 +2328,7 @@ Quick setup (recommended):
- Set a unique `gateway.port` in each profile config (or pass `--port` for manual runs).
- Install a per-profile service: `moltbot --profile <name> gateway install`.
Profiles also suffix service names (`com.clawdbot.<profile>`, `moltbot-gateway-<profile>.service`, `Moltbot Gateway (<profile>)`).
Profiles also suffix service names (`bot.molt.<profile>`; legacy `com.clawdbot.*`, `moltbot-gateway-<profile>.service`, `Moltbot Gateway (<profile>)`).
Full guide: [Multiple gateways](/gateway/multiple-gateways).
### What does invalid handshake code 1008 mean
+1 -1
View File
@@ -149,7 +149,7 @@ No configuration needed.
### Metadata Fields
The `metadata.clawdbot` object supports:
The `metadata.moltbot` object supports:
- **`emoji`**: Display emoji for CLI (e.g., `"💾"`)
- **`events`**: Array of events to listen for (e.g., `["command:new", "command:reset"]`)
+1 -1
View File
@@ -57,7 +57,7 @@ On macOS, the GUI app does not automatically inherit shell env vars. You can
also enable Nix mode via defaults:
```bash
defaults write com.clawdbot.mac moltbot.nixMode -bool true
defaults write bot.molt.mac moltbot.nixMode -bool true
```
### Config + state paths
+4 -4
View File
@@ -78,14 +78,14 @@ Use this if the gateway service keeps running but `moltbot` is missing.
### macOS (launchd)
Default label is `com.clawdbot.gateway` (or `com.clawdbot.<profile>`):
Default label is `bot.molt.gateway` (or `bot.molt.<profile>`; legacy `com.clawdbot.*` may still exist):
```bash
launchctl bootout gui/$UID/com.clawdbot.gateway
rm -f ~/Library/LaunchAgents/com.clawdbot.gateway.plist
launchctl bootout gui/$UID/bot.molt.gateway
rm -f ~/Library/LaunchAgents/bot.molt.gateway.plist
```
If you used a profile, replace the label and plist name with `com.clawdbot.<profile>`.
If you used a profile, replace the label and plist name with `bot.molt.<profile>`. Remove any legacy `com.clawdbot.*` plists if present.
### Linux (systemd user unit)
+2 -2
View File
@@ -125,7 +125,7 @@ moltbot health
```
Notes:
- `pnpm build` matters when you run the packaged `moltbot` binary ([`dist/entry.js`](https://github.com/moltbot/moltbot/blob/main/dist/entry.js)) or use Node to run `dist/`.
- `pnpm build` matters when you run the packaged `moltbot` binary ([`moltbot.mjs`](https://github.com/moltbot/moltbot/blob/main/moltbot.mjs)) or use Node to run `dist/`.
- If you run from a repo checkout without a global install, use `pnpm moltbot ...` for CLI commands.
- If you run directly from TypeScript (`pnpm moltbot ...`), a rebuild is usually unnecessary, but **config migrations still apply** → run doctor.
- Switching between global and git installs is easy: install the other flavor, then run `moltbot doctor` so the gateway service entrypoint is rewritten to the current install.
@@ -158,7 +158,7 @@ moltbot logs --follow
```
If you’re supervised:
- macOS launchd (app-bundled LaunchAgent): `launchctl kickstart -k gui/$UID/com.clawdbot.gateway` (use `com.clawdbot.<profile>` if set)
- macOS launchd (app-bundled LaunchAgent): `launchctl kickstart -k gui/$UID/bot.molt.gateway` (use `bot.molt.<profile>`; legacy `com.clawdbot.*` still works)
- Linux systemd user service: `systemctl --user restart moltbot-gateway[-<profile>].service`
- Windows (WSL2): `systemctl --user restart moltbot-gateway[-<profile>].service`
- `launchctl`/`systemctl` only work if the service is installed; otherwise run `moltbot gateway install`.
+59 -121
View File
@@ -7,40 +7,47 @@ read_when:
# exe.dev
Goal: Moltbot Gateway running on an exe.dev VM, reachable from your laptop via:
- **exe.dev HTTPS proxy** (easy, no tunnel) or
- **SSH tunnel** (most secure; loopback-only Gateway)
Goal: Moltbot Gateway running on an exe.dev VM, reachable from your laptop via: `https://<vm-name>.exe.xyz`
This page assumes **Ubuntu/Debian**. If you picked a different distro, map packages accordingly.
If you’re on any other Linux VPS, the same steps apply — you just won’t use the exe.dev proxy commands.
This page assumes exe.dev's default **exeuntu** image. If you picked a different distro, map packages accordingly.
## Beginner quick path
1) Create VM → install Node 22 → install Moltbot
2) Run `moltbot onboard --install-daemon`
3) Tunnel from laptop (`ssh -N -L 18789:127.0.0.1:18789 …`)
4) Open `http://127.0.0.1:18789/` and paste your token
1) [https://exe.new/moltbot](https://exe.new/moltbot)
2) Fill in your auth key/token as needed
3) Click on "Agent" next to your VM, and wait...
4) ???
5) Profit
## What you need
- exe.dev account + `ssh exe.dev` working on your laptop
- SSH keys set up (your laptop → exe.dev)
- Model auth (OAuth or API key) you want to use
- Provider credentials (optional): WhatsApp QR scan, Telegram bot token, Discord bot token, …
- exe.dev account
- `ssh exe.dev` access to [exe.dev](https://exe.dev) virtual machines (optional)
## Automated Install with Shelley
Shelley, [exe.dev](https://exe.dev)'s agent, can install Moltbot instantly with our
prompt. The prompt used is as below:
```
Set up Moltbot (https://docs.molt.bot/install) on this VM. Use the non-interactive and accept-risk flags for moltbot onboarding. Add the supplied auth or token as needed. Configure nginx to forward from the default port 18789 to the root location on the default enabled site config, making sure to enable Websocket support. Pairing is done by "moltbot devices list" and "moltbot device approve <request id>". Make sure the dashboard shows that Moltbot's health is OK. exe.dev handles forwarding from port 8000 to port 80/443 and HTTPS for us, so the final "reachable" should be <vm-name>.exe.xyz, without port specification.
```
## Manual installation
## 1) Create the VM
From your laptop:
From your device:
```bash
ssh exe.dev new --name=moltbot
ssh exe.dev new
```
Then connect:
```bash
ssh moltbot.exe.xyz
ssh <vm-name>.exe.xyz
```
Tip: keep this VM **stateful**. Moltbot stores state under `~/.clawdbot/` and `~/clawd/`.
@@ -52,130 +59,61 @@ sudo apt-get update
sudo apt-get install -y git curl jq ca-certificates openssl
```
### Node 22
Install Node **>= 22.12** (any method is fine). Quick check:
```bash
node -v
```
If you don’t already have Node 22 on the VM, use your preferred Node manager (nvm/mise/asdf) or a distro package source that provides Node 22+.
Common Ubuntu/Debian option (NodeSource):
```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
```
## 3) Install Moltbot
Recommended on servers: npm global install.
Run the Moltbot install script:
```bash
npm i -g moltbot@latest
moltbot --version
curl -fsSL https://molt.bot/install.sh | bash
```
If native deps fail to install (rare; usually `sharp`), add build tools:
## 4) Setup nginx to proxy Moltbot to port 8000
Edit `/etc/nginx/sites-enabled/default` with
```bash
sudo apt-get install -y build-essential python3
```
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 8000;
listen [::]:8000;
## 4) First-time setup (wizard)
server_name _;
Run the onboarding wizard on the VM:
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
```bash
moltbot onboard --install-daemon
```
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
It can set up:
- `~/clawd` workspace bootstrap
- `~/.clawdbot/moltbot.json` config
- model auth profiles
- model provider config/login
- Linux systemd **user** service (service)
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
If you’re doing OAuth on a headless VM: do OAuth on a normal machine first, then copy the auth profile to the VM (see [Help](/help)).
## 5) Remote access options
### Option A (recommended): SSH tunnel (loopback-only)
Keep Gateway on loopback (default) and tunnel it from your laptop:
```bash
ssh -N -L 18789:127.0.0.1:18789 moltbot.exe.xyz
```
Open locally:
- `http://127.0.0.1:18789/` (Control UI)
Runbook: [Remote access](/gateway/remote)
### Option B: exe.dev HTTPS proxy (no tunnel)
To let exe.dev proxy traffic to the VM, bind the Gateway to the LAN interface and set a token:
```bash
export CLAWDBOT_GATEWAY_TOKEN="$(openssl rand -hex 32)"
moltbot gateway --bind lan --port 8080 --token "$CLAWDBOT_GATEWAY_TOKEN"
```
For service runs, persist it in `~/.clawdbot/moltbot.json`:
```json5
{
gateway: {
mode: "local",
port: 8080,
bind: "lan",
auth: { mode: "token", token: "YOUR_TOKEN" }
}
# Timeout settings for long-lived connections
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
```
Notes:
- Non-loopback binds require `gateway.auth.token` (or `CLAWDBOT_GATEWAY_TOKEN`).
- `gateway.remote.token` is only for remote CLI calls; it does not enable local auth.
## 5) Access Moltbot and grant privileges
Then point exe.dev’s proxy at `8080` (or whatever port you chose) and open your VM’s HTTPS URL:
Access `https://<vm-name>.exe.xyz/?token=YOUR-TOKEN-FROM-TERMINAL`. Approve
devices with `moltbot devices list` and `moltbot device approve`. When in doubt,
use Shelley from your browser!
```bash
ssh exe.dev share port moltbot 8080
```
## Remote Access
Open:
- `https://moltbot.exe.xyz/`
Remote access is handled by [exe.dev](https://exe.dev)'s authentication. By
default, HTTP traffic from port 8000 is forwarded to `https://<vm-name>.exe.xyz`
with email auth.
In the Control UI, paste the token (UI → Settings → token). The UI sends it as `connect.params.auth.token`.
Notes:
- Prefer a **non-default** port (like `8080`) if your proxy expects an app port.
- Treat the token like a password.
Control UI details: [Control UI](/web/control-ui)
## 6) Keep it running (service)
On Linux, Moltbot uses a systemd **user** service. After `--install-daemon`, verify:
```bash
systemctl --user status moltbot-gateway[-<profile>].service
```
If the service dies after logout, enable lingering:
```bash
sudo loginctl enable-linger "$USER"
```
More: [Linux](/platforms/linux)
## 7) Updates
## Updating
```bash
npm i -g moltbot@latest
+1 -1
View File
@@ -185,7 +185,7 @@ cat > /data/moltbot.json << 'EOF'
"bind": "auto"
},
"meta": {
"lastTouchedVersion": "2026.1.26"
"lastTouchedVersion": "2026.1.27-beta.1"
}
}
EOF
+1 -1
View File
@@ -46,5 +46,5 @@ Use one of these (all supported):
- Repair/migrate: `moltbot doctor` (offers to install or fix the service)
The service target depends on OS:
- macOS: LaunchAgent (`com.clawdbot.gateway` or `com.clawdbot.<profile>`)
- macOS: LaunchAgent (`bot.molt.gateway` or `bot.molt.<profile>`; legacy `com.clawdbot.*`)
- Linux/WSL2: systemd user service (`moltbot-gateway[-<profile>].service`)
+3 -3
View File
@@ -26,11 +26,11 @@ The macOS app’s **Install CLI** button runs the same flow via npm/pnpm (bun no
## Launchd (Gateway as LaunchAgent)
Label:
- `com.clawdbot.gateway` (or `com.clawdbot.<profile>`)
- `bot.molt.gateway` (or `bot.molt.<profile>`; legacy `com.clawdbot.*` may remain)
Plist location (per‑user):
- `~/Library/LaunchAgents/com.clawdbot.gateway.plist`
(or `~/Library/LaunchAgents/com.clawdbot.<profile>.plist`)
- `~/Library/LaunchAgents/bot.molt.gateway.plist`
(or `~/Library/LaunchAgents/bot.molt.<profile>.plist`)
Manager:
- The macOS app owns LaunchAgent install/update in Local mode.
+5 -5
View File
@@ -16,8 +16,8 @@ If you need tighter coupling to the UI, run the Gateway manually in a terminal.
## Default behavior (launchd)
- The app installs a per‑user LaunchAgent labeled `com.clawdbot.gateway`
(or `com.clawdbot.<profile>` when using `--profile`/`CLAWDBOT_PROFILE`).
- The app installs a per‑user LaunchAgent labeled `bot.molt.gateway`
(or `bot.molt.<profile>` when using `--profile`/`CLAWDBOT_PROFILE`; legacy `com.clawdbot.*` is supported).
- When Local mode is enabled, the app ensures the LaunchAgent is loaded and
starts the Gateway if needed.
- Logs are written to the launchd gateway log path (visible in Debug Settings).
@@ -25,11 +25,11 @@ If you need tighter coupling to the UI, run the Gateway manually in a terminal.
Common commands:
```bash
launchctl kickstart -k gui/$UID/com.clawdbot.gateway
launchctl bootout gui/$UID/com.clawdbot.gateway
launchctl kickstart -k gui/$UID/bot.molt.gateway
launchctl bootout gui/$UID/bot.molt.gateway
```
Replace the label with `com.clawdbot.<profile>` when running a named profile.
Replace the label with `bot.molt.<profile>` when running a named profile.
## Unsigned dev builds
+1 -1
View File
@@ -74,7 +74,7 @@ If the app crashes when you try to allow **Speech Recognition** or **Microphone*
**Fix:**
1. Reset the TCC permissions:
```bash
tccutil reset All com.clawdbot.mac.debug
tccutil reset All bot.molt.mac.debug
```
2. If that fails, change the `BUNDLE_ID` temporarily in [`scripts/package-mac-app.sh`](https://github.com/moltbot/moltbot/blob/main/scripts/package-mac-app.sh) to force a "clean slate" from macOS.
+4 -4
View File
@@ -22,11 +22,11 @@ Notes:
Unified logging redacts most payloads unless a subsystem opts into `privacy -off`. Per Peter's write-up on macOS [logging privacy shenanigans](https://steipete.me/posts/2025/logging-privacy-shenanigans) (2025) this is controlled by a plist in `/Library/Preferences/Logging/Subsystems/` keyed by the subsystem name. Only new log entries pick up the flag, so enable it before reproducing an issue.
## Enable for Moltbot (`com.clawdbot`)
## Enable for Moltbot (`bot.molt`)
- Write the plist to a temp file first, then install it atomically as root:
```bash
cat <<'EOF' >/tmp/com.clawdbot.plist
cat <<'EOF' >/tmp/bot.molt.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
@@ -39,13 +39,13 @@ cat <<'EOF' >/tmp/com.clawdbot.plist
</dict>
</plist>
EOF
sudo install -m 644 -o root -g wheel /tmp/com.clawdbot.plist /Library/Preferences/Logging/Subsystems/com.clawdbot.plist
sudo install -m 644 -o root -g wheel /tmp/bot.molt.plist /Library/Preferences/Logging/Subsystems/bot.molt.plist
```
- No reboot is required; logd notices the file quickly, but only new log lines will include private payloads.
- View the richer output with the existing helper, e.g. `./scripts/clawlog.sh --category WebChat --last 5m`.
## Disable after debugging
- Remove the override: `sudo rm /Library/Preferences/Logging/Subsystems/com.clawdbot.plist`.
- Remove the override: `sudo rm /Library/Preferences/Logging/Subsystems/bot.molt.plist`.
- Optionally run `sudo log config --reload` to force logd to drop the override immediately.
- Remember this surface can include phone numbers and message bodies; keep the plist in place only while you actively need the extra detail.
+2 -2
View File
@@ -31,8 +31,8 @@ grants, and prompts can disappear entirely until the stale entries are cleared.
Example resets (replace bundle ID as needed):
```bash
sudo tccutil reset Accessibility com.clawdbot.mac
sudo tccutil reset ScreenCapture com.clawdbot.mac
sudo tccutil reset Accessibility bot.molt.mac
sudo tccutil reset ScreenCapture bot.molt.mac
sudo tccutil reset AppleEvents
```
+9 -9
View File
@@ -29,45 +29,45 @@ Notes:
```bash
# From repo root; set release IDs so Sparkle feed is enabled.
# APP_BUILD must be numeric + monotonic for Sparkle compare.
BUNDLE_ID=com.clawdbot.mac \
APP_VERSION=2026.1.26 \
BUNDLE_ID=bot.molt.mac \
APP_VERSION=2026.1.27-beta.1 \
APP_BUILD="$(git rev-list --count HEAD)" \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-app.sh
# Zip for distribution (includes resource forks for Sparkle delta support)
ditto -c -k --sequesterRsrc --keepParent dist/Moltbot.app dist/Moltbot-2026.1.26.zip
ditto -c -k --sequesterRsrc --keepParent dist/Moltbot.app dist/Moltbot-2026.1.27-beta.1.zip
# Optional: also build a styled DMG for humans (drag to /Applications)
scripts/create-dmg.sh dist/Moltbot.app dist/Moltbot-2026.1.26.dmg
scripts/create-dmg.sh dist/Moltbot.app dist/Moltbot-2026.1.27-beta.1.dmg
# Recommended: build + notarize/staple zip + DMG
# First, create a keychain profile once:
# xcrun notarytool store-credentials "moltbot-notary" \
# --apple-id "<apple-id>" --team-id "<team-id>" --password "<app-specific-password>"
NOTARIZE=1 NOTARYTOOL_PROFILE=moltbot-notary \
BUNDLE_ID=com.clawdbot.mac \
APP_VERSION=2026.1.26 \
BUNDLE_ID=bot.molt.mac \
APP_VERSION=2026.1.27-beta.1 \
APP_BUILD="$(git rev-list --count HEAD)" \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-dist.sh
# Optional: ship dSYM alongside the release
ditto -c -k --keepParent apps/macos/.build/release/Moltbot.app.dSYM dist/Moltbot-2026.1.26.dSYM.zip
ditto -c -k --keepParent apps/macos/.build/release/Moltbot.app.dSYM dist/Moltbot-2026.1.27-beta.1.dSYM.zip
```
## Appcast entry
Use the release note generator so Sparkle renders formatted HTML notes:
```bash
SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/Moltbot-2026.1.26.zip https://raw.githubusercontent.com/moltbot/moltbot/main/appcast.xml
SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/Moltbot-2026.1.27-beta.1.zip https://raw.githubusercontent.com/moltbot/moltbot/main/appcast.xml
```
Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/moltbot/moltbot/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry.
Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when publishing.
## Publish & verify
- Upload `Moltbot-2026.1.26.zip` (and `Moltbot-2026.1.26.dSYM.zip`) to the GitHub release for tag `v2026.1.26`.
- Upload `Moltbot-2026.1.27-beta.1.zip` (and `Moltbot-2026.1.27-beta.1.dSYM.zip`) to the GitHub release for tag `v2026.1.27-beta.1`.
- Ensure the raw appcast URL matches the baked feed: `https://raw.githubusercontent.com/moltbot/moltbot/main/appcast.xml`.
- Sanity checks:
- `curl -I https://raw.githubusercontent.com/moltbot/moltbot/main/appcast.xml` returns 200.
+1 -1
View File
@@ -7,7 +7,7 @@ read_when:
This app is usually built from [`scripts/package-mac-app.sh`](https://github.com/moltbot/moltbot/blob/main/scripts/package-mac-app.sh), which now:
- sets a stable debug bundle identifier: `com.clawdbot.mac.debug`
- sets a stable debug bundle identifier: `bot.molt.mac.debug`
- writes the Info.plist with that bundle id (override via `BUNDLE_ID=...`)
- calls [`scripts/codesign-mac-app.sh`](https://github.com/moltbot/moltbot/blob/main/scripts/codesign-mac-app.sh) to sign the main binary and app bundle so macOS treats each rebuild as the same signed bundle and keeps TCC permissions (notifications, accessibility, screen recording, mic, speech). For stable permissions, use a real signing identity; ad-hoc is opt-in and fragile (see [macOS permissions](/platforms/mac/permissions)).
- uses `CODESIGN_TIMESTAMP=auto` by default; it enables trusted timestamps for Developer ID signatures. Set `CODESIGN_TIMESTAMP=off` to skip timestamping (offline debug builds).
+2 -2
View File
@@ -11,10 +11,10 @@ The macOS app surfaces Moltbot skills via the gateway; it does not parse skills
## Data source
- `skills.status` (gateway) returns all skills plus eligibility and missing requirements
(including allowlist blocks for bundled skills).
- Requirements are derived from `metadata.clawdbot.requires` in each `SKILL.md`.
- Requirements are derived from `metadata.moltbot.requires` in each `SKILL.md`.
## Install actions
- `metadata.clawdbot.install` defines install options (brew/node/go/uv).
- `metadata.moltbot.install` defines install options (brew/node/go/uv).
- The app calls `skills.install` to run installers on the gateway host.
- The gateway surfaces only one preferred installer when multiple are provided
(brew when available, otherwise node manager from `skills.install`, default npm).
+2 -2
View File
@@ -32,14 +32,14 @@ Audience: macOS app contributors. Goal: keep the voice overlay predictable when
- Push-to-talk: no delay; wake-word: optional delay for auto-send.
- Apply a short cooldown to the wake runtime after push-to-talk finishes so wake-word doesn’t immediately retrigger.
5. **Logging**
- Coordinator emits `.info` logs in subsystem `com.clawdbot`, categories `voicewake.overlay` and `voicewake.chime`.
- Coordinator emits `.info` logs in subsystem `bot.molt`, categories `voicewake.overlay` and `voicewake.chime`.
- Key events: `session_started`, `adopted_by_push_to_talk`, `partial`, `finalized`, `send`, `dismiss`, `cancel`, `cooldown`.
### Debugging checklist
- Stream logs while reproducing a sticky overlay:
```bash
sudo log stream --predicate 'subsystem == "com.clawdbot" AND category CONTAINS "voicewake"' --level info --style compact
sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact
```
- Verify only one active session token; stale callbacks should be dropped by the coordinator.
- Ensure push-to-talk release always calls `endCapture` with the active token; if text is empty, expect `dismiss` without chime or send.
+1 -1
View File
@@ -20,7 +20,7 @@ agent (with a session switcher for other sessions).
```bash
dist/Moltbot.app/Contents/MacOS/Moltbot --webchat
```
- Logs: `./scripts/clawlog.sh` (subsystem `com.clawdbot`, category `WebChatSwiftUI`).
- Logs: `./scripts/clawlog.sh` (subsystem `bot.molt`, category `WebChatSwiftUI`).
## How it’s wired
+5 -5
View File
@@ -32,15 +32,15 @@ The app does not spawn the Gateway as a child process.
## Launchd control
The app manages a per‑user LaunchAgent labeled `com.clawdbot.gateway`
(or `com.clawdbot.<profile>` when using `--profile`/`CLAWDBOT_PROFILE`).
The app manages a per‑user LaunchAgent labeled `bot.molt.gateway`
(or `bot.molt.<profile>` when using `--profile`/`CLAWDBOT_PROFILE`; legacy `com.clawdbot.*` still unloads).
```bash
launchctl kickstart -k gui/$UID/com.clawdbot.gateway
launchctl bootout gui/$UID/com.clawdbot.gateway
launchctl kickstart -k gui/$UID/bot.molt.gateway
launchctl bootout gui/$UID/bot.molt.gateway
```
Replace the label with `com.clawdbot.<profile>` when running a named profile.
Replace the label with `bot.molt.<profile>` when running a named profile.
If the LaunchAgent isn’t installed, enable it from the app or run
`moltbot gateway install`.
+13 -2
View File
@@ -9,11 +9,12 @@ read_when:
# Moonshot AI (Kimi)
Moonshot provides the Kimi API with OpenAI-compatible endpoints. Configure the
provider and set the default model to `moonshot/kimi-k2-0905-preview`, or use
provider and set the default model to `moonshot/kimi-k2.5`, or use
Kimi Code with `kimi-code/kimi-for-coding`.
Current Kimi K2 model IDs:
{/* moonshot-kimi-k2-ids:start */}
- `kimi-k2.5`
- `kimi-k2-0905-preview`
- `kimi-k2-turbo-preview`
- `kimi-k2-thinking`
@@ -39,9 +40,10 @@ Note: Moonshot and Kimi Code are separate providers. Keys are not interchangeabl
env: { MOONSHOT_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "moonshot/kimi-k2-0905-preview" },
model: { primary: "moonshot/kimi-k2.5" },
models: {
// moonshot-kimi-k2-aliases:start
"moonshot/kimi-k2.5": { alias: "Kimi K2.5" },
"moonshot/kimi-k2-0905-preview": { alias: "Kimi K2" },
"moonshot/kimi-k2-turbo-preview": { alias: "Kimi K2 Turbo" },
"moonshot/kimi-k2-thinking": { alias: "Kimi K2 Thinking" },
@@ -59,6 +61,15 @@ Note: Moonshot and Kimi Code are separate providers. Keys are not interchangeabl
api: "openai-completions",
models: [
// moonshot-kimi-k2-models:start
{
id: "kimi-k2.5",
name: "Kimi K2.5",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 256000,
maxTokens: 8192
},
{
id: "kimi-k2-0905-preview",
name: "Kimi K2 0905 Preview",
+2 -2
View File
@@ -17,10 +17,10 @@ When the operator says “release”, immediately do this preflight (no extra qu
- Use Sparkle keys from `~/Library/CloudStorage/Dropbox/Backup/Sparkle` if needed.
1) **Version & metadata**
- [ ] Bump `package.json` version (e.g., `2026.1.26`).
- [ ] Bump `package.json` version (e.g., `2026.1.27-beta.1`).
- [ ] Run `pnpm plugins:sync` to align extension package versions + changelogs.
- [ ] Update CLI/version strings: [`src/cli/program.ts`](https://github.com/moltbot/moltbot/blob/main/src/cli/program.ts) and the Baileys user agent in [`src/provider-web.ts`](https://github.com/moltbot/moltbot/blob/main/src/provider-web.ts).
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`dist/entry.js`](https://github.com/moltbot/moltbot/blob/main/dist/entry.js) for `moltbot`.
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`moltbot.mjs`](https://github.com/moltbot/moltbot/blob/main/moltbot.mjs) for `moltbot`.
- [ ] If dependencies changed, run `pnpm install` so `pnpm-lock.yaml` is current.
2) **Build & artifacts**
+62 -9
View File
@@ -8,6 +8,8 @@ permalink: /security/formal-verification/
This page tracks Moltbot’s **formal security models** (TLA+/TLC today; more as needed).
> Note: some older links may refer to the previous project name.
**Goal (north star):** provide a machine-checked argument that Moltbot enforces its
intended security policy (authorization, session isolation, tool gating, and
misconfiguration safety), under explicit assumptions.
@@ -20,7 +22,7 @@ misconfiguration safety), under explicit assumptions.
## Where the models live
Models are maintained in a separate repo: [vignesh07/moltbot-formal-models](https://github.com/vignesh07/moltbot-formal-models).
Models are maintained in a separate repo: [vignesh07/clawdbot-formal-models](https://github.com/vignesh07/clawdbot-formal-models).
## Important caveats
@@ -37,8 +39,8 @@ Today, results are reproduced by cloning the models repo locally and running TLC
Getting started:
```bash
git clone https://github.com/vignesh07/moltbot-formal-models
cd moltbot-formal-models
git clone https://github.com/vignesh07/clawdbot-formal-models
cd clawdbot-formal-models
# Java 11+ required (TLC runs on the JVM).
# The repo vendors a pinned `tla2tools.jar` (TLA+ tools) and provides `bin/tlc` + Make targets.
@@ -98,10 +100,61 @@ See also: `docs/gateway-exposure-matrix.md` in the models repo.
- Red (expected):
- `make routing-isolation-negative`
## Roadmap
Next models to deepen fidelity:
- Pairing store concurrency/locking/idempotency
- Provider-specific ingress preflight modeling
- Routing identity-links + dmScope variants + binding precedence
- Gateway auth conformance (proxy/tailscale specifics)
## v1++: additional bounded models (concurrency, retries, trace correctness)
These are follow-on models that tighten fidelity around real-world failure modes (non-atomic updates, retries, and message fan-out).
### Pairing store concurrency / idempotency
**Claim:** a pairing store should enforce `MaxPending` and idempotency even under interleavings (i.e., “check-then-write” must be atomic / locked; refresh shouldn’t create duplicates).
What it means:
- Under concurrent requests, you can’t exceed `MaxPending` for a channel.
- Repeated requests/refreshes for the same `(channel, sender)` should not create duplicate live pending rows.
- Green runs:
- `make pairing-race` (atomic/locked cap check)
- `make pairing-idempotency`
- `make pairing-refresh`
- `make pairing-refresh-race`
- Red (expected):
- `make pairing-race-negative` (non-atomic begin/commit cap race)
- `make pairing-idempotency-negative`
- `make pairing-refresh-negative`
- `make pairing-refresh-race-negative`
### Ingress trace correlation / idempotency
**Claim:** ingestion should preserve trace correlation across fan-out and be idempotent under provider retries.
What it means:
- When one external event becomes multiple internal messages, every part keeps the same trace/event identity.
- Retries do not result in double-processing.
- If provider event IDs are missing, dedupe falls back to a safe key (e.g., trace ID) to avoid dropping distinct events.
- Green:
- `make ingress-trace`
- `make ingress-trace2`
- `make ingress-idempotency`
- `make ingress-dedupe-fallback`
- Red (expected):
- `make ingress-trace-negative`
- `make ingress-trace2-negative`
- `make ingress-idempotency-negative`
- `make ingress-dedupe-fallback-negative`
### Routing dmScope precedence + identityLinks
**Claim:** routing must keep DM sessions isolated by default, and only collapse sessions when explicitly configured (channel precedence + identity links).
What it means:
- Channel-specific dmScope overrides must win over global defaults.
- identityLinks should collapse only within explicit linked groups, not across unrelated peers.
- Green:
- `make routing-precedence`
- `make routing-identitylinks`
- Red (expected):
- `make routing-precedence-negative`
- `make routing-identitylinks-negative`
+1 -1
View File
@@ -180,7 +180,7 @@ If you don’t have a global install yet, run the onboarding step via `pnpm molt
Gateway (from this repo):
```bash
node dist/entry.js gateway --port 18789 --verbose
node moltbot.mjs gateway --port 18789 --verbose
```
## 7) Verify end-to-end
+1 -1
View File
@@ -60,7 +60,7 @@ Per-skill fields:
## Notes
- Keys under `entries` map to the skill name by default. If a skill defines
`metadata.clawdbot.skillKey`, use that key instead.
`metadata.moltbot.skillKey`, use that key instead.
- Changes to skills are picked up on the next agent turn when the watcher is enabled.
### Sandboxed skills + env vars
+6 -6
View File
@@ -41,7 +41,7 @@ applies: workspace wins, then managed/local, then bundled.
Plugins can ship their own skills by listing `skills` directories in
`moltbot.plugin.json` (paths relative to the plugin root). Plugin skills load
when the plugin is enabled and participate in the normal skill precedence rules.
You can gate them via `metadata.clawdbot.requires.config` on the plugin’s config
You can gate them via `metadata.moltbot.requires.config` on the plugin’s config
entry. See [Plugins](/plugin) for discovery/config and [Tools](/tools) for the
tool surface those skills teach.
@@ -89,7 +89,7 @@ Notes:
- `metadata` should be a **single-line JSON object**.
- Use `{baseDir}` in instructions to reference the skill folder path.
- Optional frontmatter keys:
- `homepage` — URL surfaced as “Website” in the macOS Skills UI (also supported via `metadata.clawdbot.homepage`).
- `homepage` — URL surfaced as “Website” in the macOS Skills UI (also supported via `metadata.moltbot.homepage`).
- `user-invocable` — `true|false` (default: `true`). When `true`, the skill is exposed as a user slash command.
- `disable-model-invocation` — `true|false` (default: `false`). When `true`, the skill is excluded from the model prompt (still available via user invocation).
- `command-dispatch` — `tool` (optional). When set to `tool`, the slash command bypasses the model and dispatches directly to a tool.
@@ -111,7 +111,7 @@ metadata: {"moltbot":{"requires":{"bins":["uv"],"env":["GEMINI_API_KEY"],"config
---
```
Fields under `metadata.clawdbot`:
Fields under `metadata.moltbot`:
- `always: true` — always include the skill (skip other gates).
- `emoji` — optional emoji used by the macOS Skills UI.
- `homepage` — optional URL shown as “Website” in the macOS Skills UI.
@@ -152,7 +152,7 @@ Notes:
- Go installs: if `go` is missing and `brew` is available, the gateway installs Go via Homebrew first and sets `GOBIN` to Homebrew’s `bin` when possible.
- Download installs: `url` (required), `archive` (`tar.gz` | `tar.bz2` | `zip`), `extract` (default: auto when archive detected), `stripComponents`, `targetDir` (default: `~/.clawdbot/tools/<skillKey>`).
If no `metadata.clawdbot` is present, the skill is always eligible (unless
If no `metadata.moltbot` is present, the skill is always eligible (unless
disabled in config or blocked by `skills.allowBundled` for bundled skills).
## Config overrides (`~/.clawdbot/moltbot.json`)
@@ -184,12 +184,12 @@ Bundled/managed skills can be toggled and supplied with env values:
Note: if the skill name contains hyphens, quote the key (JSON5 allows quoted keys).
Config keys match the **skill name** by default. If a skill defines
`metadata.clawdbot.skillKey`, use that key under `skills.entries`.
`metadata.moltbot.skillKey`, use that key under `skills.entries`.
Rules:
- `enabled: false` disables the skill even if it’s bundled/installed.
- `env`: injected **only if** the variable isn’t already set in the process.
- `apiKey`: convenience for skills that declare `metadata.clawdbot.primaryEnv`.
- `apiKey`: convenience for skills that declare `metadata.moltbot.primaryEnv`.
- `config`: optional bag for custom per-skill fields; custom keys must live here.
- `allowBundled`: optional allowlist for **bundled** skills only. If set, only
bundled skills in the list are eligible (managed/workspace skills unaffected).