feat(agentctl): guild sound mesh journey and guildSoundNamed matcher (Phase 793)
Add runGuildMeshSoundJourney for 2-peer soundboard propagation verification and wait diagnostics for guild sound counts. 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 793 (v0.8.760):** `runGuildMeshSoundJourney` (2-peer custom sound gossip). Bundle: `npm run test:ci-phase793`.
|
||||
|
||||
**Phase 792 (v0.8.759):** `runGuildMeshPinsJourney` (2-peer channel pin gossip). Bundle: `npm run test:ci-phase792`.
|
||||
|
||||
**Phase 791 (v0.8.758):** `runGuildMeshStickerJourney` (2-peer custom sticker gossip). Bundle: `npm run test:ci-phase791`.
|
||||
|
||||
@@ -337,6 +337,14 @@ function matchView (view, spec) {
|
||||
if (!hit) return false
|
||||
continue
|
||||
}
|
||||
if (key === 'guildSoundNamed') {
|
||||
const needle = String(expected).toLowerCase()
|
||||
const hit = (view?.guildSounds || []).some(
|
||||
(s) => String(s?.name || '').toLowerCase() === needle
|
||||
)
|
||||
if (!hit) return false
|
||||
continue
|
||||
}
|
||||
if (key === 'channelPinsMin') {
|
||||
const min = Number(expected) || 0
|
||||
if ((view?.pins || []).length < min) return false
|
||||
|
||||
+44
@@ -4847,6 +4847,50 @@ class HeadlessSession {
|
||||
}
|
||||
}
|
||||
|
||||
/** Phase 793: 2-peer mesh — host custom sound visible in guest guildSounds. */
|
||||
async runGuildMeshSoundJourney () {
|
||||
const { connectGuildMeshPeers } = require('./mesh-helpers')
|
||||
const { buildTestToneWav } = require('pearcord-soundboard')
|
||||
const token = `mesh793_${Date.now()}`
|
||||
const base = path.join(os.tmpdir(), `pearcord-agentctl-sound793-${Date.now()}`)
|
||||
const host = new HeadlessSession({ storagePath: path.join(base, 'host') })
|
||||
const guest = new HeadlessSession({ storagePath: path.join(base, 'guest') })
|
||||
await host.start()
|
||||
await guest.start()
|
||||
try {
|
||||
await host.registerUser({ username: 'sdhost793', displayName: 'Sound Host 793' })
|
||||
await host.createGuild({ name: 'Sound Mesh 793', publicListing: false })
|
||||
await host.wait({ mode: 'guild' }, 45000)
|
||||
const invite = await host.platform.createInvite().catch(() => null)
|
||||
const code = invite?.shareCode || invite?.code
|
||||
if (!code) throw new Error('host invite missing')
|
||||
await guest.registerUser({ username: 'sdguest793', displayName: 'Sound Guest 793' })
|
||||
await guest.ipc({ type: 'join-invite', code })
|
||||
await guest.wait({ mode: 'guild' }, 45000)
|
||||
await connectGuildMeshPeers(host.platform, guest.platform, 45000)
|
||||
await host.upsertGuildSound({
|
||||
name: token,
|
||||
description: 'Mesh 793 sound',
|
||||
audio: {
|
||||
data: buildTestToneWav(250),
|
||||
filename: `${token}.wav`,
|
||||
mimeType: 'audio/wav'
|
||||
}
|
||||
})
|
||||
if (typeof host.platform.requestGuildSyncFanout === 'function') {
|
||||
host.platform.requestGuildSyncFanout()
|
||||
}
|
||||
await guest.wait({ guildSoundNamed: token }, 90000)
|
||||
const gv = await guest.refreshView()
|
||||
const hit = (gv.guildSounds || []).find((s) => s.name === token)
|
||||
if (!hit) throw new Error('guest missing custom sound')
|
||||
return { soundName: token }
|
||||
} finally {
|
||||
await host.close()
|
||||
await guest.close()
|
||||
}
|
||||
}
|
||||
|
||||
/** Phase 791: 2-peer mesh — host custom sticker visible in guest guildStickers. */
|
||||
async runGuildMeshStickerJourney () {
|
||||
const { connectGuildMeshPeers } = require('./mesh-helpers')
|
||||
|
||||
@@ -45,6 +45,7 @@ function snapshotWaitDiagnostics (view, match) {
|
||||
reactionMessageCount: Object.keys(view?.reactions || {}).length,
|
||||
guildCustomEmojiCount: (view?.guildEmojis || []).filter((e) => !e.builtin).length,
|
||||
guildStickerCount: view?.guildStickers?.length ?? 0,
|
||||
guildSoundCount: view?.guildSounds?.length ?? 0,
|
||||
channelPinCount: view?.pins?.length ?? 0,
|
||||
sessionReady: !!view?.sessionReady,
|
||||
workerPoll: view?.workerPoll || null,
|
||||
|
||||
Reference in New Issue
Block a user