diff --git a/CHANGELOG.md b/CHANGELOG.md index a321b9eda3b..1d5819a586f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ Docs: https://docs.openclaw.ai - Discord/voice: make `openclaw channels capabilities --channel discord --target channel:` and `channels status --probe` audit voice-channel permissions, including auto-join targets, so missing Connect/Speak/Read Message History permissions show up before `/vc join`. - Channels CLI: make `openclaw channels list` channel-only — drop the `Auth providers (OAuth + API keys)` block (use `openclaw models auth list`), drop the per-provider usage/quota fetch and the `--no-usage` flag (use `openclaw status` or `openclaw models list`), add `--all` to surface bundled-unconfigured, catalog-not-installed, and catalog-installed-but-unconfigured channels, and render explicit `installed` / `configured` / `enabled` tags per row plus an `origin` + `installed` field in JSON. Fixes WeCom-class catalog channels disappearing from `--all` when installed on disk but not yet configured. (#78456) Thanks @sliverp. - CLI/cron: add computed `status` field to `cron list --json` and `cron show --json` output, mirroring the human-readable status column (disabled/running/ok/error/skipped/idle) so external tooling can determine job state without re-deriving it from raw state fields. (#78701) Thanks @aweiker. -- Docs/iMessage: deprecate BlueBubbles for new OpenClaw setups, document the upstream server-release rationale, and point new iMessage deployments toward the native `imsg` path while keeping BlueBubbles as a supported legacy fallback. +- Channels/iMessage: remove the bundled BlueBubbles channel surface and docs, make `imsg` the supported iMessage setup path, and report non-macOS default `imsg` configs with remote-Mac wrapper guidance. - Discord/voice: make voice capture less choppy by extending the default post-speech silence grace to 2.5s, add `voice.captureSilenceGraceMs` for noisy Discord sessions, and tighten the spoken-output prompt around live STT fragments. Thanks @vincentkoc. - Discord/streaming: default Discord replies to progress draft previews so tool/work activity appears in one edited Discord message unless `channels.discord.streaming.mode` is set to `off`. - OpenAI: support `openai/chat-latest` as an explicit direct API-key model override for trying the moving ChatGPT Instant API alias without changing the stable default model. @@ -153,7 +153,6 @@ Docs: https://docs.openclaw.ai - Compute plugin callback authorization dynamically [AI]. (#78866) Thanks @pgondhi987. - fix(active-memory): require admin scope for global toggles [AI]. (#78863) Thanks @pgondhi987. - Honor owner enforcement for native commands [AI]. (#78864) Thanks @pgondhi987. -- Config/BlueBubbles: remove the duplicate core-owned BlueBubbles config schema while preserving plugin-owned `dmPolicy` allowFrom validation for channel and account configs. Fixes #69238. Thanks @omarshahine. - Tavily: resolve dedicated `tavily_search` and `tavily_extract` tool credentials from the active runtime config snapshot, so `exec` SecretRef-backed API keys do not reach the tools unresolved. (#78610) Thanks @VACInc. - Gateway/sessions: clear cached skills snapshots during `/new` and `sessions.reset` so long-lived channel sessions rebuild the visible skill list after skills change. (#78873) Thanks @Evizero. - fix(auto-reply): gate inline skill tool dispatch [AI]. (#78517) Thanks @pgondhi987. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5b441bac09..d6a6298b84a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ Welcome to the lobster tank! 🦞 - **Ayaan Zaidi** - Telegram subsystem, Android app - GitHub: [@obviyus](https://github.com/obviyus) · X: [@obviyus](https://x.com/obviyus) -- **Tyler Yust** - Agents/subagents, cron, BlueBubbles, macOS app +- **Tyler Yust** - Agents/subagents, cron, iMessage, macOS app - GitHub: [@tyler6204](https://github.com/tyler6204) · X: [@tyleryust](https://x.com/tyleryust) - **Mariano Belinky** - iOS app, Security diff --git a/README.md b/README.md index 2dcc71e50ef..c4be5a4cab3 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ It answers you on the channels you already use. It can speak and listen on macOS If you want a personal, single-user assistant that feels local, fast, and always-on, this is it. -Supported channels include: WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, BlueBubbles, IRC, Microsoft Teams, Matrix, Feishu, LINE, Mattermost, Nextcloud Talk, Nostr, Synology Chat, Tlon, Twitch, Zalo, Zalo Personal, WeChat, QQ, WebChat. +Supported channels include: WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, IRC, Microsoft Teams, Matrix, Feishu, LINE, Mattermost, Nextcloud Talk, Nostr, Synology Chat, Tlon, Twitch, Zalo, Zalo Personal, WeChat, QQ, WebChat. [Website](https://openclaw.ai) · [Docs](https://docs.openclaw.ai) · [Vision](VISION.md) · [DeepWiki](https://deepwiki.com/openclaw/openclaw) · [Getting Started](https://docs.openclaw.ai/start/getting-started) · [Updating](https://docs.openclaw.ai/install/updating) · [Showcase](https://docs.openclaw.ai/start/showcase) · [FAQ](https://docs.openclaw.ai/help/faq) · [Onboarding](https://docs.openclaw.ai/start/wizard) · [Nix](https://github.com/openclaw/nix-openclaw) · [Docker](https://docs.openclaw.ai/install/docker) · [Discord](https://discord.gg/clawd) @@ -121,7 +121,7 @@ openclaw gateway --port 18789 --verbose # Send a message openclaw message send --target +1234567890 --message "Hello from OpenClaw" -# Talk to the assistant (optionally deliver back to any connected channel: WhatsApp/Telegram/Slack/Discord/Google Chat/Signal/iMessage/BlueBubbles/IRC/Microsoft Teams/Matrix/Feishu/LINE/Mattermost/Nextcloud Talk/Nostr/Synology Chat/Tlon/Twitch/Zalo/Zalo Personal/WeChat/QQ/WebChat) +# Talk to the assistant (optionally deliver back to any connected channel: WhatsApp/Telegram/Slack/Discord/Google Chat/Signal/iMessage/IRC/Microsoft Teams/Matrix/Feishu/LINE/Mattermost/Nextcloud Talk/Nostr/Synology Chat/Tlon/Twitch/Zalo/Zalo Personal/WeChat/QQ/WebChat) openclaw agent --message "Ship checklist" --thinking high ``` @@ -146,7 +146,7 @@ Run `openclaw doctor` to surface risky/misconfigured DM policies. ## Highlights - **[Local-first Gateway](https://docs.openclaw.ai/gateway)** — single control plane for sessions, channels, tools, and events. -- **[Multi-channel inbox](https://docs.openclaw.ai/channels)** — WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, BlueBubbles (iMessage), iMessage (legacy), IRC, Microsoft Teams, Matrix, Feishu, LINE, Mattermost, Nextcloud Talk, Nostr, Synology Chat, Tlon, Twitch, Zalo, Zalo Personal, WeChat, QQ, WebChat, macOS, iOS/Android. +- **[Multi-channel inbox](https://docs.openclaw.ai/channels)** — WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, IRC, Microsoft Teams, Matrix, Feishu, LINE, Mattermost, Nextcloud Talk, Nostr, Synology Chat, Tlon, Twitch, Zalo, Zalo Personal, WeChat, QQ, WebChat, macOS, iOS/Android. - **[Multi-agent routing](https://docs.openclaw.ai/gateway/configuration)** — route inbound channels/accounts/peers to isolated agents (workspaces + per-agent sessions). - **[Voice Wake](https://docs.openclaw.ai/nodes/voicewake) + [Talk Mode](https://docs.openclaw.ai/nodes/talk)** — wake words on macOS/iOS and continuous voice on Android (ElevenLabs + system TTS fallback). - **[Live Canvas](https://docs.openclaw.ai/platforms/mac/canvas)** — agent-driven visual workspace with [A2UI](https://docs.openclaw.ai/platforms/mac/canvas#canvas-a2ui). diff --git a/docs/.i18n/zh-Hans-navigation.json b/docs/.i18n/zh-Hans-navigation.json index da0ec3e87a0..1f2a7b1aebf 100644 --- a/docs/.i18n/zh-Hans-navigation.json +++ b/docs/.i18n/zh-Hans-navigation.json @@ -76,7 +76,6 @@ { "group": "消息平台", "pages": [ - "zh-CN/channels/bluebubbles", "zh-CN/channels/discord", "zh-CN/channels/feishu", "zh-CN/channels/grammy", diff --git a/docs/automation/standing-orders.md b/docs/automation/standing-orders.md index 33c2d7b2d7a..51bb285ff39 100644 --- a/docs/automation/standing-orders.md +++ b/docs/automation/standing-orders.md @@ -90,7 +90,7 @@ openclaw cron add \ --tz America/New_York \ --timeout-seconds 300 \ --announce \ - --channel bluebubbles \ + --channel imessage \ --to "+1XXXXXXXXXX" \ --message "Execute daily inbox triage per standing orders. Check mail for new alerts. Parse, categorize, and persist each item. Report summary to owner. Escalate unknowns." ``` diff --git a/docs/channels/groups.md b/docs/channels/groups.md index ce7e5d1b375..4c33e65fe43 100644 --- a/docs/channels/groups.md +++ b/docs/channels/groups.md @@ -482,10 +482,6 @@ Group inbound payloads set: - `WasMentioned` (mention gating result) - Telegram forum topics also include `MessageThreadId` and `IsForum`. -Channel-specific notes: - -- BlueBubbles can optionally enrich unnamed macOS group participants from the local Contacts database before populating `GroupMembers`. This is off by default and only runs after normal group gating passes. - The agent system prompt includes a group intro on the first turn of a new group session. It reminds the model to respond like a human, avoid Markdown tables, minimize empty lines and follow normal chat spacing, and avoid typing literal `\n` sequences. Channel-sourced group names and participant labels are rendered as fenced untrusted metadata, not inline system instructions. ## iMessage specifics diff --git a/docs/channels/imessage.md b/docs/channels/imessage.md index 081887bb792..5b85b3a4e90 100644 --- a/docs/channels/imessage.md +++ b/docs/channels/imessage.md @@ -7,18 +7,18 @@ title: "iMessage" --- -For new OpenClaw iMessage deployments, start here when you can run `imsg` on a signed-in macOS Messages host. BlueBubbles remains available as a legacy fallback for existing setups that depend on its HTTP server, webhooks, or richer private-API actions. +For OpenClaw iMessage deployments, use `imsg` on a signed-in macOS Messages host. If your Gateway runs on Linux or Windows, point `channels.imessage.cliPath` at an SSH wrapper that runs `imsg` on the Mac. Status: native external CLI integration. Gateway spawns `imsg rpc` and communicates over JSON-RPC on stdio (no separate daemon/port). - - Keep using it for existing BlueBubbles-backed routing; avoid it for new setups when imsg fits. - iMessage DMs default to pairing mode. + + Use an SSH wrapper when the Gateway is not running on the Messages Mac. + Full iMessage field reference. @@ -362,7 +362,23 @@ imsg rpc --help openclaw channels status --probe ``` - If probe reports RPC unsupported, update `imsg`. + If probe reports RPC unsupported, update `imsg`. If the Gateway is not running on macOS, use the Remote Mac over SSH setup above instead of the default local `imsg` path. + + + + + The default `cliPath: "imsg"` must run on the Mac signed into Messages. On Linux or Windows, set `channels.imessage.cliPath` to a wrapper script that SSHes to that Mac and runs `imsg "$@"`. + +```bash +#!/usr/bin/env bash +exec ssh -T messages-mac imsg "$@" +``` + + Then run: + +```bash +openclaw channels status --probe --channel imessage +``` @@ -414,7 +430,6 @@ imsg send "test" - [Configuration reference - iMessage](/gateway/config-channels#imessage) - [Gateway configuration](/gateway/configuration) - [Pairing](/channels/pairing) -- [BlueBubbles](/channels/bluebubbles) ## Related diff --git a/docs/channels/index.md b/docs/channels/index.md index 9857c2fb2cd..e655ac23e6c 100644 --- a/docs/channels/index.md +++ b/docs/channels/index.md @@ -21,11 +21,10 @@ Text is supported everywhere; media and reactions vary by channel. ## Supported channels -- [BlueBubbles](/channels/bluebubbles) - Legacy iMessage bridge via the BlueBubbles macOS server REST API; deprecated for new OpenClaw setups but still supported for existing configs and richer private-API actions. - [Discord](/channels/discord) - Discord Bot API + Gateway; supports servers, channels, and DMs. - [Feishu](/channels/feishu) - Feishu/Lark bot via WebSocket (bundled plugin). - [Google Chat](/channels/googlechat) - Google Chat API app via HTTP webhook (downloadable plugin). -- [iMessage](/channels/imessage) - Native macOS integration via the imsg CLI; preferred for new OpenClaw iMessage setups when host permissions and Messages access fit. +- [iMessage](/channels/imessage) - Native macOS integration via the `imsg` CLI on a signed-in Mac; use an SSH wrapper when the Gateway runs elsewhere. - [IRC](/channels/irc) - Classic IRC servers; channels + DMs with pairing/allowlist controls. - [LINE](/channels/line) - LINE Messaging API bot (downloadable plugin). - [Matrix](/channels/matrix) - Matrix protocol (downloadable plugin). diff --git a/docs/channels/pairing.md b/docs/channels/pairing.md index 040a995aadb..9482d770ae7 100644 --- a/docs/channels/pairing.md +++ b/docs/channels/pairing.md @@ -45,7 +45,7 @@ That gives first-time setups an explicit owner for privileged commands and exec approval prompts. After an owner exists, later pairing approvals only grant DM access; they do not add more owners. -Supported channels: `bluebubbles`, `discord`, `feishu`, `googlechat`, `imessage`, `irc`, `line`, `matrix`, `mattermost`, `msteams`, `nextcloud-talk`, `nostr`, `openclaw-weixin`, `signal`, `slack`, `synology-chat`, `telegram`, `twitch`, `whatsapp`, `zalo`, `zalouser`. +Supported channels: `discord`, `feishu`, `googlechat`, `imessage`, `irc`, `line`, `matrix`, `mattermost`, `msteams`, `nextcloud-talk`, `nostr`, `openclaw-weixin`, `signal`, `slack`, `synology-chat`, `telegram`, `twitch`, `whatsapp`, `zalo`, `zalouser`. ### Reusable sender groups @@ -209,6 +209,5 @@ Stored under `~/.openclaw/devices/`: - WhatsApp: [WhatsApp](/channels/whatsapp) - Signal: [Signal](/channels/signal) - iMessage: [iMessage](/channels/imessage) - - BlueBubbles (legacy iMessage bridge): [BlueBubbles](/channels/bluebubbles) - Discord: [Discord](/channels/discord) - Slack: [Slack](/channels/slack) diff --git a/docs/channels/troubleshooting.md b/docs/channels/troubleshooting.md index db30bc0af99..6b09a2de9df 100644 --- a/docs/channels/troubleshooting.md +++ b/docs/channels/troubleshooting.md @@ -82,20 +82,19 @@ Full troubleshooting: [Discord troubleshooting](/channels/discord#troubleshootin Full troubleshooting: [Slack troubleshooting](/channels/slack#troubleshooting) -## iMessage and BlueBubbles +## iMessage -### iMessage and BlueBubbles failure signatures +### iMessage failure signatures -| Symptom | Fastest check | Fix | -| -------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------- | -| No inbound events | Verify webhook/server reachability and app permissions | Fix webhook URL or BlueBubbles server state. | -| Can send but no receive on macOS | Check macOS privacy permissions for Messages automation | Re-grant TCC permissions and restart channel process. | -| DM sender blocked | `openclaw pairing list imessage` or `openclaw pairing list bluebubbles` | Approve pairing or update allowlist. | +| Symptom | Fastest check | Fix | +| ------------------------------------ | ------------------------------------------------------- | --------------------------------------------------------------------- | +| `imsg` missing or fails on non-macOS | `openclaw channels status --probe --channel imessage` | Run OpenClaw on the Messages Mac or use an SSH wrapper for `cliPath`. | +| Can send but no receive on macOS | Check macOS privacy permissions for Messages automation | Re-grant TCC permissions and restart channel process. | +| DM sender blocked | `openclaw pairing list imessage` | Approve pairing or update allowlist. | Full troubleshooting: - [iMessage troubleshooting](/channels/imessage#troubleshooting) -- [BlueBubbles troubleshooting](/channels/bluebubbles#troubleshooting) ## Signal diff --git a/docs/concepts/features.md b/docs/concepts/features.md index 701f9122bdc..b3cfa5da079 100644 --- a/docs/concepts/features.md +++ b/docs/concepts/features.md @@ -33,7 +33,7 @@ title: "Features" **Channels:** - Built-in channels include Discord, Google Chat, iMessage, IRC, Signal, Slack, Telegram, WebChat, and WhatsApp -- Bundled plugin channels include BlueBubbles as a legacy iMessage bridge, Feishu, LINE, Matrix, Mattermost, Microsoft Teams, Nextcloud Talk, Nostr, QQ Bot, Synology Chat, Tlon, Twitch, Zalo, and Zalo Personal +- Bundled plugin channels include Feishu, LINE, Matrix, Mattermost, Microsoft Teams, Nextcloud Talk, Nostr, QQ Bot, Synology Chat, Tlon, Twitch, Zalo, and Zalo Personal - Optional separately installed channel plugins include Voice Call and third-party packages such as WeChat - Third-party channel plugins can extend the Gateway further, such as WeChat - Group chat support with mention-based activation diff --git a/docs/concepts/message-lifecycle-refactor.md b/docs/concepts/message-lifecycle-refactor.md index edc57c23776..c6672394196 100644 --- a/docs/concepts/message-lifecycle-refactor.md +++ b/docs/concepts/message-lifecycle-refactor.md @@ -763,7 +763,7 @@ Concrete migration hazards to preserve: - Telegram silent fallback delivery must deliver the full projected payload array. A single-payload shortcut can drop additional fallback payloads after projection. -- LINE, BlueBubbles, Zalo, Nostr, and other existing assembled/helper paths may +- LINE, Zalo, Nostr, and other existing assembled/helper paths may have reply-token handling, media proxying, sent-message caches, loading/status cleanup, or callback-only targets. They stay on channel-owned delivery until those semantics are represented by the send adapter and verified by tests. @@ -854,30 +854,30 @@ Core policy: ## Channel mapping -| Channel | Target migration | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Telegram | Receive ack policy plus durable final sends. Live adapter owns send plus edit preview, stale preview final send, topics, quote-reply preview skip, media fallback, and retry-after handling. | -| Discord | Send adapter wraps existing durable payload delivery. Live adapter owns draft edit, progress draft, media/error preview cancel, reply target preservation, and message id receipts. Audit bot-authored gateway-failure echoes in shared rooms; use an outbound registry or other native equivalent if Discord cannot carry origin metadata on normal messages. | -| Slack | Send adapter handles normal chat posts. Live adapter chooses native stream when thread shape supports it, otherwise draft preview. Receipts preserve thread timestamps. Origin adapter maps OpenClaw gateway failures to Slack `chat.postMessage.metadata` and drops tagged bot-room echoes before `allowBots` authorization. | -| WhatsApp | Send adapter owns text/media send with durable final intents. Receive adapter handles group mention and sender identity. Live can stay absent until WhatsApp has an editable transport. | -| Matrix | Live adapter owns draft event edits, finalization, redaction, encrypted media constraints, and reply-target mismatch fallback. Receive adapter owns encrypted event hydration and dedupe. Origin adapter should encode OpenClaw gateway-failure origin into Matrix event content and drop configured-bot room echoes before `allowBots` handling. | -| Mattermost | Live adapter owns one draft post, progress/tool folding, finalization in place, and fresh-send fallback. | -| Microsoft Teams | Live adapter owns native progress and block stream behavior. Send adapter owns activities and attachment/card receipts. | -| Feishu | Render adapter owns text/card/raw rendering. Live adapter owns streaming cards and duplicate final suppression. Send adapter owns comments, topic sessions, media, and voice suppression. | -| QQ Bot | Live adapter owns C2C streaming, accumulator timeout, and fallback final send. Render adapter owns media tags and text-as-voice. | -| Signal | Simple receive plus send adapter. No live adapter unless signal-cli adds reliable edit support. | -| iMessage and BlueBubbles | Simple receive plus send adapter. iMessage send must preserve monitor echo-cache population before durable finals can bypass monitor delivery. BlueBubbles-specific typing, reactions, and attachments remain adapter capabilities. | -| Google Chat | Simple receive plus send adapter with thread relation mapped to spaces and thread ids. Audit `allowBots=true` room behavior for tagged OpenClaw gateway-failure echoes. | -| LINE | Simple receive plus send adapter with reply-token constraints modeled as target/relation capability. | -| Nextcloud Talk | SDK receive bridge plus send adapter. | -| IRC | Simple receive plus send adapter, no durable edit receipts. | -| Nostr | Receive plus send adapter for encrypted DMs; receipts are event ids. | -| QA Channel | Contract-test adapter for receive, send, live, retry, and recovery behavior. | -| Synology Chat | Simple receive plus send adapter. | -| Tlon | Send adapter must preserve model-signature rendering and participated-thread tracking before generic durable final delivery is enabled. | -| Twitch | Simple receive plus send adapter with rate-limit classification. | -| Zalo | Simple receive plus send adapter. | -| Zalo Personal | Simple receive plus send adapter. | +| Channel | Target migration | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Telegram | Receive ack policy plus durable final sends. Live adapter owns send plus edit preview, stale preview final send, topics, quote-reply preview skip, media fallback, and retry-after handling. | +| Discord | Send adapter wraps existing durable payload delivery. Live adapter owns draft edit, progress draft, media/error preview cancel, reply target preservation, and message id receipts. Audit bot-authored gateway-failure echoes in shared rooms; use an outbound registry or other native equivalent if Discord cannot carry origin metadata on normal messages. | +| Slack | Send adapter handles normal chat posts. Live adapter chooses native stream when thread shape supports it, otherwise draft preview. Receipts preserve thread timestamps. Origin adapter maps OpenClaw gateway failures to Slack `chat.postMessage.metadata` and drops tagged bot-room echoes before `allowBots` authorization. | +| WhatsApp | Send adapter owns text/media send with durable final intents. Receive adapter handles group mention and sender identity. Live can stay absent until WhatsApp has an editable transport. | +| Matrix | Live adapter owns draft event edits, finalization, redaction, encrypted media constraints, and reply-target mismatch fallback. Receive adapter owns encrypted event hydration and dedupe. Origin adapter should encode OpenClaw gateway-failure origin into Matrix event content and drop configured-bot room echoes before `allowBots` handling. | +| Mattermost | Live adapter owns one draft post, progress/tool folding, finalization in place, and fresh-send fallback. | +| Microsoft Teams | Live adapter owns native progress and block stream behavior. Send adapter owns activities and attachment/card receipts. | +| Feishu | Render adapter owns text/card/raw rendering. Live adapter owns streaming cards and duplicate final suppression. Send adapter owns comments, topic sessions, media, and voice suppression. | +| QQ Bot | Live adapter owns C2C streaming, accumulator timeout, and fallback final send. Render adapter owns media tags and text-as-voice. | +| Signal | Simple receive plus send adapter. No live adapter unless signal-cli adds reliable edit support. | +| iMessage | Simple receive plus send adapter. iMessage send must preserve monitor echo-cache population before durable finals can bypass monitor delivery. | +| Google Chat | Simple receive plus send adapter with thread relation mapped to spaces and thread ids. Audit `allowBots=true` room behavior for tagged OpenClaw gateway-failure echoes. | +| LINE | Simple receive plus send adapter with reply-token constraints modeled as target/relation capability. | +| Nextcloud Talk | SDK receive bridge plus send adapter. | +| IRC | Simple receive plus send adapter, no durable edit receipts. | +| Nostr | Receive plus send adapter for encrypted DMs; receipts are event ids. | +| QA Channel | Contract-test adapter for receive, send, live, retry, and recovery behavior. | +| Synology Chat | Simple receive plus send adapter. | +| Tlon | Send adapter must preserve model-signature rendering and participated-thread tracking before generic durable final delivery is enabled. | +| Twitch | Simple receive plus send adapter with rate-limit classification. | +| Zalo | Simple receive plus send adapter. | +| Zalo Personal | Simple receive plus send adapter. | ## Migration plan @@ -1035,7 +1035,7 @@ Channel tests: - Discord prepared dispatcher finals route through the send context before docs or changelog claim Discord final-reply durability. - iMessage durable final sends populate the monitor sent-message echo cache. -- LINE, BlueBubbles, Zalo, and Nostr legacy delivery paths are not bypassed by +- LINE, Zalo, and Nostr legacy delivery paths are not bypassed by generic durable send until their adapter parity tests exist. - Direct-DM/Nostr callback delivery remains authoritative unless explicitly migrated to a complete message target and replay-safe send adapter. diff --git a/docs/concepts/messages.md b/docs/concepts/messages.md index 0b1cd65ca7e..50b296a97fb 100644 --- a/docs/concepts/messages.md +++ b/docs/concepts/messages.md @@ -59,7 +59,7 @@ Config (global default + per-channel overrides): Notes: - Debounce applies to **text-only** messages; media/attachments flush immediately. -- Control commands bypass debouncing so they remain standalone — **except** when a channel explicitly opts in to same-sender DM coalescing (e.g. [BlueBubbles `coalesceSameSenderDms`](/channels/bluebubbles#coalescing-split-send-dms-command--url-in-one-composition)), where DM commands wait inside the debounce window so a split-send payload can join the same agent turn. +- Control commands bypass debouncing so they remain standalone. Channels that explicitly opt in to same-sender DM coalescing can keep DM commands inside the debounce window so a split-send payload can join the same agent turn. ## Sessions and devices diff --git a/docs/concepts/multi-agent.md b/docs/concepts/multi-agent.md index cd57956d107..32139af31ae 100644 --- a/docs/concepts/multi-agent.md +++ b/docs/concepts/multi-agent.md @@ -262,7 +262,7 @@ Common channels supporting this pattern include: - `whatsapp`, `telegram`, `discord`, `slack`, `signal`, `imessage` - `irc`, `line`, `googlechat`, `mattermost`, `matrix`, `nextcloud-talk` -- `bluebubbles`, `zalo`, `zalouser`, `nostr`, `feishu` +- `zalo`, `zalouser`, `nostr`, `feishu` ## Concepts diff --git a/docs/docs.json b/docs/docs.json index 59679e162d0..ee228cca921 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1059,7 +1059,6 @@ "channels/msteams", "channels/googlechat", "channels/imessage", - "channels/bluebubbles", "channels/matrix", "channels/matrix-migration", "channels/matrix-push-rules" diff --git a/docs/gateway/config-agents.md b/docs/gateway/config-agents.md index e19b9578e57..c2936a9652f 100644 --- a/docs/gateway/config-agents.md +++ b/docs/gateway/config-agents.md @@ -1290,7 +1290,7 @@ Variables are case-insensitive. `{think}` is an alias for `{thinkingLevel}`. - Per-channel overrides: `channels..ackReaction`, `channels..accounts..ackReaction`. - Resolution order: account → channel → `messages.ackReaction` → identity fallback. - Scope: `group-mentions` (default), `group-all`, `direct`, `all`. -- `removeAckAfterReply`: removes ack after reply on reaction-capable channels such as Slack, Discord, Telegram, WhatsApp, and BlueBubbles. +- `removeAckAfterReply`: removes ack after reply on reaction-capable channels such as Slack, Discord, Telegram, WhatsApp, and iMessage. - `messages.statusReactions.enabled`: enables lifecycle status reactions on Slack, Discord, and Telegram. On Slack and Discord, unset keeps status reactions enabled when ack reactions are active. On Telegram, set it explicitly to `true` to enable lifecycle status reactions. diff --git a/docs/gateway/config-channels.md b/docs/gateway/config-channels.md index c16916bc9a5..0b9dcbf5319 100644 --- a/docs/gateway/config-channels.md +++ b/docs/gateway/config-channels.md @@ -581,32 +581,12 @@ When Mattermost native commands are enabled: - `channels.signal.configWrites`: allow or deny Signal-initiated config writes. - Optional `channels.signal.defaultAccount` overrides default account selection when it matches a configured account id. -### BlueBubbles - -BlueBubbles is the legacy iMessage bridge (plugin-backed, configured under `channels.bluebubbles`). Existing setups remain supported, but new OpenClaw iMessage deployments should prefer `channels.imessage` when `imsg` can run on the Messages host. - -```json5 -{ - channels: { - bluebubbles: { - enabled: true, - dmPolicy: "pairing", - // serverUrl, password, webhookPath, group controls, and advanced actions: - // see /channels/bluebubbles - }, - }, -} -``` - -- Core key paths covered here: `channels.bluebubbles`, `channels.bluebubbles.dmPolicy`. -- Optional `channels.bluebubbles.defaultAccount` overrides default account selection when it matches a configured account id. -- Top-level `bindings[]` entries with `type: "acp"` can bind BlueBubbles conversations to persistent ACP sessions. Use a BlueBubbles handle or target string (`chat_id:*`, `chat_guid:*`, `chat_identifier:*`) in `match.peer.id`. Shared field semantics: [ACP Agents](/tools/acp-agents#persistent-channel-bindings). -- Full BlueBubbles channel configuration and deprecation rationale are documented in [BlueBubbles](/channels/bluebubbles). - ### iMessage OpenClaw spawns `imsg rpc` (JSON-RPC over stdio). No daemon or port required. This is the preferred path for new OpenClaw iMessage setups when the host can grant Messages database and Automation permissions. +If the Gateway is not running on the signed-in Messages Mac, keep `channels.imessage.enabled=true` and set `channels.imessage.cliPath` to an SSH wrapper that runs `imsg "$@"` on that Mac. The default local `imsg` path is macOS-only. + ```json5 { channels: { diff --git a/docs/gateway/heartbeat.md b/docs/gateway/heartbeat.md index 7c1630d20ab..5ea320ded43 100644 --- a/docs/gateway/heartbeat.md +++ b/docs/gateway/heartbeat.md @@ -102,7 +102,7 @@ Outside heartbeats, stray `HEARTBEAT_OK` at the start/end of a message is stripp lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history) skipWhenBusy: false, // default: false; true also waits for subagent/nested lanes - target: "last", // default: none | options: last | none | (core or plugin, e.g. "bluebubbles") + target: "last", // default: none | options: last | none | (core or plugin, e.g. "imessage") to: "+15551234567", // optional channel-specific override accountId: "ops-bot", // optional multi-account channel id prompt: "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.", diff --git a/docs/help/faq-first-run.md b/docs/help/faq-first-run.md index 05b774112e0..6b9c4bc1549 100644 --- a/docs/help/faq-first-run.md +++ b/docs/help/faq-first-run.md @@ -670,22 +670,22 @@ and troubleshooting see the main [FAQ](/help/faq). No. OpenClaw runs on macOS or Linux (Windows via WSL2). A Mac mini is optional - some people buy one as an always-on host, but a small VPS, home server, or Raspberry Pi-class box works too. - You only need a Mac **for macOS-only tools**. For iMessage, use [BlueBubbles](/channels/bluebubbles) (recommended) - the BlueBubbles server runs on any Mac, and the Gateway can run on Linux or elsewhere. If you want other macOS-only tools, run the Gateway on a Mac or pair a macOS node. + You only need a Mac **for macOS-only tools**. For iMessage, use [iMessage](/channels/imessage) with `imsg` on any Mac signed into Messages. If the Gateway runs on Linux or elsewhere, set `channels.imessage.cliPath` to an SSH wrapper that runs `imsg` on that Mac. If you want other macOS-only tools, run the Gateway on a Mac or pair a macOS node. - Docs: [BlueBubbles](/channels/bluebubbles), [Nodes](/nodes), [Mac remote mode](/platforms/mac/remote). + Docs: [iMessage](/channels/imessage), [Nodes](/nodes), [Mac remote mode](/platforms/mac/remote). You need **some macOS device** signed into Messages. It does **not** have to be a Mac mini - - any Mac works. **Use [BlueBubbles](/channels/bluebubbles)** (recommended) for iMessage - the BlueBubbles server runs on macOS, while the Gateway can run on Linux or elsewhere. + any Mac works. **Use [iMessage](/channels/imessage)** with `imsg`; the Gateway can run on that Mac, or it can run elsewhere with an SSH wrapper `cliPath`. Common setups: - - Run the Gateway on Linux/VPS, and run the BlueBubbles server on any Mac signed into Messages. + - Run the Gateway on Linux/VPS, and set `channels.imessage.cliPath` to an SSH wrapper that runs `imsg` on a Mac signed into Messages. - Run everything on the Mac if you want the simplest single-machine setup. - Docs: [BlueBubbles](/channels/bluebubbles), [Nodes](/nodes), + Docs: [iMessage](/channels/imessage), [Nodes](/nodes), [Mac remote mode](/platforms/mac/remote). diff --git a/docs/install/macos-vm.md b/docs/install/macos-vm.md index e4095daea62..40e3aadf908 100644 --- a/docs/install/macos-vm.md +++ b/docs/install/macos-vm.md @@ -2,7 +2,7 @@ summary: "Run OpenClaw in a sandboxed macOS VM (local or hosted) when you need isolation or iMessage" read_when: - You want OpenClaw isolated from your main macOS environment - - You want iMessage integration (BlueBubbles) in a sandbox + - You want iMessage integration in a sandbox - You want a resettable macOS environment you can clone - You want to compare local vs hosted macOS VM options title: "macOS VMs" @@ -14,7 +14,7 @@ title: "macOS VMs" - **Dedicated hardware** (Mac mini or Linux box) if you want full control and a **residential IP** for browser automation. Many sites block data center IPs, so local browsing often works better. - **Hybrid:** keep the Gateway on a cheap VPS, and connect your Mac as a **node** when you need browser/UI automation. See [Nodes](/nodes) and [Gateway remote](/gateway/remote). -Use a macOS VM when you specifically need macOS-only capabilities (iMessage/BlueBubbles) or want strict isolation from your daily Mac. +Use a macOS VM when you specifically need macOS-only capabilities such as iMessage or want strict isolation from your daily Mac. ## macOS VM options @@ -25,7 +25,7 @@ Run OpenClaw in a sandboxed macOS VM on your existing Apple Silicon Mac using [L This gives you: - Full macOS environment in isolation (your host stays clean) -- iMessage support via BlueBubbles (impossible on Linux/Windows) +- iMessage support via `imsg` (the default local path is impossible on Linux/Windows) - Instant reset by cloning VMs - No extra hardware or cloud costs @@ -198,24 +198,24 @@ ssh youruser@192.168.64.X "openclaw status" ## Bonus: iMessage integration -This is the killer feature of running on macOS. Use [BlueBubbles](https://bluebubbles.app) to add iMessage to OpenClaw. +This is the killer feature of running on macOS. Use [iMessage](/channels/imessage) with `imsg` to add Messages to OpenClaw. Inside the VM: -1. Download BlueBubbles from bluebubbles.app -2. Sign in with your Apple ID -3. Enable the Web API and set a password -4. Point BlueBubbles webhooks at your gateway (example: `https://your-gateway-host:3000/bluebubbles-webhook?password=`) +1. Sign in to Messages. +2. Install `imsg`. +3. Grant Full Disk Access and Automation permission for the process running OpenClaw/`imsg`. +4. Verify RPC support with `imsg rpc --help`. Add to your OpenClaw config: ```json5 { channels: { - bluebubbles: { - serverUrl: "http://localhost:1234", - password: "your-api-password", - webhookPath: "/bluebubbles-webhook", + imessage: { + enabled: true, + cliPath: "imsg", + dbPath: "~/Library/Messages/chat.db", }, }, } @@ -223,7 +223,7 @@ Add to your OpenClaw config: Restart the gateway. Now your agent can send and receive iMessages. -Full setup details: [BlueBubbles channel](/channels/bluebubbles) +Full setup details: [iMessage channel](/channels/imessage) --- @@ -274,7 +274,7 @@ For true always-on, consider a dedicated Mac mini or a small VPS. See [VPS hosti - [VPS hosting](/vps) - [Nodes](/nodes) - [Gateway remote](/gateway/remote) -- [BlueBubbles channel](/channels/bluebubbles) +- [iMessage channel](/channels/imessage) - [Lume Quickstart](https://cua.ai/docs/lume/guide/getting-started/quickstart) - [Lume CLI Reference](https://cua.ai/docs/lume/reference/cli-reference) - [Unattended VM Setup](https://cua.ai/docs/lume/guide/fundamentals/unattended-setup) (advanced) diff --git a/docs/reference/rpc.md b/docs/reference/rpc.md index 348d4a319fb..fffbfe0a17f 100644 --- a/docs/reference/rpc.md +++ b/docs/reference/rpc.md @@ -17,11 +17,9 @@ OpenClaw integrates external CLIs via JSON-RPC. Two patterns are used today. See [Signal](/channels/signal) for setup and endpoints. -## Pattern B: stdio child process (legacy: imsg) +## Pattern B: stdio child process (imsg) -> **Note:** For new iMessage setups, use [BlueBubbles](/channels/bluebubbles) instead. - -- OpenClaw spawns `imsg rpc` as a child process (legacy iMessage integration). +- OpenClaw spawns `imsg rpc` as a child process for [iMessage](/channels/imessage). - JSON-RPC is line-delimited over stdin/stdout (one JSON object per line). - No TCP port, no daemon required. diff --git a/docs/reference/secretref-credential-surface.md b/docs/reference/secretref-credential-surface.md index 045ec2128f6..1e7b27e613b 100644 --- a/docs/reference/secretref-credential-surface.md +++ b/docs/reference/secretref-credential-surface.md @@ -82,8 +82,6 @@ Scope intent: - `channels.irc.nickserv.password` - `channels.irc.accounts.*.password` - `channels.irc.accounts.*.nickserv.password` -- `channels.bluebubbles.password` -- `channels.bluebubbles.accounts.*.password` - `channels.feishu.appSecret` - `channels.feishu.encryptKey` - `channels.feishu.verificationToken` diff --git a/docs/reference/secretref-user-supplied-credentials-matrix.json b/docs/reference/secretref-user-supplied-credentials-matrix.json index da473149004..33aa6f1c05e 100644 --- a/docs/reference/secretref-user-supplied-credentials-matrix.json +++ b/docs/reference/secretref-user-supplied-credentials-matrix.json @@ -60,20 +60,6 @@ "optIn": true, "notes": "Compatibility exception: sibling ref field remains canonical." }, - { - "id": "channels.bluebubbles.accounts.*.password", - "configFile": "openclaw.json", - "path": "channels.bluebubbles.accounts.*.password", - "secretShape": "secret_input", - "optIn": true - }, - { - "id": "channels.bluebubbles.password", - "configFile": "openclaw.json", - "path": "channels.bluebubbles.password", - "secretShape": "secret_input", - "optIn": true - }, { "id": "channels.discord.accounts.*.pluralkit.token", "configFile": "openclaw.json", diff --git a/docs/reference/wizard.md b/docs/reference/wizard.md index 902f732a6b2..8e5ee0e8f0f 100644 --- a/docs/reference/wizard.md +++ b/docs/reference/wizard.md @@ -102,8 +102,7 @@ For a high-level overview, see [Onboarding (CLI)](/start/wizard). - [Google Chat](/channels/googlechat): service account JSON + webhook audience. - [Mattermost](/channels/mattermost) (plugin): bot token + base URL. - [Signal](/channels/signal): optional `signal-cli` install + account config. - - [BlueBubbles](/channels/bluebubbles): **recommended for iMessage**; server URL + password + webhook. - - [iMessage](/channels/imessage): legacy `imsg` CLI path + DB access. + - [iMessage](/channels/imessage): `imsg` CLI path + Messages DB access; use an SSH wrapper when the Gateway runs off-Mac. - DM security: default is pairing. First DM sends a code; approve via `openclaw pairing approve ` or use allowlists. @@ -249,5 +248,5 @@ will prompt to install it (npm or a local path) before it can be configured. - Onboarding overview: [Onboarding (CLI)](/start/wizard) - macOS app onboarding: [Onboarding](/start/onboarding) - Config reference: [Gateway configuration](/gateway/configuration) -- Providers: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord), [Google Chat](/channels/googlechat), [Signal](/channels/signal), [BlueBubbles](/channels/bluebubbles) (iMessage), [iMessage](/channels/imessage) (legacy) +- Providers: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord), [Google Chat](/channels/googlechat), [Signal](/channels/signal), [iMessage](/channels/imessage) - Skills: [Skills](/tools/skills), [Skills config](/tools/skills-config) diff --git a/docs/start/docs-directory.md b/docs/start/docs-directory.md index 26433a9f9a1..6179ace1b22 100644 --- a/docs/start/docs-directory.md +++ b/docs/start/docs-directory.md @@ -39,7 +39,6 @@ For a complete map of the docs, see [Docs hubs](/start/hubs). - [Telegram](/channels/telegram) - [Discord](/channels/discord) - [Mattermost](/channels/mattermost) -- [BlueBubbles (legacy iMessage bridge)](/channels/bluebubbles) - [QQ Bot](/channels/qqbot) - [iMessage](/channels/imessage) - [Groups](/channels/groups) diff --git a/docs/start/hubs.md b/docs/start/hubs.md index 6b291aeafe7..7d00a56fd69 100644 --- a/docs/start/hubs.md +++ b/docs/start/hubs.md @@ -73,7 +73,6 @@ Use these hubs to discover every page, including deep dives and reference docs t - [Discord](/channels/discord) - [Mattermost](/channels/mattermost) - [Signal](/channels/signal) -- [BlueBubbles (legacy iMessage bridge)](/channels/bluebubbles) - [QQ Bot](/channels/qqbot) - [iMessage](/channels/imessage) - [Location parsing](/channels/location) diff --git a/docs/start/onboarding-overview.md b/docs/start/onboarding-overview.md index 03e5cdbf0a3..9c66b4eb1d2 100644 --- a/docs/start/onboarding-overview.md +++ b/docs/start/onboarding-overview.md @@ -31,7 +31,7 @@ Regardless of which path you choose, onboarding sets up: 2. **Workspace** — directory for agent files, bootstrap templates, and memory 3. **Gateway** — port, bind address, auth mode 4. **Channels** (optional) — built-in and bundled chat channels such as - BlueBubbles, Discord, Feishu, Google Chat, Mattermost, Microsoft Teams, + iMessage, Discord, Feishu, Google Chat, Mattermost, Microsoft Teams, Telegram, WhatsApp, and more 5. **Daemon** (optional) — background service so the Gateway starts automatically diff --git a/docs/start/wizard-cli-reference.md b/docs/start/wizard-cli-reference.md index 28d90609c80..f00156cda7f 100644 --- a/docs/start/wizard-cli-reference.md +++ b/docs/start/wizard-cli-reference.md @@ -17,7 +17,7 @@ Local mode (default) walks you through: - Model and auth setup (OpenAI Code subscription OAuth, Anthropic Claude CLI or API key, plus MiniMax, GLM, Ollama, Moonshot, StepFun, and AI Gateway options) - Workspace location and bootstrap files - Gateway settings (port, bind, auth, tailscale) -- Channels and providers (Telegram, WhatsApp, Discord, Google Chat, Mattermost, Signal, BlueBubbles, and other bundled channel plugins) +- Channels and providers (Telegram, WhatsApp, Discord, Google Chat, Mattermost, Signal, iMessage, and other bundled channel plugins) - Daemon install (LaunchAgent, systemd user unit, or native Windows Scheduled Task with Startup-folder fallback) - Health check - Skills setup @@ -70,8 +70,7 @@ It does not install or modify anything on the remote host. - [Google Chat](/channels/googlechat): service account JSON + webhook audience - [Mattermost](/channels/mattermost): bot token + base URL - [Signal](/channels/signal): optional `signal-cli` install + account config - - [BlueBubbles](/channels/bluebubbles): recommended for iMessage; server URL + password + webhook - - [iMessage](/channels/imessage): legacy `imsg` CLI path + DB access + - [iMessage](/channels/imessage): `imsg` CLI path + Messages DB access; use an SSH wrapper when the Gateway runs off-Mac - DM security: default is pairing. First DM sends a code; approve via `openclaw pairing approve ` or use allowlists. diff --git a/docs/start/wizard.md b/docs/start/wizard.md index 4eda1c45205..046f429cd87 100644 --- a/docs/start/wizard.md +++ b/docs/start/wizard.md @@ -77,7 +77,7 @@ Onboarding starts with **QuickStart** (defaults) vs **Advanced** (full control). 3. **Gateway** — Port, bind address, auth mode, Tailscale exposure. In interactive token mode, choose default plaintext token storage or opt into SecretRef. Non-interactive token SecretRef path: `--gateway-token-ref-env `. -4. **Channels** — built-in and bundled chat channels such as BlueBubbles, Discord, Feishu, Google Chat, Mattermost, Microsoft Teams, QQ Bot, Signal, Slack, Telegram, WhatsApp, and more. +4. **Channels** — built-in and bundled chat channels such as iMessage, Discord, Feishu, Google Chat, Mattermost, Microsoft Teams, QQ Bot, Signal, Slack, Telegram, WhatsApp, and more. 5. **Daemon** — Installs a LaunchAgent (macOS), systemd user unit (Linux/WSL2), or native Windows Scheduled Task with per-user Startup-folder fallback. If token auth requires a token and `gateway.auth.token` is SecretRef-managed, daemon install validates it but does not persist the resolved token into supervisor service environment metadata. If token auth requires a token and the configured token SecretRef is unresolved, daemon install is blocked with actionable guidance. diff --git a/docs/tools/acp-agents.md b/docs/tools/acp-agents.md index e09f2cbacd0..d4da2acd0fb 100644 --- a/docs/tools/acp-agents.md +++ b/docs/tools/acp-agents.md @@ -336,7 +336,6 @@ top-level `bindings[]` entries. - **Discord channel/thread:** `match.channel="discord"` + `match.peer.id=""` - **Telegram forum topic:** `match.channel="telegram"` + `match.peer.id=":topic:"` -- **BlueBubbles DM/group:** `match.channel="bluebubbles"` + `match.peer.id=""`. Prefer `chat_id:*` or `chat_identifier:*` for stable group bindings. - **iMessage DM/group:** `match.channel="imessage"` + `match.peer.id=""`. Prefer `chat_id:*` for stable group bindings. diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index c13a43c5dd4..e5c70c1e8b9 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -235,7 +235,6 @@ current OpenClaw or a local checkout until a newer npm package is published. | Plugin | Package | Docs | | --------------- | -------------------------- | ------------------------------------------ | -| BlueBubbles | `@openclaw/bluebubbles` | [BlueBubbles](/channels/bluebubbles) | | Discord | `@openclaw/discord` | [Discord](/channels/discord) | | Feishu | `@openclaw/feishu` | [Feishu](/channels/feishu) | | Matrix | `@openclaw/matrix` | [Matrix](/channels/matrix) | diff --git a/docs/tools/tts.md b/docs/tools/tts.md index 353f3d4b15a..289f070cd8b 100644 --- a/docs/tools/tts.md +++ b/docs/tools/tts.md @@ -709,8 +709,6 @@ delivery. `audio/ogg; codecs=opus`. If conversion fails, Feishu receives the original file as an attachment; WhatsApp send fails rather than posting an incompatible PTT payload. -- **BlueBubbles**: keeps provider synthesis on the normal audio-file path; MP3 - and CAF outputs are marked for iMessage voice memo delivery. - **Other channels**: MP3 (`mp3_44100_128` from ElevenLabs, `mp3` from OpenAI). - 44.1kHz / 128kbps is the default balance for speech clarity. - **MiniMax**: MP3 (`speech-2.8-hd` model, 32kHz sample rate) for normal audio attachments. For channel-advertised voice-note targets, OpenClaw transcodes the MiniMax MP3 to 48kHz Opus with `ffmpeg` before delivery when the channel advertises transcoding.