This commit removes the URL balloon message handling logic from the monitor, simplifying the message processing flow. Additionally, it enhances error logging by including the account ID in the error messages for better traceability.
When users send iMessages containing URLs, BlueBubbles sends separate
webhook events for the text message and the URL balloon/link preview.
This caused Clawdbot to receive them as separate queued messages.
This fix adds inbound debouncing (following the pattern from WhatsApp/MS Teams):
- Uses the existing createInboundDebouncer utility from plugin-sdk
- Adds debounceMs config option to BlueBubblesAccountConfig (default: 500ms)
- Routes inbound messages through debouncer before processing
- Combines messages from same sender/chat within the debounce window
- Handles URLBalloonProvider messages by coalescing with preceding text
- Skips debouncing for messages with attachments or control commands
Config example:
channels.bluebubbles.debounceMs: 500 # milliseconds (0 to disable)
Fixes inbound URL message splitting issue.
When the gateway restarts, the WebSocket disconnects and any in-flight
chat.final events are lost. On reconnect, chatRunId/chatStream were
still set from the orphaned run, making the UI think a run was still
in progress and not updating properly.
Fix: Reset chatRunId, chatStream, chatStreamStartedAt, and tool stream
state in the onHello callback when the WebSocket reconnects.
Fixes issue where users had to refresh the page after gateway restart
to see completed messages.
* feat(telegram): add silent message option (disable_notification)
Add support for sending Telegram messages silently without notification
sound via the `silent` parameter on the message tool.
Changes:
- Add `silent` boolean to message tool schema
- Extract and pass `silent` through telegram plugin
- Add `disable_notification: true` to Telegram API calls
- Add `--silent` flag to CLI `message send` command
- Add unit test for silent flag
Closes#2249
AI-assisted (Claude) - fully tested with unit tests + manual Telegram testing
* feat(telegram): add silent send option (#2382) (thanks @Suksham-sharma)
---------
Co-authored-by: Pocket Clawd <pocket@Pockets-Mac-mini.local>
Adds real-time streaming output support to CLI backends, enabling
line-by-line parsing of NDJSON output instead of waiting for the
full response. This brings CLI backends closer to the embedded/API
flow by emitting events as they arrive.
Key changes:
- New streaming execution module (cli-runner/streaming.ts):
- Uses readline to parse NDJSON lines as they arrive
- Extracts session IDs, usage stats, and text from stream
- Supports event type filtering with prefix matching
- Maps CLI-specific events to Clawdbot agent events
- Config extension:
- Added `streaming?: boolean` to enable streaming mode
- Added `streamingEventTypes?: string[]` to filter events
- Claude CLI defaults: stream-json format with --verbose flag
- Codex CLI defaults: streaming enabled with item/turn events
- Event mapping for different CLI formats:
- Claude CLI: tool_use, tool_result, text, result events
- Codex CLI: item.*, turn.completed, thread.completed events
- Debug logging throughout the pipeline:
- Logs raw JSON lines, parsed types, session/usage extraction
- Logs event emission and mapping decisions
- Helps diagnose streaming issues in production
The streaming path is enabled by default for Claude CLI and Codex CLI.
Users can disable it by setting `streaming: false` in their config.
Non-streaming path via runCommandWithTimeout remains available.
MEMORY.md is now loaded into context at session start, ensuring the
agent has access to curated long-term memory without requiring
embedding-based semantic search.
Previously, MEMORY.md was only accessible via the memory_search tool,
which requires an embedding provider (OpenAI/Gemini API key or local
model). When no embedding provider was configured, the agent would
claim memories were empty even though MEMORY.md existed and contained
data.
This change:
- Adds DEFAULT_MEMORY_FILENAME constant
- Includes MEMORY.md in WorkspaceBootstrapFileName type
- Loads MEMORY.md in loadWorkspaceBootstrapFiles()
- Does NOT add MEMORY.md to subagent allowlist (keeps user data private)
- Does NOT auto-create MEMORY.md template (user creates as needed)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Previously, CLI backend responses wrote hardcoded zeros for token usage
in session transcripts (input: 0, output: 0, totalTokens: 0). This caused
the UI to show incorrect token counts and status to fall back to stale
accumulated values.
Changes:
- Add usage parameter to appendMessageToTranscript and related functions
in session-utils.fs.ts to accept NormalizedUsage from CLI backends
- Pass result.meta.agentMeta?.usage when persisting assistant messages
in agent-runner-execution.ts
- Create CliSessionManager class with SDK-aligned API for future use:
static factories (open/create), accessor methods, write locking
- Add comprehensive tests for both session-utils.fs usage parameter
and the new CliSessionManager class (17 + 2 new tests)
Transcript entries now include actual input/output/cache token counts
from CLI backends like claude-cli and opus.
* docs: Add Oracle Cloud (OCI) platform guide
- Add comprehensive guide for Oracle Cloud Always Free tier (ARM)
- Cover VCN security, Tailscale Serve setup, and why traditional hardening is unnecessary
- Update vps.md to list Oracle as top provider option
- Update digitalocean.md to link to official Oracle guide instead of community gist
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Keep community gist link, remove unzip
* Fix step order: lock down VCN after Tailscale is running
* Move VCN lockdown to final step (after verifying everything works)
* docs: make Oracle/Tailscale guide safer + tone down DO copy
* docs: fix Oracle guide step numbering
* docs: tone down VPS hub Oracle blurb
* docs: add Oracle Cloud guide (#2333) (thanks @hirefrank)
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Pocket Clawd <pocket@Pockets-Mac-mini.local>