From f552820a75344e8563c7698d8793c9821ec946a4 Mon Sep 17 00:00:00 2001 From: Clawd Date: Thu, 22 Jan 2026 01:52:51 -0800 Subject: [PATCH 1/2] fix(bluebubbles): call stop typing on idle and NO_REPLY Previously, typing stop was intentionally skipped because the BlueBubbles Server DELETE endpoint was bugged (called startTyping instead of stopTyping). Now that the server bug is fixed, we can properly stop typing indicators. - onIdle: now calls sendBlueBubblesTyping(false) to stop typing - finally block: stops typing when no message sent (NO_REPLY case) --- extensions/bluebubbles/src/monitor.ts | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/extensions/bluebubbles/src/monitor.ts b/extensions/bluebubbles/src/monitor.ts index f5538306810..ab503882d11 100644 --- a/extensions/bluebubbles/src/monitor.ts +++ b/extensions/bluebubbles/src/monitor.ts @@ -1713,8 +1713,17 @@ async function processMessage( runtime.error?.(`[bluebubbles] typing start failed: ${String(err)}`); } }, - onIdle: () => { - // BlueBubbles typing stop (DELETE) does not clear bubbles reliably; wait for timeout. + onIdle: async () => { + if (!chatGuidForActions) return; + if (!baseUrl || !password) return; + try { + await sendBlueBubblesTyping(chatGuidForActions, false, { + cfg: config, + accountId: account.accountId, + }); + } catch (err) { + logVerbose(core, runtime, `typing stop failed: ${String(err)}`); + } }, onError: (err, info) => { runtime.error?.(`BlueBubbles ${info.kind} reply failed: ${String(err)}`); @@ -1754,7 +1763,13 @@ async function processMessage( }); } if (chatGuidForActions && baseUrl && password && !sentMessage) { - // BlueBubbles typing stop (DELETE) does not clear bubbles reliably; wait for timeout. + // Stop typing indicator when no message was sent (e.g., NO_REPLY) + sendBlueBubblesTyping(chatGuidForActions, false, { + cfg: config, + accountId: account.accountId, + }).catch((err) => { + logVerbose(core, runtime, `typing stop (no reply) failed: ${String(err)}`); + }); } } } From 3993c9a3b4b6a75befacbf503c09856d76b87538 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 22 Jan 2026 21:33:19 +0000 Subject: [PATCH 2/2] fix: stop BlueBubbles typing on idle/no-reply (#1439) (thanks @Nicell) --- CHANGELOG.md | 5 + extensions/bluebubbles/package.json | 2 +- extensions/bluebubbles/src/monitor.test.ts | 94 +++++++++++++++++++ extensions/copilot-proxy/package.json | 2 +- extensions/diagnostics-otel/package.json | 2 +- extensions/discord/package.json | 2 +- .../google-antigravity-auth/package.json | 2 +- .../google-gemini-cli-auth/package.json | 2 +- extensions/imessage/package.json | 2 +- extensions/lobster/package.json | 2 +- extensions/matrix/CHANGELOG.md | 5 + extensions/matrix/package.json | 2 +- extensions/memory-core/package.json | 2 +- extensions/memory-lancedb/package.json | 2 +- extensions/msteams/CHANGELOG.md | 5 + extensions/msteams/package.json | 2 +- extensions/nextcloud-talk/package.json | 2 +- extensions/nostr/CHANGELOG.md | 5 + extensions/nostr/package.json | 2 +- extensions/signal/package.json | 2 +- extensions/slack/package.json | 2 +- extensions/telegram/package.json | 2 +- extensions/voice-call/CHANGELOG.md | 5 + extensions/voice-call/package.json | 2 +- extensions/whatsapp/package.json | 2 +- extensions/zalo/CHANGELOG.md | 5 + extensions/zalo/package.json | 2 +- extensions/zalouser/CHANGELOG.md | 5 + extensions/zalouser/package.json | 2 +- package.json | 2 +- 30 files changed, 151 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 489f158901f..f6b4e140bf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Docs: https://docs.clawd.bot +## 2026.1.22 + +### Fixes +- BlueBubbles: stop typing indicator on idle/no-reply. (#1439) Thanks @Nicell. + ## 2026.1.21-2 ### Fixes diff --git a/extensions/bluebubbles/package.json b/extensions/bluebubbles/package.json index 0ff638c2895..d511722a933 100644 --- a/extensions/bluebubbles/package.json +++ b/extensions/bluebubbles/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/bluebubbles", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot BlueBubbles channel plugin", "clawdbot": { diff --git a/extensions/bluebubbles/src/monitor.test.ts b/extensions/bluebubbles/src/monitor.test.ts index ee9b150844e..0dcccbef8df 100644 --- a/extensions/bluebubbles/src/monitor.test.ts +++ b/extensions/bluebubbles/src/monitor.test.ts @@ -1563,6 +1563,100 @@ describe("BlueBubbles webhook monitor", () => { expect.any(Object), ); }); + + it("stops typing on idle", async () => { + const { sendBlueBubblesTyping } = await import("./chat.js"); + vi.mocked(sendBlueBubblesTyping).mockClear(); + + const account = createMockAccount(); + const config: ClawdbotConfig = {}; + const core = createMockRuntime(); + setBlueBubblesRuntime(core); + + unregister = registerBlueBubblesWebhookTarget({ + account, + config, + runtime: { log: vi.fn(), error: vi.fn() }, + core, + path: "/bluebubbles-webhook", + }); + + const payload = { + type: "new-message", + data: { + text: "hello", + handle: { address: "+15551234567" }, + isGroup: false, + isFromMe: false, + guid: "msg-1", + chatGuid: "iMessage;-;+15551234567", + date: Date.now(), + }, + }; + + mockDispatchReplyWithBufferedBlockDispatcher.mockImplementationOnce(async (params) => { + await params.dispatcherOptions.onReplyStart?.(); + await params.dispatcherOptions.deliver({ text: "replying now" }, { kind: "final" }); + await params.dispatcherOptions.onIdle?.(); + }); + + const req = createMockRequest("POST", "/bluebubbles-webhook", payload); + const res = createMockResponse(); + + await handleBlueBubblesWebhookRequest(req, res); + await new Promise((resolve) => setTimeout(resolve, 50)); + + expect(sendBlueBubblesTyping).toHaveBeenCalledWith( + expect.any(String), + false, + expect.any(Object), + ); + }); + + it("stops typing when no reply is sent", async () => { + const { sendBlueBubblesTyping } = await import("./chat.js"); + vi.mocked(sendBlueBubblesTyping).mockClear(); + + const account = createMockAccount(); + const config: ClawdbotConfig = {}; + const core = createMockRuntime(); + setBlueBubblesRuntime(core); + + unregister = registerBlueBubblesWebhookTarget({ + account, + config, + runtime: { log: vi.fn(), error: vi.fn() }, + core, + path: "/bluebubbles-webhook", + }); + + const payload = { + type: "new-message", + data: { + text: "hello", + handle: { address: "+15551234567" }, + isGroup: false, + isFromMe: false, + guid: "msg-1", + chatGuid: "iMessage;-;+15551234567", + date: Date.now(), + }, + }; + + mockDispatchReplyWithBufferedBlockDispatcher.mockImplementationOnce(async () => undefined); + + const req = createMockRequest("POST", "/bluebubbles-webhook", payload); + const res = createMockResponse(); + + await handleBlueBubblesWebhookRequest(req, res); + await new Promise((resolve) => setTimeout(resolve, 50)); + + expect(sendBlueBubblesTyping).toHaveBeenCalledWith( + expect.any(String), + false, + expect.any(Object), + ); + }); }); describe("outbound message ids", () => { diff --git a/extensions/copilot-proxy/package.json b/extensions/copilot-proxy/package.json index 64d23edb257..36b9e140374 100644 --- a/extensions/copilot-proxy/package.json +++ b/extensions/copilot-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/copilot-proxy", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Copilot Proxy provider plugin", "clawdbot": { diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json index a71c880c78b..fd1b655a046 100644 --- a/extensions/diagnostics-otel/package.json +++ b/extensions/diagnostics-otel/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/diagnostics-otel", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot diagnostics OpenTelemetry exporter", "clawdbot": { diff --git a/extensions/discord/package.json b/extensions/discord/package.json index 7073d8b8e86..8f43497a9d0 100644 --- a/extensions/discord/package.json +++ b/extensions/discord/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/discord", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Discord channel plugin", "clawdbot": { diff --git a/extensions/google-antigravity-auth/package.json b/extensions/google-antigravity-auth/package.json index 6f60b9fb1c2..c7626c272d4 100644 --- a/extensions/google-antigravity-auth/package.json +++ b/extensions/google-antigravity-auth/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/google-antigravity-auth", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Google Antigravity OAuth provider plugin", "clawdbot": { diff --git a/extensions/google-gemini-cli-auth/package.json b/extensions/google-gemini-cli-auth/package.json index c94a78f2976..9e9515f3e84 100644 --- a/extensions/google-gemini-cli-auth/package.json +++ b/extensions/google-gemini-cli-auth/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/google-gemini-cli-auth", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Gemini CLI OAuth provider plugin", "clawdbot": { diff --git a/extensions/imessage/package.json b/extensions/imessage/package.json index 2b0b369720c..94b120b260b 100644 --- a/extensions/imessage/package.json +++ b/extensions/imessage/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/imessage", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot iMessage channel plugin", "clawdbot": { diff --git a/extensions/lobster/package.json b/extensions/lobster/package.json index 3e62dc2f948..2b4a5b2dd51 100644 --- a/extensions/lobster/package.json +++ b/extensions/lobster/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/lobster", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)", "clawdbot": { diff --git a/extensions/matrix/CHANGELOG.md b/extensions/matrix/CHANGELOG.md index 603b5ed1938..2d25c41c408 100644 --- a/extensions/matrix/CHANGELOG.md +++ b/extensions/matrix/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/matrix/package.json b/extensions/matrix/package.json index 5f70904b015..e5dc66a8c40 100644 --- a/extensions/matrix/package.json +++ b/extensions/matrix/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/matrix", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Matrix channel plugin", "clawdbot": { diff --git a/extensions/memory-core/package.json b/extensions/memory-core/package.json index ffbee5ff6dc..57dfc36ef09 100644 --- a/extensions/memory-core/package.json +++ b/extensions/memory-core/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/memory-core", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot core memory search plugin", "clawdbot": { diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json index c052ce9956f..bdaa21f3593 100644 --- a/extensions/memory-lancedb/package.json +++ b/extensions/memory-lancedb/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/memory-lancedb", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot LanceDB-backed long-term memory plugin with auto-recall/capture", "dependencies": { diff --git a/extensions/msteams/CHANGELOG.md b/extensions/msteams/CHANGELOG.md index d6bbd6789b1..aa132c3829f 100644 --- a/extensions/msteams/CHANGELOG.md +++ b/extensions/msteams/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/msteams/package.json b/extensions/msteams/package.json index b8a5921afdf..5f7843f8a47 100644 --- a/extensions/msteams/package.json +++ b/extensions/msteams/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/msteams", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Microsoft Teams channel plugin", "clawdbot": { diff --git a/extensions/nextcloud-talk/package.json b/extensions/nextcloud-talk/package.json index 6286b7ae48d..c5ee0b8c6a5 100644 --- a/extensions/nextcloud-talk/package.json +++ b/extensions/nextcloud-talk/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/nextcloud-talk", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Nextcloud Talk channel plugin", "clawdbot": { diff --git a/extensions/nostr/CHANGELOG.md b/extensions/nostr/CHANGELOG.md index 2ab17911311..2005c22b35c 100644 --- a/extensions/nostr/CHANGELOG.md +++ b/extensions/nostr/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/nostr/package.json b/extensions/nostr/package.json index 2e0bd0132d9..dc5a9e00214 100644 --- a/extensions/nostr/package.json +++ b/extensions/nostr/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/nostr", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Nostr channel plugin for NIP-04 encrypted DMs", "clawdbot": { diff --git a/extensions/signal/package.json b/extensions/signal/package.json index 3a80b650ee1..6c26e77741b 100644 --- a/extensions/signal/package.json +++ b/extensions/signal/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/signal", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Signal channel plugin", "clawdbot": { diff --git a/extensions/slack/package.json b/extensions/slack/package.json index d07ec2fdae6..93470c49dc2 100644 --- a/extensions/slack/package.json +++ b/extensions/slack/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/slack", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Slack channel plugin", "clawdbot": { diff --git a/extensions/telegram/package.json b/extensions/telegram/package.json index 38333c2f3b5..2dc95db2e25 100644 --- a/extensions/telegram/package.json +++ b/extensions/telegram/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/telegram", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Telegram channel plugin", "clawdbot": { diff --git a/extensions/voice-call/CHANGELOG.md b/extensions/voice-call/CHANGELOG.md index 807c6ffb67b..08d0f500692 100644 --- a/extensions/voice-call/CHANGELOG.md +++ b/extensions/voice-call/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/voice-call/package.json b/extensions/voice-call/package.json index a56fafdf88d..ef0323ee4a9 100644 --- a/extensions/voice-call/package.json +++ b/extensions/voice-call/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/voice-call", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot voice-call plugin", "dependencies": { diff --git a/extensions/whatsapp/package.json b/extensions/whatsapp/package.json index 44a7cd44744..49f0fb541e9 100644 --- a/extensions/whatsapp/package.json +++ b/extensions/whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/whatsapp", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot WhatsApp channel plugin", "clawdbot": { diff --git a/extensions/zalo/CHANGELOG.md b/extensions/zalo/CHANGELOG.md index 1890023c2d8..a5e56e1da0c 100644 --- a/extensions/zalo/CHANGELOG.md +++ b/extensions/zalo/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/zalo/package.json b/extensions/zalo/package.json index cf26a354d8d..0f59602e7bf 100644 --- a/extensions/zalo/package.json +++ b/extensions/zalo/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/zalo", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Zalo channel plugin", "clawdbot": { diff --git a/extensions/zalouser/CHANGELOG.md b/extensions/zalouser/CHANGELOG.md index f0154f95d6f..f5b7a307195 100644 --- a/extensions/zalouser/CHANGELOG.md +++ b/extensions/zalouser/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026.1.22 + +### Changes +- Version alignment with core Clawdbot release numbers. + ## 2026.1.21 ### Changes diff --git a/extensions/zalouser/package.json b/extensions/zalouser/package.json index 932fe6b3d5c..71e6da3cb90 100644 --- a/extensions/zalouser/package.json +++ b/extensions/zalouser/package.json @@ -1,6 +1,6 @@ { "name": "@clawdbot/zalouser", - "version": "2026.1.21", + "version": "2026.1.22", "type": "module", "description": "Clawdbot Zalo Personal Account plugin via zca-cli", "dependencies": { diff --git a/package.json b/package.json index f2801884593..4d1a21b715a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawdbot", - "version": "2026.1.21-2", + "version": "2026.1.22", "description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent", "type": "module", "main": "dist/index.js",