185209242e
The union agent roster (host.agents) enumerates EVERY registered connection, including the active gateway that already answered profiles.list. The plugin merger treated the active gateway's own agents as rows from other sources because a remote-primary desktop reports them with connectionKind 'remote', so every bot appeared twice (baseline) and kept growing with each refetch. Match union agents to the active gateway via the new primaryConnectionId field on the roster RPC response and annotate the local rows in place instead of appending phantom copies. Same-named profiles on genuinely separate sources (This device, other remotes) still get their own tagged rows, preserving the @name-device disambiguation rule. Fall back to the legacy connectionKind==='local' rule when primaryConnectionId is absent (older Electron builds), so single-source behavior is byte-identical. Fixes #88344