From fdc49f475e5383d33b6e83e9573e3f000d8e405b Mon Sep 17 00:00:00 2001 From: Artem Rootman <4586640+artemrootman@users.noreply.github.com> Date: Sun, 5 Apr 2026 16:38:09 +0000 Subject: [PATCH 1/2] fix: filter out system inboxes (*, user) from team member list The broadcast inbox file (inboxes/*.json) was being parsed by listInboxNames() as a member named "*", which appeared in the UI as a phantom team member. Since "*" fails the MEMBER_NAME_PATTERN validation, it could not be removed through the UI. Filter system inbox names (*, user) from listInboxNames() so they are not treated as real team members. --- src/main/services/team/TeamInboxReader.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/services/team/TeamInboxReader.ts b/src/main/services/team/TeamInboxReader.ts index 563a634c..95fc44b2 100644 --- a/src/main/services/team/TeamInboxReader.ts +++ b/src/main/services/team/TeamInboxReader.ts @@ -42,9 +42,14 @@ export class TeamInboxReader { throw error; } + // Exclude broadcast inbox (*.json) and user inbox (user.json) — these are + // system inboxes, not real team members. Without this filter, '*' appears + // as a phantom member in the UI that can't be removed. + const SYSTEM_INBOX_NAMES = new Set(['*', 'user']); return entries .filter((name) => name.endsWith('.json') && !name.startsWith('.')) - .map((name) => name.replace(/\.json$/, '')); + .map((name) => name.replace(/\.json$/, '')) + .filter((name) => !SYSTEM_INBOX_NAMES.has(name)); } async getMessagesFor(teamName: string, member: string): Promise { From 23796cddc3e3b959385216c2041ae9c50323f02b Mon Sep 17 00:00:00 2001 From: Artem Rootman <4586640+artemrootman@users.noreply.github.com> Date: Sun, 5 Apr 2026 16:45:31 +0000 Subject: [PATCH 2/2] fix: only filter broadcast inbox (*), keep user inbox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user inbox (user.json) contains real teammate-to-user messages generated by Claude Code CLI. Filtering it as a system inbox was incorrect — it broke message aggregation for user-directed messages. Only the broadcast inbox (*.json) needs to be excluded since '*' is not a valid member name and causes a phantom member in the UI. --- src/main/services/team/TeamInboxReader.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/services/team/TeamInboxReader.ts b/src/main/services/team/TeamInboxReader.ts index 95fc44b2..a020e29a 100644 --- a/src/main/services/team/TeamInboxReader.ts +++ b/src/main/services/team/TeamInboxReader.ts @@ -42,14 +42,10 @@ export class TeamInboxReader { throw error; } - // Exclude broadcast inbox (*.json) and user inbox (user.json) — these are - // system inboxes, not real team members. Without this filter, '*' appears - // as a phantom member in the UI that can't be removed. - const SYSTEM_INBOX_NAMES = new Set(['*', 'user']); return entries .filter((name) => name.endsWith('.json') && !name.startsWith('.')) .map((name) => name.replace(/\.json$/, '')) - .filter((name) => !SYSTEM_INBOX_NAMES.has(name)); + .filter((name) => name !== '*'); } async getMessagesFor(teamName: string, member: string): Promise {