feat(platform): DM voice/video call stubs and group rename API (Phase 655)

Add renameGroupDM, startDmVoiceCall, startDmVideoCall spans and dm.open
sidebarFilterActive metadata for inbox telemetry and P2P call groundwork.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-02 00:25:16 -04:00
co-authored by Cursor
parent 5c941bf38e
commit c3f07793dc
2 changed files with 90 additions and 4 deletions
+3 -1
View File
@@ -2,7 +2,9 @@
Application facade: one `PearcordPlatform` class that wires identity, database, guild mesh, DMs, invites, voice, discovery, bots, and dozens of feature modules for the Pearcord desktop sidecar and companion.
**Phase 654 (current, 50 swarm/repl/sync items active):** Global mesh resilience — adaptive peer retry + discovery refresh aid (P654-1), improved backoff using swarm adaptive (P654-26 area), replicator joiner attach work, auto-heal triggers, full CRDT slices, diagnostics. Composer UI production polish (autofocus always-ready, send button, autogrow) landed in renderer + verified via manual agentctl + pear run BOOT_OK. See PLATFORM_ROADMAP.md.
**Phase 655 (v0.8.628):** `renameGroupDM`, `startDmVoiceCall` / `startDmVideoCall` (P2P stubs + spans), `dm.open` `sidebarFilterActive` metadata. See [DM_INBOX.md](../../docs/DM_INBOX.md).
**Phase 654 (50 swarm/repl/sync items):** Global mesh resilience — adaptive peer retry + discovery refresh aid (P654-1), improved backoff using swarm adaptive (P654-26 area), replicator joiner attach work, auto-heal triggers, full CRDT slices, diagnostics.
## Mission
+87 -3
View File
@@ -1734,11 +1734,12 @@ class PearcordPlatform extends EventEmitter {
return user
}
async openDM ({ peerUserId, peerDisplayName }) {
async openDM ({ peerUserId, peerDisplayName, sidebarFilterActive = false }) {
const span = this.log.time('dm.open', {
spanKind: 'dm.open',
peerUserId: peerUserId || null,
peerDisplayNameLen: String(peerDisplayName || '').trim().length
peerDisplayNameLen: String(peerDisplayName || '').trim().length,
sidebarFilterActive: !!sidebarFilterActive
})
try {
await this._initDmSession()
@@ -1770,7 +1771,8 @@ class PearcordPlatform extends EventEmitter {
reusedChannel,
dmConversationCount: dmConversations.length,
activeChannelId: channel.id,
guildCount: (this.guilds || []).length
guildCount: (this.guilds || []).length,
sidebarFilterActive: !!sidebarFilterActive
})
return channel
} catch (err) {
@@ -1783,6 +1785,88 @@ class PearcordPlatform extends EventEmitter {
}
}
async renameGroupDM ({ channelId, displayName }) {
const label = String(displayName || '').trim()
const span = this.log.time('dm.group.rename', {
spanKind: 'dm.group.rename',
channelId: channelId || null,
nameLen: label.length
})
try {
await this._initDmSession()
const channel = await this.dm.renameGroup(channelId, label)
if (this.dm?.channel?.id === channel.id) {
this.emit('dm', this.dm.channel)
}
const dmConversations = await this.listDMConversations()
span.end({
spanKind: 'dm.group.rename',
channelId: channel.id,
nameLen: label.length,
dmConversationCount: dmConversations.length,
activeChannelId: this.activeChannelId
})
return channel
} catch (err) {
this.log.error('dm.group.rename error', {
channelId,
error: err?.message || String(err)
})
span.fail(err)
throw err
}
}
async startDmVoiceCall () {
if (this.mode !== 'dm') throw new Error('not in dm')
const ch = this.dm?.channel
if (!ch?.id) throw new Error('no dm channel')
const span = this.log.time('dm.voice.call', {
spanKind: 'dm.voice.call',
channelId: ch.id,
group: !!ch.isGroup
})
try {
const peerUserId = this._dmPeerId()
span.end({
spanKind: 'dm.voice.call',
channelId: ch.id,
group: !!ch.isGroup,
peerUserId: peerUserId || null,
stub: true
})
return { started: true, stub: true, channelId: ch.id, peerUserId }
} catch (err) {
span.fail(err)
throw err
}
}
async startDmVideoCall () {
if (this.mode !== 'dm') throw new Error('not in dm')
const ch = this.dm?.channel
if (!ch?.id) throw new Error('no dm channel')
const span = this.log.time('dm.video.call', {
spanKind: 'dm.video.call',
channelId: ch.id,
group: !!ch.isGroup
})
try {
const peerUserId = this._dmPeerId()
span.end({
spanKind: 'dm.video.call',
channelId: ch.id,
group: !!ch.isGroup,
peerUserId: peerUserId || null,
stub: true
})
return { started: true, stub: true, channelId: ch.id, peerUserId }
} catch (err) {
span.fail(err)
throw err
}
}
async createGroupDM ({ peerUserIds, name }) {
const ids = peerUserIds || []
const span = this.log.time('dm.group.create', {