feat(agentctl): channel topic and forum tag mesh journey (Phase 797)
runGuildMeshChannelTopicJourney with activeChannelTopicIncludes and forumTagPaletteMin. 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.
|
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 797 (v0.8.764):** `runGuildMeshChannelTopicJourney` (topic + forum tags). Bundle: `npm run test:ci-phase797`.
|
||||||
|
|
||||||
**Phase 796 (v0.8.763):** `runGuildMeshTriplePartitionHealJourney` (3-peer heal + presence). Bundle: `npm run test:ci-phase796`.
|
**Phase 796 (v0.8.763):** `runGuildMeshTriplePartitionHealJourney` (3-peer heal + presence). Bundle: `npm run test:ci-phase796`.
|
||||||
|
|
||||||
**Phase 795 (v0.8.762):** `runGuildMeshTripleMessageJourney` (3-peer message fanout); exports `connectGuildMeshTriple`. Bundle: `npm run test:ci-phase795`.
|
**Phase 795 (v0.8.762):** `runGuildMeshTripleMessageJourney` (3-peer message fanout); exports `connectGuildMeshTriple`. Bundle: `npm run test:ci-phase795`.
|
||||||
|
|||||||
@@ -93,6 +93,20 @@ function matchView (view, spec) {
|
|||||||
if (sec < Number(spec.minSeconds ?? 1)) return false
|
if (sec < Number(spec.minSeconds ?? 1)) return false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (key === 'activeChannelTopicIncludes') {
|
||||||
|
const needle = String(expected || '')
|
||||||
|
const chId = view?.activeChannelId
|
||||||
|
const ch = (view?.channels || []).find((c) => c.id === chId)
|
||||||
|
const topic = ch?.topic || view?.activeChannelSummary?.topic || ''
|
||||||
|
if (!String(topic).includes(needle)) return false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (key === 'forumTagPaletteMin') {
|
||||||
|
const min = Number(expected ?? 1)
|
||||||
|
const n = (view?.forumPaletteTags || []).length
|
||||||
|
if (n < min) return false
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (key === 'typingUsersIncludes') {
|
if (key === 'typingUsersIncludes') {
|
||||||
const uid = String(expected || '')
|
const uid = String(expected || '')
|
||||||
if (!(view?.typingUsers || []).includes(uid)) return false
|
if (!(view?.typingUsers || []).includes(uid)) return false
|
||||||
|
|||||||
+51
@@ -4986,6 +4986,57 @@ class HeadlessSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Phase 797: 2-peer mesh — host topic + forum tags visible on guest. */
|
||||||
|
async runGuildMeshChannelTopicJourney () {
|
||||||
|
const { connectGuildMeshPeers } = require('./mesh-helpers')
|
||||||
|
const topicToken = `mesh797_${Date.now()}`
|
||||||
|
const tagA = `tag797a_${Date.now()}`
|
||||||
|
const tagB = `tag797b_${Date.now()}`
|
||||||
|
const base = path.join(os.tmpdir(), `pearcord-agentctl-chtopic797-${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: 'cthost797', displayName: 'Topic Host 797' })
|
||||||
|
await host.createGuild({ name: 'Topic Mesh 797', 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: 'ctguest797', displayName: 'Topic Guest 797' })
|
||||||
|
await guest.ipc({ type: 'join-invite', code })
|
||||||
|
await guest.wait({ mode: 'guild' }, 45000)
|
||||||
|
const textId = (await host.refreshView()).activeChannelId
|
||||||
|
if (!textId) throw new Error('active text channel missing')
|
||||||
|
await guest.ipc({ type: 'select-channel', channelId: textId })
|
||||||
|
await guest.wait({ activeChannelId: textId }, 30000)
|
||||||
|
await connectGuildMeshPeers(host.platform, guest.platform, 45000)
|
||||||
|
await host.platform.setChannelTopic(textId, `Phase 797 ${topicToken}`)
|
||||||
|
if (typeof host.platform.requestGuildSyncFanout === 'function') {
|
||||||
|
host.platform.requestGuildSyncFanout()
|
||||||
|
}
|
||||||
|
await guest.wait({ activeChannelTopicIncludes: topicToken }, 90000)
|
||||||
|
const forumCh = await host.createGuildChannel('Forum Topic 797', { type: 'forum' })
|
||||||
|
await guest.ipc({ type: 'select-channel', channelId: forumCh.id })
|
||||||
|
await guest.wait({ activeChannelId: forumCh.id }, 30000)
|
||||||
|
await host.platform.setForumChannelPalette(forumCh.id, [tagA, tagB])
|
||||||
|
if (typeof host.platform.requestGuildSyncFanout === 'function') {
|
||||||
|
host.platform.requestGuildSyncFanout()
|
||||||
|
}
|
||||||
|
await guest.wait({ forumTagPaletteMin: 2 }, 90000)
|
||||||
|
const gv = await guest.refreshView()
|
||||||
|
const palette = gv.forumPaletteTags || []
|
||||||
|
if (!palette.includes(tagA) || !palette.includes(tagB)) {
|
||||||
|
throw new Error('guest missing forum tag palette')
|
||||||
|
}
|
||||||
|
return { channelId: textId, topicToken, forumChannelId: forumCh.id, palette }
|
||||||
|
} finally {
|
||||||
|
await host.close()
|
||||||
|
await guest.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Phase 794: 2-peer mesh — host slowmode visible in guest channelSettings. */
|
/** Phase 794: 2-peer mesh — host slowmode visible in guest channelSettings. */
|
||||||
async runGuildMeshChannelSettingsJourney () {
|
async runGuildMeshChannelSettingsJourney () {
|
||||||
const { connectGuildMeshPeers } = require('./mesh-helpers')
|
const { connectGuildMeshPeers } = require('./mesh-helpers')
|
||||||
|
|||||||
Reference in New Issue
Block a user