feat(agentctl): Phase 673 member/voice/stage headless journeys
Add runMemberListJourney, runVoiceRosterJourney, and runStageSpeakerJourney for Phase 673 regression coverage alongside README notes. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
Agent control plane for Pearcord — send the same IPC messages the UI sends, read `view` snapshots, and run scripted journeys against a **live worker** or an in-process **headless** session.
|
||||
|
||||
**Phase 673 (v0.8.648):** `runMemberListJourney`, `runVoiceRosterJourney`, `runStageSpeakerJourney`; bundle `test:agentctl-phase673-member-voice`.
|
||||
|
||||
**Phase 672 (v0.8.647):** `runThreadCreateJourney`, `runForumPostSearchJourney`, `runThreadArchiveJourney`; bundle `test:agentctl-phase672-threads-forum`.
|
||||
|
||||
**Phase 671 (v0.8.646):** `runSearchModalJourney`, `runPinToggleJourney`, `runJumpToMessageJourney`; bundle `test:agentctl-phase671-search-pins`.
|
||||
|
||||
+49
@@ -3113,6 +3113,55 @@ class HeadlessSession {
|
||||
return { threadId, messageId: row.id }
|
||||
}
|
||||
|
||||
async runMemberListJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
await this.registerUser({ username: 'mb673', displayName: 'Member 673' })
|
||||
await this.createGuild({ name: 'Member 673', publicListing: false })
|
||||
await this.wait({ mode: 'guild' }, 45000)
|
||||
const v = await this.refreshView()
|
||||
const memberCount = (v.members || []).length
|
||||
if (memberCount < 1) throw new Error('expected at least one member in roster view')
|
||||
const presencePeers = (v.presence?.peers || []).length
|
||||
return { memberCount, presencePeers, guildId: v.guild?.id }
|
||||
}
|
||||
|
||||
async runVoiceRosterJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
await this.registerUser({ username: 'vc673', displayName: 'Voice 673' })
|
||||
await this.createGuild({ name: 'Voice 673', publicListing: false })
|
||||
await this.wait({ mode: 'guild' }, 45000)
|
||||
const voiceCh = await this.createGuildChannel('Voice Room', { type: 'voice', userLimit: 10 })
|
||||
if (!voiceCh?.id) throw new Error('expected voice channel')
|
||||
await this.joinGuildVoiceChannel(voiceCh.id)
|
||||
const v = await this.refreshView()
|
||||
if (v.myVoiceChannelId !== voiceCh.id) {
|
||||
throw new Error('expected myVoiceChannelId after join')
|
||||
}
|
||||
const peers = v.voiceStatesByChannel?.[voiceCh.id] || []
|
||||
if (!peers.some((p) => p.userId === v.user?.id)) {
|
||||
throw new Error('expected self in voiceStatesByChannel')
|
||||
}
|
||||
await this.leaveGuildVoiceChannel()
|
||||
return { channelId: voiceCh.id, peerCount: peers.length }
|
||||
}
|
||||
|
||||
async runStageSpeakerJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
await this.registerUser({ username: 'st673', displayName: 'Stage 673' })
|
||||
await this.createGuild({ name: 'Stage 673', publicListing: false })
|
||||
await this.wait({ mode: 'guild' }, 45000)
|
||||
const stageCh = await this.createGuildChannel('Main Stage', { type: 'stage' })
|
||||
if (!stageCh?.id) throw new Error('expected stage channel')
|
||||
await this.joinGuildStageChannel(stageCh.id)
|
||||
const v = await this.refreshView()
|
||||
if (v.myVoiceChannelId !== stageCh.id) {
|
||||
throw new Error('expected stage channel active after join')
|
||||
}
|
||||
const peers = v.voiceStatesByChannel?.[stageCh.id] || []
|
||||
if (!peers.length) throw new Error('expected stage voice state row')
|
||||
return { channelId: stageCh.id, peerCount: peers.length, myStageRole: v.myStageRole }
|
||||
}
|
||||
|
||||
async upsertGuildSound (opts) {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
const row = await this.platform.upsertGuildSound(opts)
|
||||
|
||||
Reference in New Issue
Block a user