docs: add imessage rpc and groups docs

This commit is contained in:
Peter Steinberger
2026-01-02 01:19:22 +01:00
parent cbac34347b
commit 336048441c
11 changed files with 173 additions and 13 deletions

View File

@@ -18,4 +18,4 @@ read_when:
- Output:
- Default: prints text (and `MEDIA:<url>` lines) to stdout.
- `--json`: prints structured payloads + meta.
- Optional: `--deliver` sends the reply back to the selected provider (requires `--to` for WhatsApp).
- Optional: `--deliver` sends the reply back to the selected provider (`whatsapp`, `telegram`, `discord`, `signal`, `imessage`).

View File

@@ -88,7 +88,7 @@ Allowlist of E.164 phone numbers that may trigger auto-replies.
### `routing.groupChat`
Group messages default to **require mention** (either metadata mention or regex patterns).
Group messages default to **require mention** (either metadata mention or regex patterns). Applies to WhatsApp, Telegram, Discord, and iMessage group chats.
```json5
{

View File

@@ -75,7 +75,7 @@ Each job is a JSON object with stable keys (unknown keys ignored for forward com
- For `sessionTarget:"main"`, `wakeMode` controls whether we trigger the heartbeat immediately or just enqueue and wait.
- `payload` (one of)
- `{"kind":"systemEvent","text":string}` (enqueue as `System:`)
- `{"kind":"agentTurn","message":string,"deliver"?:boolean,"channel"?: "last"|"whatsapp"|"telegram","to"?:string,"timeoutSeconds"?:number}`
- `{"kind":"agentTurn","message":string,"deliver"?:boolean,"channel"?: "last"|"whatsapp"|"telegram"|"discord"|"signal"|"imessage","to"?:string,"timeoutSeconds"?:number}`
- `isolation` (optional; only meaningful for isolated jobs)
- `{"postToMainPrefix"?: string}`
- `runtime` (optional)
@@ -264,7 +264,7 @@ Add a `cron` command group (all commands should also support `--json` where sens
- `--wake now|next-heartbeat`
- payload flags (choose one):
- `--system-event "<text>"`
- `--message "<agent message>" [--deliver] [--channel last|whatsapp|telegram|discord] [--to <dest>]`
- `--message "<agent message>" [--deliver] [--channel last|whatsapp|telegram|discord|signal|imessage] [--to <dest>]`
- `clawdis cron edit <id> ...` (patch-by-flags, non-interactive)
- `clawdis cron rm <id>`

56
docs/groups.md Normal file
View File

@@ -0,0 +1,56 @@
---
summary: "Group chat behavior across surfaces (WhatsApp/Telegram/Discord/iMessage)"
read_when:
- Changing group chat behavior or mention gating
---
# Groups
Clawdis treats group chats consistently across surfaces: WhatsApp, Telegram, Discord, iMessage.
## Session keys
- Group sessions use `group:<id>` in `ctx.From`.
- Direct chats use the main session (or per-sender if configured).
- Heartbeats are skipped for group sessions.
## Mention gating (default)
Group messages require a mention unless overridden per group.
```json5
{
routing: {
groupChat: {
requireMention: true,
mentionPatterns: ["@clawd", "clawdbot", "\\+15555550123"],
historyLimit: 50
}
}
}
```
Notes:
- `mentionPatterns` are case-insensitive regexes.
- Surfaces that provide explicit mentions still pass; patterns are a fallback.
## Activation (owner-only)
Group owners can toggle per-group activation:
- `/activation mention`
- `/activation always`
Owner is determined by `routing.allowFrom` (or the bots default identity when unset).
## Context fields
Group inbound payloads set:
- `ChatType=group`
- `GroupSubject` (if known)
- `GroupMembers` (if known)
- `WasMentioned` (mention gating result)
The agent system prompt includes a group intro on the first turn of a new group session.
## iMessage specifics
- Prefer `chat_id:<id>` when routing or allowlisting.
- List chats: `imsg chats --limit 20`.
- Group replies always go back to the same `chat_id`.
## WhatsApp specifics
See `docs/group-messages.md` for WhatsApp-only behavior (history injection, mention handling details).

63
docs/imessage.md Normal file
View File

@@ -0,0 +1,63 @@
---
summary: "iMessage support via imsg (JSON-RPC over stdio), setup, and chat_id routing"
read_when:
- Setting up iMessage support
- Debugging iMessage send/receive
---
# iMessage (imsg)
Status: external CLI integration. No daemon.
## Model
- Clawdis spawns `imsg rpc` as a child process.
- JSON-RPC runs over stdin/stdout (one JSON object per line).
- Gateway owns the process; no TCP port needed.
## Requirements
- macOS with Messages signed in.
- Full Disk Access for Clawdis + the `imsg` binary (Messages DB access).
- Automation permission for Messages when sending.
## Config
```json5
{
imessage: {
enabled: true,
cliPath: "imsg",
dbPath: "~/Library/Messages/chat.db",
allowFrom: ["+15555550123", "user@example.com", "chat_id:123"],
includeAttachments: false,
mediaMaxMb: 16,
service: "auto",
region: "US"
}
}
```
Notes:
- `allowFrom` accepts handles (phone/email) or `chat_id:<id>` entries.
- `service` defaults to `auto` (use `imessage` or `sms` to pin).
- `region` is only used for SMS targeting.
## Addressing / targets
Prefer `chat_id` for stable routing:
- `chat_id:123` (preferred)
- `chat_guid:...` (fallback)
- `chat_identifier:...` (fallback)
- direct handles: `imessage:+1555` / `sms:+1555` / `user@example.com`
List chats:
```
imsg chats --limit 20
```
## Group chat behavior
- Group messages set `ChatType=group`, `GroupSubject`, and `GroupMembers`.
- Group activation respects `routing.groupChat.requireMention` and `mentionPatterns`.
- Replies go back to the same `chat_id` (group or direct).
## Troubleshooting
- `clawdis gateway call providers.status --params '{"probe":true}'`
- Verify `imsg` is on PATH and has access to Messages DB.

View File

@@ -13,7 +13,7 @@ read_when:
</p>
<p align="center">
<strong>WhatsApp + Telegram + Discord gateway for AI agents (Pi).</strong><br>
<strong>WhatsApp + Telegram + Discord + iMessage gateway for AI agents (Pi).</strong><br>
Send a message, get an agent response — from your pocket.
</p>
@@ -23,7 +23,7 @@ read_when:
<a href="./clawd">Clawd setup</a>
</p>
CLAWDIS bridges WhatsApp (via WhatsApp Web / Baileys), Telegram (Bot API / grammY), and Discord (Bot API / discord.js) to coding agents like [Pi](https://github.com/badlogic/pi-mono).
CLAWDIS bridges WhatsApp (via WhatsApp Web / Baileys), Telegram (Bot API / grammY), Discord (Bot API / discord.js), and iMessage (imsg CLI) to coding agents like [Pi](https://github.com/badlogic/pi-mono).
Its built for [Clawd](https://clawd.me), a space lobster who needed a TARDIS.
## How it works
@@ -61,6 +61,7 @@ Most operations flow through the **Gateway** (`clawdis gateway`), a single long-
- 📱 **WhatsApp Integration** — Uses Baileys for WhatsApp Web protocol
- ✈️ **Telegram Bot** — DMs + groups via grammY
- 🎮 **Discord Bot** — DMs + guild channels via discord.js
- 💬 **iMessage** — Local imsg CLI integration (macOS)
- 🤖 **Agent bridge** — Pi (RPC mode) with tool streaming
- 💬 **Sessions** — Direct chats collapse into shared `main` (default); groups are isolated
- 👥 **Group Chat Support** — Mention-based by default; owner can toggle `/activation always|mention`
@@ -121,6 +122,7 @@ Example:
- [Skills](./skills.md)
- [Skills config](./skills-config.md)
- [Workspace templates](./templates/AGENTS.md)
- [RPC adapters](./rpc.md)
- [Gateway runbook](./gateway.md)
- [Nodes (iOS/Android)](./nodes.md)
- [Web surfaces (Control UI)](./web.md)
@@ -131,7 +133,9 @@ Example:
- [Control UI (browser)](./control-ui.md)
- [Telegram](./telegram.md)
- [Discord](./discord.md)
- [Group messages](./group-messages.md)
- [iMessage](./imessage.md)
- [Groups](./groups.md)
- [WhatsApp group messages](./group-messages.md)
- [Media: images](./images.md)
- [Media: audio](./audio.md)
- Ops and safety:

35
docs/rpc.md Normal file
View File

@@ -0,0 +1,35 @@
---
summary: "RPC adapters for external CLIs (signal-cli, imsg) and gateway patterns"
read_when:
- Adding or changing external CLI integrations
- Debugging RPC adapters (signal-cli, imsg)
---
# RPC adapters
Clawdis integrates external CLIs via JSON-RPC. Two patterns are used today.
## Pattern A: HTTP daemon (signal-cli)
- `signal-cli` runs as a daemon with JSON-RPC over HTTP.
- Event stream is SSE (`/api/v1/events`).
- Health probe: `/api/v1/check`.
- Clawdis owns lifecycle when `signal.autoStart=true`.
See `docs/signal.md` for setup and endpoints.
## Pattern B: stdio child process (imsg)
- Clawdis spawns `imsg rpc` as a child process.
- JSON-RPC is line-delimited over stdin/stdout (one JSON object per line).
- No TCP port, no daemon required.
Core methods used:
- `watch.subscribe` → notifications (`method: "message"`)
- `watch.unsubscribe`
- `send`
- `chats.list` (probe/diagnostics)
See `docs/imessage.md` for setup and addressing (`chat_id` preferred).
## Adapter guidelines
- Gateway owns the process (start/stop tied to provider lifecycle).
- Keep RPC clients resilient: timeouts, restart on exit.
- Prefer stable IDs (e.g., `chat_id`) over display strings.

View File

@@ -9,12 +9,12 @@ Updated: 2025-12-07
Goal: make replies deterministic per channel while keeping one shared context for direct chats.
- **Surfaces** (channel labels): `whatsapp`, `webchat`, `telegram`, `discord`, `voice`, etc. Add `Surface` to inbound `MsgContext` so templates/agents can log which channel a turn came from. Routing is fixed: replies go back to the origin surface; the model doesnt choose.
- **Surfaces** (channel labels): `whatsapp`, `webchat`, `telegram`, `discord`, `imessage`, `voice`, etc. Add `Surface` to inbound `MsgContext` so templates/agents can log which channel a turn came from. Routing is fixed: replies go back to the origin surface; the model doesnt choose.
- **Reply context:** inbound replies include `ReplyToId`, `ReplyToBody`, and `ReplyToSender`, and the quoted context is appended to `Body` as a `[Replying to ...]` block.
- **Canonical direct session:** All direct chats collapse into the single `main` session by default (no config needed). Groups stay `group:<jid>`, so they remain isolated.
- **Session store:** Keys are resolved via `resolveSessionKey(scope, ctx, mainKey)`; the agent JSONL path lives under `~/.clawdis/sessions/<SessionId>.jsonl`.
- **WebChat:** Always attaches to `main`, loads the full session transcript so desktop reflects cross-surface history, and writes new turns back to the same session.
- **Implementation hints:**
- Set `Surface` in each ingress (WhatsApp gateway, WebChat bridge, Telegram, Discord).
- Set `Surface` in each ingress (WhatsApp gateway, WebChat bridge, Telegram, Discord, iMessage).
- Keep routing deterministic: originate → same surface. Use the gateway WebSocket for sends; avoid side channels.
- Do not let the agent emit “send to X” decisions; keep that policy in the host code.

View File

@@ -65,6 +65,7 @@ It does **not** install or change anything on the remote host.
- Telegram: bot token.
- Discord: bot token.
- Signal: optional `signal-cli` install + account config.
- iMessage: local `imsg` CLI path + DB access.
6) **Daemon install**
- macOS: LaunchAgent
@@ -131,7 +132,7 @@ Typical fields in `~/.clawdis/clawdis.json`:
- `agent.workspace`
- `agent.model` / `models.providers` (if Minimax chosen)
- `gateway.*` (mode, bind, auth, tailscale)
- `telegram.botToken`, `discord.token`, `signal.*`
- `telegram.botToken`, `discord.token`, `signal.*`, `imessage.*`
- `skills.install.nodeManager`
- `wizard.lastRunAt`
- `wizard.lastRunVersion`
@@ -146,5 +147,5 @@ Sessions are stored under `~/.clawdis/sessions/`.
- macOS app onboarding: `docs/onboarding.md`
- Config reference: `docs/configuration.md`
- Providers: `docs/whatsapp.md`, `docs/telegram.md`, `docs/discord.md`, `docs/signal.md`
- Providers: `docs/whatsapp.md`, `docs/telegram.md`, `docs/discord.md`, `docs/signal.md`, `docs/imessage.md`
- Skills: `docs/skills.md`, `docs/skills-config.md`