feat(agentctl): channel search cache scenario and channel selectors
Add selectChannelOtherThanActive, searchResultsCached assert, and document headless steps for channel-switch search cache validation. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -154,10 +154,11 @@ Bundled scenarios under `apps/pearcord/scenarios/`:
|
|||||||
| `agentctl-mark-read-mention-alerts.json` | Seed mention alert + `markActiveChannelRead` clears `mentionAlerts` (v0.8.264) |
|
| `agentctl-mark-read-mention-alerts.json` | Seed mention alert + `markActiveChannelRead` clears `mentionAlerts` (v0.8.264) |
|
||||||
| `agentctl-forum-channel-cache.json` | Forum search then switch forum → empty hits (v0.8.265) |
|
| `agentctl-forum-channel-cache.json` | Forum search then switch forum → empty hits (v0.8.265) |
|
||||||
| `agentctl-thread-parent-perms.json` | Thread exposes `parentChannelPermissions` in view (v0.8.265) |
|
| `agentctl-thread-parent-perms.json` | Thread exposes `parentChannelPermissions` in view (v0.8.265) |
|
||||||
|
| `agentctl-channel-search-cache.json` | Channel search empty after switching text channels (v0.8.266) |
|
||||||
|
|
||||||
`mesh.connectGuildMeshThread(scenarioPath)` — host steps + invite + `create-thread` + reply; guest must receive `threadReply` token.
|
`mesh.connectGuildMeshThread(scenarioPath)` — host steps + invite + `create-thread` + reply; guest must receive `threadReply` token.
|
||||||
|
|
||||||
Scenario step extras (headless + attached `run`): `joinFirstVoice`, `openDmPeer`, `selectFirstForumChannel`, `selectSecondForumChannel`, `markActiveChannelRead`, `seedMentionAlertForActiveChannel`, `createThreadFromLastMessage`, `markThreadAndParentRead`, `messagesMin`, `messageContentIncludes`, `searchResultsMin`, `searchResultsMax`, `mentionAlertCountMax`, `parentChannelPermissions` on `wait`.
|
Scenario step extras (headless + attached `run`): `joinFirstVoice`, `openDmPeer`, `selectFirstForumChannel`, `selectSecondForumChannel`, `selectFirstTextChannel`, `selectSecondTextChannel`, `selectChannelNamed`, `selectChannelOtherThanActive`, `markActiveChannelRead`, `seedMentionAlertForActiveChannel`, `createThreadFromLastMessage`, `markThreadAndParentRead`, `messagesMin`, `messageContentIncludes`, `searchResultsMin`, `searchResultsMax`, `searchResultsCached`, `mentionAlertCountMax`, `activeChannelName`, `parentChannelPermissions` on `wait`.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ function matchView (view, spec) {
|
|||||||
if ((view?.searchResults || []).length > Number(expected)) return false
|
if ((view?.searchResults || []).length > Number(expected)) return false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (key === 'activeChannelName') {
|
||||||
|
const ch = (view?.channels || []).find((c) => c.id === view?.activeChannelId)
|
||||||
|
if (!ch || String(ch.name || '').toLowerCase() !== String(expected).toLowerCase()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (key === 'searchResultsCached') {
|
||||||
|
if (!!view?.searchResultsCached !== !!expected) return false
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (key === 'mentionAlertCountMax') {
|
if (key === 'mentionAlertCountMax') {
|
||||||
const alerts = view?.mentionAlerts || {}
|
const alerts = view?.mentionAlerts || {}
|
||||||
const max = Object.values(alerts).reduce(
|
const max = Object.values(alerts).reduce(
|
||||||
|
|||||||
+38
@@ -133,6 +133,44 @@ class HeadlessSession {
|
|||||||
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
||||||
results.push({ selectSecondForumChannel: true, channelId: ch.id, view })
|
results.push({ selectSecondForumChannel: true, channelId: ch.id, view })
|
||||||
}
|
}
|
||||||
|
if (step.selectFirstTextChannel) {
|
||||||
|
const text = (this._lastView?.channels || []).filter(
|
||||||
|
(c) => c.type === 'text' || c.type === 'announcement'
|
||||||
|
)
|
||||||
|
if (!text.length) throw new Error('no text channel in view')
|
||||||
|
const ch = text[0]
|
||||||
|
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
||||||
|
results.push({ selectFirstTextChannel: true, channelId: ch.id, view })
|
||||||
|
}
|
||||||
|
if (step.selectChannelNamed) {
|
||||||
|
const name = String(step.selectChannelNamed || '').trim()
|
||||||
|
const ch = (this._lastView?.channels || []).find(
|
||||||
|
(c) => String(c.name || '').toLowerCase() === name.toLowerCase()
|
||||||
|
)
|
||||||
|
if (!ch) throw new Error(`no channel named ${name}`)
|
||||||
|
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
||||||
|
results.push({ selectChannelNamed: name, channelId: ch.id, view })
|
||||||
|
}
|
||||||
|
if (step.selectChannelOtherThanActive) {
|
||||||
|
const active = this._lastView?.activeChannelId
|
||||||
|
const text = (this._lastView?.channels || []).filter(
|
||||||
|
(c) =>
|
||||||
|
(c.type === 'text' || c.type === 'announcement') && c.id && c.id !== active
|
||||||
|
)
|
||||||
|
if (!text.length) throw new Error('no other text channel to select')
|
||||||
|
const ch = text[0]
|
||||||
|
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
||||||
|
results.push({ selectChannelOtherThanActive: true, channelId: ch.id, view })
|
||||||
|
}
|
||||||
|
if (step.selectSecondTextChannel) {
|
||||||
|
const text = (this._lastView?.channels || []).filter(
|
||||||
|
(c) => c.type === 'text' || c.type === 'announcement'
|
||||||
|
)
|
||||||
|
if (text.length < 2) throw new Error('need at least two text channels')
|
||||||
|
const ch = text[1]
|
||||||
|
const view = await this.ipc({ type: 'select-channel', channelId: ch.id })
|
||||||
|
results.push({ selectSecondTextChannel: true, channelId: ch.id, view })
|
||||||
|
}
|
||||||
if (step.markActiveChannelRead) {
|
if (step.markActiveChannelRead) {
|
||||||
const chId = this._lastView?.activeChannelId
|
const chId = this._lastView?.activeChannelId
|
||||||
if (!chId) throw new Error('no active channel for mark-channel-read')
|
if (!chId) throw new Error('no active channel for mark-channel-read')
|
||||||
|
|||||||
Reference in New Issue
Block a user