feat: M12-MatrixBridge — Matrix/Element chat bridge integration #408

Merged
jason.woltje merged 18 commits from feature/m12-matrix-bridge into develop 2026-02-15 18:22:17 +00:00
Owner

Summary

Complete implementation of the Matrix/Element chat bridge for Mosaic Stack (Milestone M12-MatrixBridge, 0.0.12).

What's included

  • MatrixService — Full IChatProvider implementation with matrix-bot-sdk: connect/disconnect, message sending, MSC3440 thread support, command parsing via shared CommandParserService
  • MatrixRoomService — Workspace-to-Matrix-room mapping: provision rooms, link/unlink existing rooms, reverse lookup for message routing
  • MatrixStreamingService — Streaming AI responses via Matrix message edits (m.replace): rate-limited at 500ms, typing indicators, graceful error handling
  • BridgeModule conditional loading — CHAT_PROVIDERS injection token: Discord loads if DISCORD_BOT_TOKEN set, Matrix loads if MATRIX_ACCESS_TOKEN set, both can coexist
  • Herald Service refactored — From Discord-specific to bridge-agnostic CHAT_PROVIDERS broadcasting
  • Dev infrastructure — docker-compose.matrix.yml overlay (Synapse + Element Web), bot setup script
  • Documentation — docs/MATRIX-BRIDGE.md: architecture, setup guide, command reference, deployment considerations

Test coverage

  • 95 matrix-related tests (39 unit + 10 room + 20 streaming + 26 integration)
  • Integration tests cover: BridgeModule DI, command flow, Herald broadcast, room mapping, streaming, multi-provider coexistence
  • All pre-commit quality gates pass (lint, typecheck, prettier, git-secrets)

Issues closed

Fixes #378, #379, #380, #381, #382, #383, #384, #385, #386, #387
Epic: #377

Test plan

  • All 95 matrix tests pass: `pnpm --filter @mosaic/api exec vitest run src/bridge/matrix/`
  • Herald tests pass: `pnpm --filter @mosaic/api exec vitest run src/herald/`
  • BridgeModule tests pass: `pnpm --filter @mosaic/api exec vitest run src/bridge/bridge.module`
  • TypeScript compiles: `pnpm --filter @mosaic/api exec tsc --noEmit`
  • Prisma migration applies: `pnpm prisma:migrate`
## Summary Complete implementation of the Matrix/Element chat bridge for Mosaic Stack (Milestone M12-MatrixBridge, 0.0.12). ### What's included - **MatrixService** — Full IChatProvider implementation with matrix-bot-sdk: connect/disconnect, message sending, MSC3440 thread support, command parsing via shared CommandParserService - **MatrixRoomService** — Workspace-to-Matrix-room mapping: provision rooms, link/unlink existing rooms, reverse lookup for message routing - **MatrixStreamingService** — Streaming AI responses via Matrix message edits (m.replace): rate-limited at 500ms, typing indicators, graceful error handling - **BridgeModule conditional loading** — CHAT_PROVIDERS injection token: Discord loads if DISCORD_BOT_TOKEN set, Matrix loads if MATRIX_ACCESS_TOKEN set, both can coexist - **Herald Service refactored** — From Discord-specific to bridge-agnostic CHAT_PROVIDERS broadcasting - **Dev infrastructure** — docker-compose.matrix.yml overlay (Synapse + Element Web), bot setup script - **Documentation** — docs/MATRIX-BRIDGE.md: architecture, setup guide, command reference, deployment considerations ### Test coverage - 95 matrix-related tests (39 unit + 10 room + 20 streaming + 26 integration) - Integration tests cover: BridgeModule DI, command flow, Herald broadcast, room mapping, streaming, multi-provider coexistence - All pre-commit quality gates pass (lint, typecheck, prettier, git-secrets) ### Issues closed Fixes #378, #379, #380, #381, #382, #383, #384, #385, #386, #387 Epic: #377 ## Test plan - [ ] All 95 matrix tests pass: \`pnpm --filter @mosaic/api exec vitest run src/bridge/matrix/\` - [ ] Herald tests pass: \`pnpm --filter @mosaic/api exec vitest run src/herald/\` - [ ] BridgeModule tests pass: \`pnpm --filter @mosaic/api exec vitest run src/bridge/bridge.module\` - [ ] TypeScript compiles: \`pnpm --filter @mosaic/api exec tsc --noEmit\` - [ ] Prisma migration applies: \`pnpm prisma:migrate\`
jason.woltje added 14 commits 2026-02-15 08:43:39 +00:00
Parsed 11 issues into 10 tasks across 6 phases.
#387 already completed. Estimated total: ~160K tokens.

Refs #377
feat(#384): Add Synapse + Element Web to docker-compose for dev
All checks were successful
ci/woodpecker/push/infra Pipeline was successful
4a5cb6441e
- Create docker-compose.matrix.yml as optional dev overlay
- Add Synapse homeserver config with shared PostgreSQL
- Add Element Web client config (port 8501)
- Add bot account setup script (docker/matrix/scripts/setup-bot.sh)
- Add Makefile targets: matrix-up, matrix-down, matrix-logs, matrix-setup-bot
- Document Matrix env vars in .env.example
- Synapse accessible at localhost:8008, Element at localhost:8501
- Usage: docker compose -f docker/docker-compose.yml -f docker/docker-compose.matrix.yml up

Refs #384

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(#378): Install matrix-bot-sdk and create MatrixService skeleton
Some checks failed
ci/woodpecker/push/api Pipeline failed
ci/woodpecker/push/orchestrator Pipeline failed
ci/woodpecker/push/web Pipeline failed
5b5d3811d6
- Add matrix-bot-sdk dependency to @mosaic/api
- Create MatrixService implementing IChatProvider interface
- Support connect/disconnect, message sending, thread management
- Parse @mosaic and !mosaic command prefixes
- Delegate commands to StitcherService (same flow as Discord)
- Add comprehensive unit tests with mocked MatrixClient (31 tests)
- Add Matrix env vars to .env.example

Refs #378

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MB-001 (MatrixService skeleton): done — commit 5b5d381
MB-002 (Synapse dev compose): done — commit 4a5cb64
MB-003, MB-004: in-progress

Refs #377
feat(#380): Workspace-to-Matrix-Room mapping and provisioning
Some checks failed
ci/woodpecker/push/api Pipeline failed
7d22c2490a
- Add matrix_room_id column to workspace table (migration)
- Create MatrixRoomService for room provisioning and mapping
- Auto-create Matrix room on workspace provisioning (when configured)
- Support manual room linking for existing workspaces
- Unit tests for all mapping operations

Refs #380
feat(#379): Register MatrixService in BridgeModule with conditional loading
Some checks failed
ci/woodpecker/push/api Pipeline failed
771ed484e4
- Add CHAT_PROVIDERS injection token for bridge-agnostic access
- Conditional loading based on env vars (DISCORD_BOT_TOKEN, MATRIX_ACCESS_TOKEN)
- Both bridges can run simultaneously
- No crash if neither bridge is configured
- Tests verify all configuration combinations

Refs #379
MB-003 (BridgeModule conditional loading): done — commit 771ed48
MB-004 (Workspace-Room mapping): done — commit 7d22c24
MB-005, MB-006: in-progress

Refs #377
feat(#382): Herald Service: broadcast to all active chat providers
Some checks failed
ci/woodpecker/push/api Pipeline failed
ad24720616
- Replace direct DiscordService injection with CHAT_PROVIDERS array
- Herald broadcasts to ALL active chat providers (Discord, Matrix, future)
- Graceful error handling — one provider failure doesn't block others
- Skips disconnected providers automatically
- Tests verify multi-provider broadcasting behavior
- Fix lint: remove unnecessary conditional in matrix.service.ts

Refs #382
MB-005 (Matrix command handling) and MB-006 (Herald adapter) done.
Both committed in ad24720 (bundled by pre-commit hooks).
49 Matrix tests pass, 112 total bridge tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(#383): Streaming AI responses via Matrix message edits
Some checks failed
ci/woodpecker/push/api Pipeline failed
93cd31435b
- Add MatrixStreamingService with editMessage, setTypingIndicator, streamResponse
- Rate-limited edits (500ms) for incremental streaming output
- Typing indicator management during generation
- Graceful error handling and fallback for non-streaming scenarios
- Add optional editMessage to IChatProvider interface
- Add getClient() accessor to MatrixService for streaming service
- Register MatrixStreamingService in BridgeModule
- Tests: 20 tests pass

Refs #383

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MB-007 (Streaming AI responses) done in commit 93cd314.
20 new tests, 132 total bridge tests pass.
Launching MB-008 (E2E tests) and MB-009 (Docs) in parallel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Quick start guide for dev environment
- Architecture overview with service responsibilities
- Command reference with examples
- Configuration reference
- Streaming response architecture
- Deployment considerations

Refs #386

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- BridgeModule DI verification (conditional loading)
- Command flow: message -> parser -> dispatch
- Herald multi-provider broadcast
- Room-workspace mapping integration
- Streaming flow verification
- Multi-provider coexistence

Refs #385

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
chore(orchestrator): All M12-MatrixBridge tasks complete
Some checks failed
ci/woodpecker/push/api Pipeline failed
a1f0d1dd71
All 10 tasks done:
- MB-001: MatrixService skeleton (5b5d381)
- MB-002: Dev docker-compose (4a5cb64)
- MB-003: BridgeModule conditional loading (771ed48)
- MB-004: Workspace-Room mapping (7d22c24)
- MB-005: Matrix command handling (ad24720)
- MB-006: Herald multi-provider adapter (ad24720)
- MB-007: Streaming AI responses (93cd314)
- MB-008: Integration tests - 26 tests (9cc70db)
- MB-009: Documentation (68808c0)
- MB-010: Sample compose (6e20fc5, pre-existing)

95 matrix tests pass. Ready for PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-02-15 09:01:55 +00:00
fix(#377): remediate code review and security findings
Some checks failed
ci/woodpecker/push/infra Pipeline was successful
ci/woodpecker/push/api Pipeline failed
8d19ac1f4b
- Fix sendThreadMessage room mismatch: use channelId from options instead of hardcoded controlRoomId
- Add .catch() to fire-and-forget handleRoomMessage to prevent silent error swallowing
- Wrap dispatchJob in try-catch for user-visible error reporting in handleFixCommand
- Add MATRIX_BOT_USER_ID validation in connect() to prevent infinite message loops
- Fix streamResponse error masking: wrap finally/catch side-effects in try-catch
- Replace unsafe type assertion with public getClient() in MatrixRoomService
- Add orphaned room warning in provisionRoom on DB failure
- Add provider identity to Herald error logs
- Add channelId to ThreadMessageOptions interface and all callers
- Add missing env var warnings in BridgeModule factory
- Fix JSON injection in setup-bot.sh: use jq for safe JSON construction

Fixes #377

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-02-15 09:02:38 +00:00
jason.woltje added 1 commit 2026-02-15 18:13:27 +00:00
merge: resolve conflicts with develop (telemetry + lockfile)
Some checks failed
ci/woodpecker/push/infra Pipeline was successful
ci/woodpecker/push/api Pipeline failed
ci/woodpecker/push/web Pipeline failed
ci/woodpecker/push/orchestrator Pipeline failed
ci/woodpecker/push/coordinator Pipeline was successful
eca2c46e9d
Keep both Mosaic Telemetry section (from develop) and Matrix Dev
Environment section (from feature branch) in .env.example.
Regenerate pnpm-lock.yaml with both dependency trees merged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-02-15 18:17:24 +00:00
fix(#377): add pnpm overrides for matrix-bot-sdk transitive vulnerabilities
All checks were successful
ci/woodpecker/push/orchestrator Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
ci/woodpecker/push/api Pipeline was successful
3cc2030446
matrix-bot-sdk depends on the deprecated `request` library which pulls
in vulnerable form-data (<2.5.4, critical: unsafe random boundary) and
qs (<6.14.1, high: DoS via memory exhaustion). Add pnpm overrides to
force patched versions since matrix-bot-sdk has no newer release.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jason.woltje merged commit 11d284554d into develop 2026-02-15 18:22:17 +00:00
Sign in to join this conversation.