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 f55383068..ab503882d 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 489f15890..f6b4e140b 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 0ff638c28..d511722a9 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 ee9b15084..0dcccbef8 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 64d23edb2..36b9e1403 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 a71c880c7..fd1b655a0 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 7073d8b8e..8f43497a9 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 6f60b9fb1..c7626c272 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 c94a78f29..9e9515f3e 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 2b0b36972..94b120b26 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 3e62dc2f9..2b4a5b2dd 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 603b5ed19..2d25c41c4 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 5f70904b0..e5dc66a8c 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 ffbee5ff6..57dfc36ef 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 c052ce995..bdaa21f35 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 d6bbd6789..aa132c382 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 b8a5921af..5f7843f8a 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 6286b7ae4..c5ee0b8c6 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 2ab179113..2005c22b3 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 2e0bd0132..dc5a9e002 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 3a80b650e..6c26e7774 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 d07ec2fda..93470c49d 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 38333c2f3..2dc95db2e 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 807c6ffb6..08d0f5006 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 a56fafdf8..ef0323ee4 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 44a7cd447..49f0fb541 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 1890023c2..a5e56e1da 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 cf26a354d..0f59602e7 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 f0154f95d..f5b7a3071 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 932fe6b3d..71e6da3cb 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 f28018845..4d1a21b71 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",