#14182: zulip: fix event queue registration for multiple monitored streams
docs
stale
Cluster:
Mattermost and Zulip Enhancements
## Problem
When `channels.zulip.streams` contains multiple stream names, the Zulip plugin was registering an event queue with a `narrow` like:
```json
[["stream","build"],["stream","general"],["stream","openclaw"],["stream","research"]]
```
Zulip narrows are ANDed, so this matches nothing (a message cannot be in multiple streams at once). This caused the default/Marvin account to stop receiving messages, while role accounts (1 stream each) continued to work.
## Fix
- If streams contains `"*"`: use `all_public_streams=true`
- If exactly 1 stream: use `narrow=[["stream","<name>"]]` (legacy list format)
- If multiple streams: omit `narrow` (broad queue) and rely on existing client-side filtering
## Tests
Adds a Vitest regression test covering the three cases above.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes Zulip event queue registration when multiple monitored streams are configured: it uses `all_public_streams=true` for `"*"`, uses a single-stream `narrow` for exactly one stream (legacy list format), and omits `narrow` for multiple streams while enforcing the stream allowlist client-side. It also adds new Zulip plugin implementation files (client, monitor, send/probe, config schema, normalization) plus Vitest coverage for queue registration and stream filtering, and updates docs/labeler to include Zulip.
The change integrates into the channel plugin system by providing a `zulipPlugin` with config + pairing + outbound delivery, a monitor loop using Zulip event queues, and shared helpers for routing/session keys and stream monitoring.
<h3>Confidence Score: 3/5</h3>
- This PR is close to mergeable but has a couple of logic issues that can affect message routing and inbound gating.
- Core stream registration fix looks correct and is covered by targeted tests, but there are two verified logic bugs: outbound parsing can truncate topics, and inbound mention detection uses a hardcoded agentId which can drop messages for routed agents when requireMention is enabled.
- extensions/zulip/src/zulip/send.ts; extensions/zulip/src/zulip/monitor.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22308: feat(zulip): add Zulip channel plugin
by emadomedher · 2026-02-21
82.1%
#15051: feat: Zulip channel plugin with concurrent message processing
by FtlC-ian · 2026-02-12
81.9%
#9006: fix: streaming UI, session locks, routing performance, plugin sandb...
by facundollamas2007 · 2026-02-04
71.4%
#11608: feat(slack): native streaming, Block Kit blocks, tool-aware status
by joshdavisind · 2026-02-08
70.9%
#21754: slack: pass inbound team_id into stream routing and startStream
by AIflow-Labs · 2026-02-20
69.9%
#13881: fix: Address Greptile feedback - test isolation and channel resolution
by trevorgordon981 · 2026-02-11
69.9%
#12248: fix: wire streaming config field through resolveExtraParams to stre...
by mcaxtr · 2026-02-09
68.9%
#4878: fix: string/type handling and API fixes (#4537, #4380, #4373, #4547...
by lailoo · 2026-01-30
68.7%
#23727: Fix Telegram channel resolution drift across announce + message sen...
by SmithLabsLLC · 2026-02-22
68.5%
#20623: fix(slack): duplicate replies and missing streaming recipient params
by rahulsub-be · 2026-02-19
68.3%