Context
A user runs more than one Zigbee2MQTT instance (separate coordinators, separate networks) and wants Shellbee to manage both from a single app. Today the entire app is hard-wired to a single bridge: one WebSocket client, one AppStore keyed only by friendly-name/IEEE, one ConnectionConfig slot, one Live Activity per coordinator, and ~50 UI surfaces that read environment.store.* with no concept of "which bridge".
This epic tracks the work, split into two phases. The full plan with file-level analysis lives at /Users/k/.claude/plans/please-make-detailed-github-zesty-umbrella.md (local-only) and is mirrored into the sub-issue bodies.
Two-phase rollout
Phase 1 — Saved Bridges + Switcher (milestone v1.6.0, ~2 weeks)
Reuse the existing single-bridge UI verbatim. Add a list of saved bridges, a switcher, one-tap reconnect. No store changes. Solves ~60% of user intent with no architectural surgery.
Phase 2 — True Simultaneous Multi-Bridge (milestone v2.0.0, ~4–6 weeks)
Re-key the entire store by BridgeID. Run N concurrent connections. Surface a per-bridge dimension in every UI screen. Multi Live Activities. Gated on Phase 1 ship + user demand confirmation.
Recommendation
Ship Phase 1, ship it on its own, and observe whether users actually need simultaneous (Phase 2) or whether fast-switching is sufficient. Phase 2 is a deep architectural change that should only be picked up if Phase 1 demand confirms it.
Critical files (master list)
See individual issues for per-issue file lists. High-level:
- Phase 1 touches:
AppEnvironment.swift, ConnectionSessionController.swift, ConnectionConfig.swift, ConnectionHistory.swift, AppStore.swift (audit only), Connection Live Activity, new SavedBridgesView.swift, new BridgeSwitcherToolbarItem.swift, toolbars in HomeView/DeviceListView/GroupListView/LogsView, docker-compose.yml.
- Phase 2 touches: all of Phase 1 plus new
BridgeConnectionRegistry.swift, full re-key of AppStore and all AppStore+*.swift, ~50 view files, all Live Activity coordinators/widgets, OTABulkOperationQueue, NotificationPreferences, Z2MEvent, Sentry/log layer.
Context
A user runs more than one Zigbee2MQTT instance (separate coordinators, separate networks) and wants Shellbee to manage both from a single app. Today the entire app is hard-wired to a single bridge: one WebSocket client, one
AppStorekeyed only by friendly-name/IEEE, oneConnectionConfigslot, one Live Activity per coordinator, and ~50 UI surfaces that readenvironment.store.*with no concept of "which bridge".This epic tracks the work, split into two phases. The full plan with file-level analysis lives at
/Users/k/.claude/plans/please-make-detailed-github-zesty-umbrella.md(local-only) and is mirrored into the sub-issue bodies.Two-phase rollout
Phase 1 — Saved Bridges + Switcher (milestone v1.6.0, ~2 weeks)
Reuse the existing single-bridge UI verbatim. Add a list of saved bridges, a switcher, one-tap reconnect. No store changes. Solves ~60% of user intent with no architectural surgery.
Phase 2 — True Simultaneous Multi-Bridge (milestone v2.0.0, ~4–6 weeks)
Re-key the entire store by
BridgeID. Run N concurrent connections. Surface a per-bridge dimension in every UI screen. Multi Live Activities. Gated on Phase 1 ship + user demand confirmation.Recommendation
Ship Phase 1, ship it on its own, and observe whether users actually need simultaneous (Phase 2) or whether fast-switching is sufficient. Phase 2 is a deep architectural change that should only be picked up if Phase 1 demand confirms it.
Critical files (master list)
See individual issues for per-issue file lists. High-level:
AppEnvironment.swift,ConnectionSessionController.swift,ConnectionConfig.swift,ConnectionHistory.swift,AppStore.swift(audit only), Connection Live Activity, newSavedBridgesView.swift, newBridgeSwitcherToolbarItem.swift, toolbars in HomeView/DeviceListView/GroupListView/LogsView,docker-compose.yml.BridgeConnectionRegistry.swift, full re-key ofAppStoreand allAppStore+*.swift, ~50 view files, all Live Activity coordinators/widgets,OTABulkOperationQueue,NotificationPreferences,Z2MEvent, Sentry/log layer.