feat(agentctl): channel search and mention-alert clear scenarios (v0.8.264)

Add seedMentionAlertForActiveChannel step, mentionAlertCountMax wait matcher,
and document agentctl-channel-search and mark-read-mention-alerts scenarios.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-23 07:29:14 -04:00
co-authored by Cursor
parent e666a8f899
commit 7ce437a14d
3 changed files with 30 additions and 1 deletions
+3 -1
View File
@@ -150,10 +150,12 @@ Bundled scenarios under `apps/pearcord/scenarios/`:
| `agentctl-thread-notif-mark-read.json` | Thread from message + `markThreadAndParentRead` (v0.8.262) |
| `agentctl-guild-search-mesh.json` | Guild-wide search with mesh enabled (v0.8.263) |
| `agentctl-guild-load-supersede.json` | Second `create-guild` + beta search not served from cache (v0.8.263) |
| `agentctl-channel-search.json` | Channel-scoped `update-search` hit (v0.8.264) |
| `agentctl-mark-read-mention-alerts.json` | Seed mention alert + `markActiveChannelRead` clears `mentionAlerts` (v0.8.264) |
`mesh.connectGuildMeshThread(scenarioPath)` — host steps + invite + `create-thread` + reply; guest must receive `threadReply` token.
Scenario step extras (headless + attached `run`): `joinFirstVoice`, `openDmPeer`, `selectFirstForumChannel`, `markActiveChannelRead`, `createThreadFromLastMessage`, `markThreadAndParentRead`, `messagesMin`, `messageContentIncludes`, `searchResultsMin`, `searchResultsMax` on `wait`.
Scenario step extras (headless + attached `run`): `joinFirstVoice`, `openDmPeer`, `selectFirstForumChannel`, `markActiveChannelRead`, `seedMentionAlertForActiveChannel`, `createThreadFromLastMessage`, `markThreadAndParentRead`, `messagesMin`, `messageContentIncludes`, `searchResultsMin`, `searchResultsMax`, `mentionAlertCountMax` on `wait`.
## Dependencies
+9
View File
@@ -40,6 +40,15 @@ function matchView (view, spec) {
if ((view?.searchResults || []).length > Number(expected)) return false
continue
}
if (key === 'mentionAlertCountMax') {
const alerts = view?.mentionAlerts || {}
const max = Object.values(alerts).reduce(
(m, v) => Math.max(m, Number(v) || 0),
0
)
if (max > Number(expected)) return false
continue
}
if (key === 'voiceJoined') {
if (expected && !view?.myVoiceChannelId) return false
if (!expected && view?.myVoiceChannelId) return false
+18
View File
@@ -4,6 +4,7 @@ const path = require('bare-path')
const os = require('bare-os')
const fs = require('bare-fs')
const { PearcordPlatform } = require('pearcord-platform')
const { COLLECTIONS } = require('pearcord-shared')
const { dispatchUiMessage } = require('pearcord-ui-flow')
const { createLogger, bootstrap } = require('pearcord-log')
const { matchView, matchSidecarEvent } = require('./assert')
@@ -131,6 +132,23 @@ class HeadlessSession {
const view = await this.ipc({ type: 'mark-channel-read', channelId: chId })
results.push({ markActiveChannelRead: true, channelId: chId, view })
}
if (step.seedMentionAlertForActiveChannel) {
const user = this.platform.identity?.user
const chId = this._lastView?.activeChannelId
const guildId = this._lastView?.guild?.id
if (!user?.id || !chId || !guildId) {
throw new Error('cannot seed mention alert')
}
await this.platform.db.insert(COLLECTIONS.MENTION_ALERTS, {
userId: user.id,
guildId,
channelId: chId,
count: 1,
updatedAt: Date.now()
})
await this.refreshView()
results.push({ seedMentionAlertForActiveChannel: true, channelId: chId })
}
if (step.createThreadFromLastMessage) {
const msgs = this._lastView?.messages || []
const last = msgs[msgs.length - 1]