You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dynamic Slack instance wiring for triggers — slack-instance-manifest now exposes onInstanceChange and emits { type: 'added' | 'removed', id, meta? } from addInstance / removeInstance. slack-trigger-handler.startListening seeds from listInstanceMetas() AND subscribes to the manifest so instances created at runtime via POST /api/slack/instances are wired automatically, and DELETEs get their onMessage listener torn down. Per-instance unsubscribers tracked in a Map<instanceId, off> for individual detach; stopListening removes the manifest hook plus every per-instance listener. Subscribe is idempotent. Fixes the case where triggers configured for a Slack instance added AFTER server start silently never fired.
excludeChatIds + chatIdAllowlist on WhatsApp triggers — WhatsAppTriggerConfig accepts two new literal-JID arrays. Evaluated EARLY in structuralMatch (after status/broadcast, before isEmptyContent / fromFilter / bodyPattern) so muted chats short-circuit cheap. Exact match via Array.includes — no normalization, no prefix.
excludeChannelIds + channelIdAllowlist on Slack triggers — symmetric to the WhatsApp filters. SlackTriggerConfig accepts two new literal-channel-id arrays evaluated EARLY in structuralMatch (after instanceId / channelId, before userFilter / messagePattern). Exact match.
Technical Details
13 new vitest specs covering manifest event emission, dynamic instance subscribe/unsubscribe, idempotency, stopListening teardown, and exact-match guards (prefix-collision regression test) for both WhatsApp + Slack chat-id filters.
All filters short-circuit BEFORE expensive regex (bodyPattern / messagePattern) so malformed regex on a muted chat is still safe.