docs: align channels naming

This commit is contained in:
Peter Steinberger
2026-01-13 06:51:20 +00:00
parent 993c1de361
commit 72a48c4992
12 changed files with 123 additions and 114 deletions

View File

@@ -204,7 +204,7 @@ Details: [Tailscale guide](https://docs.clawd.bot/gateway/tailscale) · [Web sur
Its perfectly fine to run the Gateway on a small Linux instance. Clients (macOS app, CLI, WebChat) can connect over **Tailscale Serve/Funnel** or **SSH tunnels**, and you can still pair device nodes (macOS/iOS/Android) to execute devicelocal actions when needed.
- **Gateway host** runs the exec tool and provider connections by default.
- **Gateway host** runs the exec tool and channel connections by default.
- **Device nodes** run devicelocal actions (`system.run`, camera, screen recording, notifications) via `node.invoke`.
In short: exec runs where the Gateway lives; device actions run where the device lives.
@@ -317,50 +317,54 @@ Details: [Security guide](https://docs.clawd.bot/gateway/security) · [Docker +
### [WhatsApp](https://docs.clawd.bot/channels/whatsapp)
- Link the device: `pnpm clawdbot providers login` (stores creds in `~/.clawdbot/credentials`).
- Allowlist who can talk to the assistant via `whatsapp.allowFrom`.
- If `whatsapp.groups` is set, it becomes a group allowlist; include `"*"` to allow all.
- Link the device: `pnpm clawdbot channels login` (stores creds in `~/.clawdbot/credentials`).
- Allowlist who can talk to the assistant via `channels.whatsapp.allowFrom`.
- If `channels.whatsapp.groups` is set, it becomes a group allowlist; include `"*"` to allow all.
### [Telegram](https://docs.clawd.bot/channels/telegram)
- Set `TELEGRAM_BOT_TOKEN` or `telegram.botToken` (env wins).
- Optional: set `telegram.groups` (with `telegram.groups."*".requireMention`); when set, it is a group allowlist (include `"*"` to allow all). Also `telegram.allowFrom` or `telegram.webhookUrl` as needed.
- Set `TELEGRAM_BOT_TOKEN` or `channels.telegram.botToken` (env wins).
- Optional: set `channels.telegram.groups` (with `channels.telegram.groups."*".requireMention`); when set, it is a group allowlist (include `"*"` to allow all). Also `channels.telegram.allowFrom` or `channels.telegram.webhookUrl` as needed.
```json5
{
telegram: {
botToken: "123456:ABCDEF"
channels: {
telegram: {
botToken: "123456:ABCDEF"
}
}
}
```
### [Slack](https://docs.clawd.bot/channels/slack)
- Set `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN` (or `slack.botToken` + `slack.appToken`).
- Set `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN` (or `channels.slack.botToken` + `channels.slack.appToken`).
### [Discord](https://docs.clawd.bot/channels/discord)
- Set `DISCORD_BOT_TOKEN` or `discord.token` (env wins).
- Optional: set `commands.native`, `commands.text`, or `commands.useAccessGroups`, plus `discord.dm.allowFrom`, `discord.guilds`, or `discord.mediaMaxMb` as needed.
- Set `DISCORD_BOT_TOKEN` or `channels.discord.token` (env wins).
- Optional: set `commands.native`, `commands.text`, or `commands.useAccessGroups`, plus `channels.discord.dm.allowFrom`, `channels.discord.guilds`, or `channels.discord.mediaMaxMb` as needed.
```json5
{
discord: {
token: "1234abcd"
channels: {
discord: {
token: "1234abcd"
}
}
}
```
### [Signal](https://docs.clawd.bot/channels/signal)
- Requires `signal-cli` and a `signal` config section.
- Requires `signal-cli` and a `channels.signal` config section.
### [iMessage](https://docs.clawd.bot/channels/imessage)
- macOS only; Messages must be signed in.
- If `imessage.groups` is set, it becomes a group allowlist; include `"*"` to allow all.
- If `channels.imessage.groups` is set, it becomes a group allowlist; include `"*"` to allow all.
### [Microsoft Teams](https://docs.clawd.bot/providers/msteams)
### [Microsoft Teams](https://docs.clawd.bot/channels/msteams)
- Configure a Teams app + Bot Framework, then add a `msteams` config section.
- Allowlist who can talk via `msteams.allowFrom`; group access via `msteams.groupAllowFrom` or `msteams.groupPolicy: "open"`.

View File

@@ -192,7 +192,7 @@ clawdbot cron add \
--session isolated \
--message "Summarize inbox + calendar for today." \
--deliver \
--provider whatsapp \
--channel whatsapp \
--to "+15551234567"
```
@@ -205,7 +205,7 @@ clawdbot cron add \
--session isolated \
--message "Summarize today; send to the nightly topic." \
--deliver \
--provider telegram \
--channel telegram \
--to "-1001234567890:topic:123"
```
@@ -220,7 +220,7 @@ clawdbot cron add \
--model "opus" \
--thinking high \
--deliver \
--provider whatsapp \
--channel whatsapp \
--to "+15551234567"
Agent selection (multi-agent setups):

View File

@@ -7,8 +7,8 @@ read_when:
# Polls
## Supported providers
- WhatsApp (web provider)
## Supported channels
- WhatsApp (web channel)
- Discord
- MS Teams (Adaptive Cards)
@@ -22,18 +22,18 @@ clawdbot message poll --to 123456789@g.us \
--poll-question "Meeting time?" --poll-option "10am" --poll-option "2pm" --poll-option "4pm" --poll-multi
# Discord
clawdbot message poll --provider discord --to channel:123456789 \
clawdbot message poll --channel discord --to channel:123456789 \
--poll-question "Snack?" --poll-option "Pizza" --poll-option "Sushi"
clawdbot message poll --provider discord --to channel:123456789 \
clawdbot message poll --channel discord --to channel:123456789 \
--poll-question "Plan?" --poll-option "A" --poll-option "B" --poll-duration-hours 48
# MS Teams
clawdbot message poll --provider msteams --to conversation:19:abc@thread.tacv2 \
clawdbot message poll --channel msteams --to conversation:19:abc@thread.tacv2 \
--poll-question "Lunch?" --poll-option "Pizza" --poll-option "Sushi"
```
Options:
- `--provider`: `whatsapp` (default), `discord`, or `msteams`
- `--channel`: `whatsapp` (default), `discord`, or `msteams`
- `--poll-multi`: allow selecting multiple options
- `--poll-duration-hours`: Discord-only (defaults to 24 when omitted)
@@ -47,16 +47,16 @@ Params:
- `options` (string[], required)
- `maxSelections` (number, optional)
- `durationHours` (number, optional)
- `provider` (string, optional, default: `whatsapp`)
- `channel` (string, optional, default: `whatsapp`)
- `idempotencyKey` (string, required)
## Provider differences
## Channel differences
- WhatsApp: 2-12 options, `maxSelections` must be within option count, ignores `durationHours`.
- Discord: 2-10 options, `durationHours` clamped to 1-768 hours (default 24). `maxSelections > 1` enables multi-select; Discord does not support a strict selection count.
- MS Teams: Adaptive Card polls (Clawdbot-managed). No native poll API; `durationHours` is ignored.
## Agent tool (Message)
Use the `message` tool with `poll` action (`to`, `pollQuestion`, `pollOption`, optional `pollMulti`, `pollDurationHours`, `provider`).
Use the `message` tool with `poll` action (`to`, `pollQuestion`, `pollOption`, optional `pollMulti`, `pollDurationHours`, `channel`).
Note: Discord has no “pick exactly N” mode; `pollMulti` maps to multi-select.
Teams polls are rendered as Adaptive Cards and require the gateway to stay online

View File

@@ -58,7 +58,7 @@ Payload:
"sessionKey": "hook:email:msg-123",
"wakeMode": "now",
"deliver": true,
"provider": "last",
"channel": "last",
"to": "+15551234567",
"model": "openai/gpt-5.2-mini",
"thinking": "low",
@@ -70,9 +70,9 @@ Payload:
- `name` optional (string): Human-readable name for the hook (e.g., "GitHub"), used as a prefix in session summaries.
- `sessionKey` optional (string): The key used to identify the agent's session. Defaults to a random `hook:<uuid>`. Using a consistent key allows for a multi-turn conversation within the hook context.
- `wakeMode` optional (`now` | `next-heartbeat`): Whether to trigger an immediate heartbeat (default `now`) or wait for the next periodic check.
- `deliver` optional (boolean): If `true`, the agent's response will be sent to the messaging provider. Defaults to `true`. Responses that are only heartbeat acknowledgments are automatically skipped.
- `provider` optional (string): The messaging service for delivery. One of: `last`, `whatsapp`, `telegram`, `discord`, `slack`, `signal`, `imessage`, `msteams`. Defaults to `last`.
- `to` optional (string): The recipient identifier for the provider (e.g., phone number for WhatsApp/Signal, chat ID for Telegram, channel ID for Discord/Slack, conversation ID for MS Teams). Defaults to the last recipient in the main session.
- `deliver` optional (boolean): If `true`, the agent's response will be sent to the messaging channel. Defaults to `true`. Responses that are only heartbeat acknowledgments are automatically skipped.
- `channel` optional (string): The messaging channel for delivery. One of: `last`, `whatsapp`, `telegram`, `discord`, `slack`, `signal`, `imessage`, `msteams`. Defaults to `last`.
- `to` optional (string): The recipient identifier for the channel (e.g., phone number for WhatsApp/Signal, chat ID for Telegram, channel ID for Discord/Slack, conversation ID for MS Teams). Defaults to the last recipient in the main session.
- `model` optional (string): Model override (e.g., `anthropic/claude-3-5-sonnet` or an alias). Must be in the allowed model list if restricted.
- `thinking` optional (string): Thinking level override (e.g., `low`, `medium`, `high`).
- `timeoutSeconds` optional (number): Maximum duration for the agent run in seconds.
@@ -94,8 +94,8 @@ Mapping options (summary):
- `hooks.transformsDir` + `transform.module` loads a JS/TS module for custom logic.
- Use `match.source` to keep a generic ingest endpoint (payload-driven routing).
- TS transforms require a TS loader (e.g. `bun` or `tsx`) or precompiled `.js` at runtime.
- Set `deliver: true` + `provider`/`to` on mappings to route replies to a chat surface
(`provider` defaults to `last` and falls back to WhatsApp).
- Set `deliver: true` + `channel`/`to` on mappings to route replies to a chat surface
(`channel` defaults to `last` and falls back to WhatsApp).
- `clawdbot hooks gmail setup` writes `hooks.gmail` config for `clawdbot hooks gmail run`.
See [Gmail Pub/Sub](/automation/gmail-pubsub) for the full Gmail watch flow.

View File

@@ -408,7 +408,7 @@ By default, Clawdbot only downloads media from Microsoft/Teams hostnames. Overri
## Polls (Adaptive Cards)
Clawdbot sends Teams polls as Adaptive Cards (there is no native Teams poll API).
- CLI: `clawdbot message poll --provider msteams --to conversation:<id> ...`
- CLI: `clawdbot message poll --channel msteams --to conversation:<id> ...`
- Votes are recorded by the gateway in `~/.clawdbot/msteams-polls.json`.
- The gateway must stay online to record votes.
- Polls do not auto-post result summaries yet (inspect the store file if needed).

View File

@@ -266,7 +266,7 @@ Outbound Telegram API calls retry on transient network/429 errors with exponenti
## Delivery targets (CLI/cron)
- Use a chat id (`123456789`) or a username (`@name`) as the target.
- Example: `clawdbot message send --provider telegram --to 123456789 --message "hi"`.
- Example: `clawdbot message send --channel telegram --to 123456789 --message "hi"`.
## Troubleshooting

View File

@@ -387,7 +387,7 @@ Subcommands:
Examples:
- `clawdbot message send --to +15555550123 --message "Hi"`
- `clawdbot message poll --provider discord --to channel:123 --poll-question "Snack?" --poll-option Pizza --poll-option Sushi`
- `clawdbot message poll --channel discord --to channel:123 --poll-question "Snack?" --poll-option Pizza --poll-option Sushi`
### `agent`
Run one agent turn via the Gateway (or `--local` embedded).
@@ -400,7 +400,7 @@ Options:
- `--session-id <id>`
- `--thinking <off|minimal|low|medium|high|xhigh>` (GPT-5.2 + Codex models only)
- `--verbose <on|off>`
- `--provider <whatsapp|telegram|discord|slack|signal|imessage>`
- `--channel <whatsapp|telegram|discord|slack|signal|imessage>`
- `--local`
- `--deliver`
- `--json`
@@ -443,7 +443,7 @@ Options:
- `--json`
- `--all` (full diagnosis; read-only, pasteable)
- `--deep` (probe channels)
- `--usage` (show provider usage/quota)
- `--usage` (show model provider usage/quota)
- `--timeout <ms>`
- `--verbose`
- `--debug` (alias for `--verbose`)

View File

@@ -1,13 +1,13 @@
---
summary: "CLI reference for `clawdbot message` (send + provider actions)"
summary: "CLI reference for `clawdbot message` (send + channel actions)"
read_when:
- Adding or modifying message CLI actions
- Changing outbound provider behavior
- Changing outbound channel behavior
---
# `clawdbot message`
Single outbound command for sending messages and provider actions
Single outbound command for sending messages and channel actions
(Discord/Slack/Telegram/WhatsApp/Signal/iMessage/MS Teams).
## Usage
@@ -16,9 +16,9 @@ Single outbound command for sending messages and provider actions
clawdbot message <subcommand> [flags]
```
Provider selection:
- `--provider` required if more than one provider is configured.
- If exactly one provider is configured, it becomes the default.
Channel selection:
- `--channel` required if more than one channel is configured.
- If exactly one channel is configured, it becomes the default.
- Values: `whatsapp|telegram|discord|slack|signal|imessage|msteams`
Target formats (`--to`):
@@ -32,7 +32,7 @@ Target formats (`--to`):
## Common flags
- `--provider <name>`
- `--channel <name>`
- `--account <id>`
- `--json`
- `--dry-run`
@@ -170,13 +170,13 @@ Target formats (`--to`):
Send a Discord reply:
```
clawdbot message send --provider discord \
clawdbot message send --channel discord \
--to channel:123 --message "hi" --reply-to 456
```
Create a Discord poll:
```
clawdbot message poll --provider discord \
clawdbot message poll --channel discord \
--to channel:123 \
--poll-question "Snack?" \
--poll-option Pizza --poll-option Sushi \
@@ -185,13 +185,13 @@ clawdbot message poll --provider discord \
Send a Teams proactive message:
```
clawdbot message send --provider msteams \
clawdbot message send --channel msteams \
--to conversation:19:abc@thread.tacv2 --message "hi"
```
Create a Teams poll:
```
clawdbot message poll --provider msteams \
clawdbot message poll --channel msteams \
--to conversation:19:abc@thread.tacv2 \
--poll-question "Lunch?" \
--poll-option Pizza --poll-option Sushi
@@ -199,12 +199,12 @@ clawdbot message poll --provider msteams \
React in Slack:
```
clawdbot message react --provider slack \
clawdbot message react --channel slack \
--to C123 --message-id 456 --emoji "✅"
```
Send Telegram inline buttons:
```
clawdbot message send --provider telegram --to @mychat --message "Choose:" \
clawdbot message send --channel telegram --to @mychat --message "Choose:" \
--buttons '[ [{"text":"Yes","callback_data":"cmd:yes"}], [{"text":"No","callback_data":"cmd:no"}] ]'
```

View File

@@ -541,6 +541,14 @@
"source": "/concepts/provider-routing/",
"destination": "/concepts/channel-routing"
},
{
"source": "/refactor/provider-plugin",
"destination": "/refactor/channel-plugin"
},
{
"source": "/refactor/provider-plugin/",
"destination": "/refactor/channel-plugin"
},
{
"source": "/queue",
"destination": "/concepts/queue"

View File

@@ -167,23 +167,23 @@ ENV NODE_ENV=production
CMD ["node","dist/index.js"]
```
### Provider setup (optional)
### Channel setup (optional)
Use the CLI container to configure providers, then restart the gateway if needed.
Use the CLI container to configure channels, then restart the gateway if needed.
WhatsApp (QR):
```bash
docker compose run --rm clawdbot-cli providers login
docker compose run --rm clawdbot-cli channels login
```
Telegram (bot token):
```bash
docker compose run --rm clawdbot-cli providers add --provider telegram --token "<token>"
docker compose run --rm clawdbot-cli channels add --channel telegram --token "<token>"
```
Discord (bot token):
```bash
docker compose run --rm clawdbot-cli providers add --provider discord --token "<token>"
docker compose run --rm clawdbot-cli channels add --channel discord --token "<token>"
```
Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord)

View File

@@ -1,83 +1,80 @@
---
summary: "Provider plugin refactor implementation notes (registry, status, gateway/runtime)"
summary: "Channel plugin refactor implementation notes (registry, status, gateway/runtime)"
read_when:
- Adding or refactoring provider plugin wiring
- Moving provider-specific behavior into plugin hooks
- Adding or refactoring channel plugin wiring
- Moving channel-specific behavior into plugin hooks
---
# Provider Plugin Refactor — Implementation Notes
# Channel Plugins — Implementation Notes
Goal: make providers (iMessage, Discord, etc.) pluggable with minimal wiring and shared UX/state paths.
Goal: make chat channels (iMessage, Discord, etc.) pluggable with minimal wiring and shared UX/state paths.
## Architecture Overview
- Registry: `src/providers/plugins/index.ts` owns the plugin list.
- Provider dock: `src/providers/dock.ts` owns lightweight provider metadata used by shared flows (reply, command auth, block streaming) without importing full plugins.
- IDs/aliases: `src/providers/registry.ts` owns stable provider ids + input aliases.
- Shape: `src/providers/plugins/types.ts` defines the plugin contract.
- Gateway: `src/gateway/server-providers.ts` drives start/stop + runtime snapshots via plugins.
- Registry: `src/channels/plugins/index.ts` owns the plugin list.
- Channel dock: `src/channels/dock.ts` owns lightweight channel metadata used by shared flows (reply, command auth, block streaming) without importing full plugins.
- IDs/aliases: `src/channels/registry.ts` owns stable channel ids + input aliases.
- Shape: `src/channels/plugins/types.ts` defines the plugin contract.
- Gateway: `src/gateway/server-channels.ts` drives start/stop + runtime snapshots via plugins.
- Outbound: `src/infra/outbound/deliver.ts` routes through plugin outbound when present.
- Outbound delivery loads **outbound adapters** on-demand via `src/providers/plugins/outbound/load.ts` (avoid importing heavy provider plugins on hot paths).
- Outbound delivery loads **outbound adapters** on-demand via `src/channels/plugins/outbound/load.ts` (avoid importing heavy channel plugins on hot paths).
- Reload: `src/gateway/config-reload.ts` uses plugin `reload.configPrefixes` lazily (avoid init cycles).
- CLI: `src/commands/providers/*` uses plugin list for add/remove/status/list.
- Protocol: `src/gateway/protocol/schema.ts` (v3) makes provider-shaped responses container-generic (maps keyed by provider id).
- CLI: `src/commands/channels/*` uses plugin list for add/remove/status/list.
- Protocol: `src/gateway/protocol/schema.ts` keeps `channels.status` schema-light (maps keyed by channel id).
## Plugin Contract (high-level)
Each `ProviderPlugin` bundles:
Each `ChannelPlugin` bundles:
- `meta`: id/labels/docs/sort order.
- `capabilities`: chatTypes + optional features (polls, media, nativeCommands, etc.).
- `config`: list/resolve/default/isConfigured/describeAccount + isEnabled + (un)configured reasons + `resolveAllowFrom` + `formatAllowFrom`.
- `outbound`: deliveryMode + chunker + resolveTarget (mode-aware) + sendText/sendMedia/sendPoll + pollMaxOptions.
- `status`: defaultRuntime + probe/audit/buildAccountSnapshot + buildProviderSummary + logSelfId + collectStatusIssues.
- `status`: defaultRuntime + probe/audit/buildAccountSnapshot + buildChannelSummary + logSelfId + collectStatusIssues.
- `gateway`: startAccount/stopAccount with runtime context (`getStatus`/`setStatus`), plus optional `loginWithQrStart/loginWithQrWait` for gateway-owned QR login flows.
- `security`: dmPolicy + allowFrom hints used by `doctor security`.
- `heartbeat`: optional readiness checks + heartbeat recipient resolution when providers own targeting.
- `auth`: optional login hook used by `clawdbot channels login`.
- `reload`: `configPrefixes` that map to hot restarts.
- `onboarding`: optional CLI onboarding adapter (wizard UI hooks per provider).
- `agentTools`: optional provider-owned agent tools (ex: QR login).
- `onboarding`: optional CLI onboarding adapter (wizard UI hooks per channel).
- `agentTools`: optional channel-owned agent tools (ex: QR login).
## Key Integration Notes
- `listProviderPlugins()` is the runtime source of truth for provider UX and wiring.
- Avoid importing `src/providers/plugins/index.ts` from shared modules (reply flow, command auth, sandbox explain). Its intentionally “heavy” (providers may pull web login / monitor code). Use `getProviderDock()` + `normalizeProviderId()` for cheap metadata, and only `getProviderPlugin()` at execution boundaries (ex: `src/auto-reply/reply/route-reply.ts`).
- `listChannelPlugins()` is the runtime source of truth for channel UX and wiring.
- Avoid importing `src/channels/plugins/index.ts` from shared modules (reply flow, command auth, sandbox explain). Its intentionally “heavy” (channels may pull web login / monitor code). Use `getChannelDock()` + `normalizeChannelId()` (from `src/channels/registry.ts`) for cheap metadata, and only `getChannelPlugin()` at execution boundaries (ex: `src/auto-reply/reply/route-reply.ts`).
- WhatsApp plugin keeps Baileys-heavy login bits behind lazy imports; cheap auth file checks live in `src/web/auth-store.ts` (so outbound routing doesnt pay Baileys import cost).
- `routeReply` delegates sending to plugin `outbound` adapters via a lazy import of `src/infra/outbound/deliver.ts` (so adding a provider is “just implement outbound adapter”, no router switches).
- Avoid static imports of provider monitors inside plugin modules. Monitors typically import the reply pipeline, which can create ESM cycles (and break Vite/Vitest SSR with TDZ errors). Prefer lazy imports inside `gateway.startAccount`.
- Debug cycle leaks quickly with: `npx -y madge --circular src/providers/plugins/index.ts`.
- Gateway protocol schema keeps provider selection as an open-ended string (no provider enum / static list) to avoid init cycles and so new plugins dont require protocol changes.
- Protocol v3: no more per-provider fields in `providers.status`; consumers must read map entries by provider id.
- `DEFAULT_CHAT_PROVIDER` lives in `src/providers/registry.ts` and is used anywhere we need a fallback delivery surface.
- Provider reload rules are computed lazily to avoid static init cycles in tests.
- Signal/iMessage media size limits are now resolved inside their plugins.
- `normalizeProviderId()` handles aliases (ex: `imsg`, `teams`) so CLI and API inputs stay stable.
- `ProviderId` is `ChatProviderId` (no extra special-cased provider IDs in shared code).
- Gateway runtime defaults (`status.defaultRuntime`) replace the old per-provider runtime map.
- Gateway runtime snapshot (`getRuntimeSnapshot`) is map-based: `{ providers, providerAccounts }` (no `${id}Accounts` keys).
- `providers.status` response keys (v3):
- `providerOrder: string[]`
- `providerLabels: Record<string, string>`
- `providers: Record<string, unknown>` (provider summary objects, plugin-defined)
- `providerAccounts: Record<string, ProviderAccountSnapshot[]>`
- `providerDefaultAccountId: Record<string, string>`
- `providers.status` summary objects come from `status.buildProviderSummary` (no per-provider branching in the handler).
- `providers.status` warnings now flow through `status.collectStatusIssues` per plugin.
- `routeReply` delegates sending to plugin `outbound` adapters via a lazy import of `src/infra/outbound/deliver.ts` (so adding a channel is “just implement outbound adapter”, no router switches).
- Avoid static imports of channel monitors inside plugin modules. Monitors typically import the reply pipeline, which can create ESM cycles (and break Vite/Vitest SSR with TDZ errors). Prefer lazy imports inside `gateway.startAccount`.
- Debug cycle leaks quickly with: `npx -y madge --circular src/channels/plugins/index.ts`.
- Protocol v3: `channels.status` is map-based and schema-light so new channels can ship without protocol updates.
- `DEFAULT_CHAT_CHANNEL` lives in `src/channels/registry.ts` and is used anywhere we need a fallback delivery surface.
- Channel reload rules are computed lazily to avoid static init cycles in tests.
- Signal/iMessage media size limits are resolved inside their plugins.
- `normalizeChannelId()` handles aliases (ex: `imsg`, `teams`) so CLI and API inputs stay stable.
- Gateway runtime snapshot (`getRuntimeSnapshot`) is map-based: `{ channels, channelAccounts }` (no `${id}Accounts` keys).
- `channels.status` response keys (v3):
- `channelOrder: string[]`
- `channelLabels: Record<string, string>`
- `channels: Record<string, unknown>` (channel summary objects, plugin-defined)
- `channelAccounts: Record<string, ChannelAccountSnapshot[]>`
- `channelDefaultAccountId: Record<string, string>`
- `channels.status` summary objects come from `status.buildChannelSummary` (no per-channel branching in the handler).
- `channels.status` warnings flow through `status.collectStatusIssues` per plugin.
- CLI list uses `meta.showConfigured` to decide whether to show configured state.
- CLI provider options and prompt provider lists are generated from `listProviderPlugins()` (avoid hardcoded arrays).
- Provider selection (`resolveMessageProviderSelection`) now inspects `config.isEnabled` + `config.isConfigured` per plugin instead of hardcoded provider checks.
- Pairing flows (CLI + store) now use `plugin.pairing` (`idLabel`, `normalizeAllowEntry`, `notifyApproval`) via `src/providers/plugins/pairing.ts`.
- CLI provider remove/disable delegates to `config.setAccountEnabled` + `config.deleteAccount` per plugin.
- CLI provider add now delegates to `plugin.setup` for account validation, naming, and config writes (no hardcoded provider checks).
- Agent provider status entries are now built from plugin config/status (`status.resolveAccountState` for custom state labels).
- Agent binding defaults use `meta.forceAccountBinding` to avoid hardcoded provider checks.
- Onboarding quickstart allowlist uses `meta.quickstartAllowFrom` to avoid hardcoded provider lists.
- `resolveProviderDefaultAccountId()` is the shared helper for picking default accounts from `accountIds` + plugin config.
- `routeReply` uses plugin outbound senders; `ProviderOutboundContext` supports `replyToId` + `threadId` and outbound delivery supports `abortSignal` for cooperative cancellation.
- Outbound target resolution (`resolveOutboundTarget`) now delegates to `plugin.outbound.resolveTarget` (mode-aware, uses config allowlists when present).
- Outbound delivery results accept `meta` for provider-specific fields to avoid core type churn in new plugins.
- Channel selection (`resolveMessageChannelSelection`) inspects `config.isEnabled` + `config.isConfigured` per plugin instead of hardcoded checks.
- Pairing flows (CLI + store) use `plugin.pairing` (`idLabel`, `normalizeAllowEntry`, `notifyApproval`) via `src/channels/plugins/pairing.ts`.
- CLI channel remove/disable delegates to `config.setAccountEnabled` + `config.deleteAccount` per plugin.
- CLI channel add delegates to `plugin.setup` for account validation, naming, and config writes (no hardcoded checks).
- Agent channel status entries are built from plugin config/status (`status.resolveAccountState` for custom state labels).
- Agent binding defaults use `meta.forceAccountBinding` to avoid hardcoded checks.
- Onboarding quickstart allowlist uses `meta.quickstartAllowFrom` to avoid hardcoded channel lists.
- `resolveChannelDefaultAccountId()` is the shared helper for picking default accounts from `accountIds` + plugin config.
- `routeReply` uses plugin outbound senders; `ChannelOutboundContext` supports `replyToId` + `threadId` and outbound delivery supports `abortSignal` for cooperative cancellation.
- Outbound target resolution (`resolveOutboundTarget`) delegates to `plugin.outbound.resolveTarget` (mode-aware, uses config allowlists when present).
- Outbound delivery results accept `meta` for channel-specific fields to avoid core type churn in new plugins.
- Agent gateway routing sets `deliveryTargetMode` and uses `resolveOutboundTarget` for implicit fallback targets when `to` is missing.
- Elevated tool allowlists (`tools.elevated.allowFrom`) are a record keyed by provider id (no schema update needed when adding providers).
- Elevated tool allowlists (`tools.elevated.allowFrom`) are a record keyed by channel id (no schema update needed when adding channels).
- Block streaming defaults live on the plugin (`capabilities.blockStreaming`, `streaming.blockStreamingCoalesceDefaults`) instead of hardcoded provider checks.
- Provider logout now routes through `providers.logout` using `gateway.logoutAccount` on each plugin (clients should call the generic method).
- Gateway message-provider normalization uses `src/providers/registry.ts` for cheap validation/normalization without plugin init cycles.
- Channel logout routes through `channels.logout` using `gateway.logoutAccount` on each plugin (clients should call the generic method).
- Gateway message-channel normalization uses `src/channels/registry.ts` for cheap validation/normalization without plugin init cycles.
- Group mention gating now flows through `plugin.groups.resolveRequireMention` (Discord/Slack/Telegram/WhatsApp/iMessage) instead of branching in reply handlers.
- Command authorization uses `config.resolveAllowFrom` + `config.formatAllowFrom`, with `commands.enforceOwnerForCommands` and `commands.skipWhenConfigEmpty` driving provider-specific behavior.
- Security warnings (`doctor security`) use `plugin.security.resolveDmPolicy` + `plugin.security.collectWarnings`; supply `policyPath` + `allowFromPath` for accurate config hints.

View File

@@ -20,7 +20,7 @@ runtime on the current machine.
- Output:
- default: prints reply text (plus `MEDIA:<url>` lines)
- `--json`: prints structured payload + metadata
- Optional delivery back to a provider with `--deliver` + `--provider` (target formats match `clawdbot message --to`).
- Optional delivery back to a channel with `--deliver` + `--channel` (target formats match `clawdbot message --to`).
If the Gateway is unreachable, the CLI **falls back** to the embedded local run.
@@ -35,9 +35,9 @@ clawdbot agent --to +15555550123 --message "Summon reply" --deliver
## Flags
- `--local`: run locally (requires provider keys in your shell)
- `--deliver`: send the reply to the chosen provider (requires `--to`)
- `--provider`: `whatsapp|telegram|discord|slack|signal|imessage` (default: `whatsapp`)
- `--local`: run locally (requires model provider API keys in your shell)
- `--deliver`: send the reply to the chosen channel (requires `--to`)
- `--channel`: `whatsapp|telegram|discord|slack|signal|imessage` (default: `whatsapp`)
- `--thinking <off|minimal|low|medium|high|xhigh>`: persist thinking level (GPT-5.2 + Codex models only)
- `--verbose <on|off>`: persist verbose level
- `--timeout <seconds>`: override agent timeout