fix: dedup status boxes — one per channel, thread sessions take priority

When a bare channel session (no 🧵 suffix) and a thread-specific session
both resolve to the same MM channel/DM, two status boxes appeared simultaneously.

Fix: in session-added handler, before creating a box, check if any existing
active session already owns that channelId. Thread sessions displace bare channel
sessions (and take priority). Bare channel sessions are skipped if a thread
session already exists. First-in wins for same-type duplicates.
This commit is contained in:
Xen
2026-03-09 21:10:41 +00:00
parent e483b0bc42
commit 3fbd46c2d2

View File

@@ -270,6 +270,32 @@ async function startDaemon() {
return; return;
} }
// Dedup: skip if another active session already owns this channel.
// This prevents duplicate status boxes when a threadless parent session and a
// thread-specific child session both resolve to the same MM channel/DM.
// Thread sessions (containing ':thread:') take priority over bare channel sessions.
const isThreadSession = sessionKey.includes(':thread:');
for (const [existingKey, existingBox] of activeBoxes) {
if (existingBox.channelId === channelId) {
const existingIsThread = existingKey.includes(':thread:');
if (isThreadSession && !existingIsThread) {
// New session is a thread — it takes priority. Remove the parent box.
logger.info({ sessionKey, displaced: existingKey }, 'Thread session displacing bare channel session');
activeBoxes.delete(existingKey);
watcher.removeSession(existingKey);
} else if (!isThreadSession && existingIsThread) {
// Existing session is a thread — skip this bare channel session.
logger.debug({ sessionKey, existingKey }, 'Bare channel session skipped — thread session already owns this channel');
return;
} else {
// Same type — skip the newcomer, first-in wins.
logger.debug({ sessionKey, existingKey }, 'Duplicate channel session skipped');
return;
}
break;
}
}
// Enforce MAX_ACTIVE_SESSIONS // Enforce MAX_ACTIVE_SESSIONS
if (activeBoxes.size >= config.maxActiveSessions) { if (activeBoxes.size >= config.maxActiveSessions) {
logger.warn( logger.warn(