Releases: ominiverdi/opencode-chat-bridge
Releases · ominiverdi/opencode-chat-bridge
Release list
v0.5.0
Added
- Configurable tool messages - New global
toolMessagessettings control
whether tool calls, compact arguments, and selected tool outputs are returned
to chat. Presentation modes includeoff, immutableevents, editable
currentstatus, and an editable cumulativetrace. Editable modes work
across WhatsApp, Telegram, Slack, Discord, Mattermost, Matrix, and Web, with
progressive ACP argument updates, trace pagination, and edit-failure
recovery. The formerstreamToolsoption is migrated automatically. - Telegram file attachments from users - The Telegram connector now
downloads photos, documents, videos, audio, voice notes, animations
(GIFs), video notes, and stickers that users send to the bot. Each
attachment is saved to<session-cwd>/uploads/and its absolute path is
prepended to the LLM prompt (alongside the user's caption) so the LLM
can useread,bash,glob, or other tools to inspect the file.
Telegram Bot API's 20 MB-per-file download limit is enforced up-front;
oversized files are skipped with a log line and the message is still
processed. Caption-less media in DMs (or inside active forum topics)
count as engagement and bypass the trigger requirement. - Telegram connector - New connector using the Telegram Bot API over HTTPS
with nativefetchand long-pollinggetUpdates. Zero external runtime
dependencies, no public port or webhook required. Features:- Trigger-prefixed messages (
!oc ...),@-mentions of the bot, and
auto-handled DMs (no prefix required in private chats) - Per-topic session isolation in forum supergroups, configurable via
threadIsolationinchat-bridge.json(defaulttrue); each topic gets
its own isolated OpenCode session - Plain replies inside an active topic continue the conversation without
requiring a re-mention (mirrors the behavior of the Slack/Mattermost
thread-isolation feature) - Native image (
sendPhoto) and document (sendDocument) uploads for
outputs from OpenCode tools - Long-message splitting at the 4096-char Telegram limit
sendChatAction"typing..." indicator while OpenCode is processing- Automatic exponential-backoff polling with
retry_afterhonored for 429s allowedUsers/TELEGRAM_ALLOWED_USERSallowlist plusignoreChats
andignoreUsersblocklistsTELEGRAM_DROP_PENDING=1to skip messages queued while offline- Swipe-replies to one of this bot's own messages are forwarded without
a trigger/@-mention, gated on an active session so stale replies are
ignored. Toggle withtelegram.respondToReplies(defaulttrue).
Fixes #34.
- Trigger-prefixed messages (
- Universal user allowlists (Slack, WhatsApp, Matrix, Discord, Mattermost, Telegram) -
Each connector now supportsallowedUsersinchat-bridge.jsonplus
per-connector*_ALLOWED_USERSenv vars. Messages from unlisted users are
silently dropped. Feature originated from PR #28 by @llvilanova and was
generalized across all connectors. - Thread isolation (Slack, Mattermost, Matrix, Telegram) - Sessions are now keyed per thread (
channel:threadTsfor Slack/Mattermost,
room:$eventIdfor Matrix, orchatId:messageThreadIdfor Telegram forum
topics) instead of per channel. Each thread gets its own isolated OpenCode
session. Replies always stay in threads. Implicit follow-ups work without
re-mentioning the bot. Configurable viathreadIsolationin
chat-bridge.json (default: true).
Inspired by PR #2, reimplemented with proper separation of concerns. - Event deduplication (all connectors) - New
EventDeduplicatorin BaseConnector
prevents duplicate event processing. Tracks recently seen event IDs with automatic
eviction. Protects against Slack retries, Matrix sync replays, Discord
re-deliveries, and Mattermost WebSocket replays. - Active query guard (all connectors) - Prevents concurrent queries on the same
session. Users get a clear "request already running" message. Sessions with
in-flight queries are protected from expiry. - Runtime session expiry - New
SESSION_RETENTION_MINSconfig (default: 30 for
Slack). Background sweep loop expires inactive in-memory sessions and cleans up
their on-disk cache directories. Coexists with existingSESSION_RETENTION_DAYS
startup cleanup. - Document attachment support (WhatsApp) - New
[DOCLIBRARY_DOC]marker and
sendDocumentFromFilemethod for sending PDF, CSV, XLSX, and other document
types as native WhatsApp file attachments. Same pattern as image handling.
Shared utilities (extractDocPaths,removeDocMarkers) and reusable
DocHandlerclass available for other connectors. - Mattermost connector - New connector using Mattermost REST API v4 and
WebSocket for real-time events. Zero external dependencies (uses native
fetchandWebSocket). Features: trigger-based responses in channels,
DM support without trigger, image file uploads, long message splitting,
tool output streaming, automatic reconnection with backoff. - HTML message formatting for Matrix - New
formatHtmlconfig option converts
markdown responses to HTML usingmarked, sending bothformatted_body(HTML)
andbody(plain text fallback) per the Matrix spec. Tables, bold, lists, and
code blocks render natively in Matrix clients. Disabled by default. - MCP server environment variables - MCP servers defined in
opencode.jsoncan
now include anenvblock for passing configuration (API URLs, tokens,
feature flags) to the server process. - Streaming tool output - Tool output now streams in real-time during execution.
Requires opencode PR #13589.- Configurable via
streamToolsinchat-bridge.json(default:["bash"]) - Only tools in the list have output streamed to chat
- Properly computes deltas from cumulative output (fixes accumulation bug)
- Skips final tool result if already streamed
- Configurable via
- OpenCode commands forwarding - Commands like
/init,/compact,/review
are discovered from OpenCode via ACP and shown in/help. When invoked, they
are forwarded directly to OpenCode instead of being handled by the bridge. - Skills infrastructure - The
.opencode/skills/directory is symlinked to
session directories, allowing custom skills to be loaded via theskilltool.
Skills provide domain-specific instructions (e.g., weather formatting, personas). - Permission request handling - Properly handles OpenCode permission requests
- Auto-rejects with clear message (e.g., "Permission denied: write")
- Prevents hanging when tools require elevated permissions
- Shows both the permission denial and the tool error to users
Changed
- Security dependency refresh - Updated Baileys to
7.0.0-rc.13,
Discord.js to14.27.0, Slack Bolt to4.7.3, and Marked to17.0.6.
This removes the audited Baileys protocol-message vulnerability and several
vulnerable transitive networking and parsing packages. - Breaking config rename (WhatsApp) -
allowedNumbersand
WHATSAPP_ALLOWED_NUMBERSwere removed in favor ofallowedUsersand
WHATSAPP_ALLOWED_USERSto match all other connectors.
Fixed
- Telegram: bot never answered swipe-replies to its own messages
(#34) - Addedtelegram.respondToReplies(defaulttrue) and a
shouldHandleTelegramBotReplydecision branch in the Telegram connector so
long-pressing the bot's message and tapping "Reply" continues the
conversation even in regular groups without a forum topic. Match is keyed
on the parent message'sfrom.id, so replies to other bots (or to
messages where Telegram redactsfrom) are ignored, and the connector
only engages when an active session exists for the chat/topic. - Trigger env var inconsistency - All connectors now support per-connector
trigger overrides (SLACK_TRIGGER,MATTERMOST_TRIGGER, etc.) with fallback
tochat-bridge.json. Previously only Slack and Discord had env overrides.
Changed
- Generic tool activity formatting - Tool activity messages now show
key=value, key=value [toolname]for ANY tool, removing hardcoded formatting.
This ensures new MCP tools display useful context automatically. - Added
markedas a dependency for markdown-to-HTML conversion