Raven ScottandCursor 3fb37af5ad Add waitLogContains matcher for agentctl scenario runs.
Introduce bounded log polling in attached and headless scenario runners so startup hardening can be asserted directly from structured pearcord.log lines.

Co-authored-by: Cursor <[email protected]>
2026-06-02 11:01:07 -04:00

pearcord-agentctl

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 659 (v0.8.638): Added runDmPollVoteJourney to verify DM single-choice idempotent vote apply, multi-select, anonymous poll creation, pre-vote edit guard behavior, close-state vote blocking, DM poll deletion, thread-scoped poll voting in dm_thread, and no synthetic unread/mention bump from poll updates; smoke test:agentctl-dm-poll-phase659.

Phase 659 (v0.8.638): Added runDmScheduledMessageJourney to verify queue/create/list/send-now/cancel behavior for DM scheduled messages; smoke test:agentctl-dm-scheduled-phase659.

Phase 658 (v0.8.638): Added DM thread closure journeys: runDmThreadArchiveJourney (archive/unarchive state) and runDmThreadP2PAuditJourney (topic audit). Smokes: test:agentctl-dm-thread-archive-phase658, test:agentctl-dm-thread-p2p-audit-phase658.

Phase 656 (v0.8.631): runDmVoiceLiveJourney, runGroupDmAddMemberJourney; smokes test:agentctl-dm-voice-live-phase656, test:agentctl-group-add-member-phase656.

Phase 656 (v0.8.630): Headless runGlobalPresenceTwoPeerJourney, runHyperDbDmMetaMigrationJourney; smokes test:agentctl-global-presence-phase656, test:agentctl-dm-meta-phase656, test:quick-switcher-phase656.

Phase 655 (v0.8.629): Headless runDmPinsAndReactionJourney, runDmOpenWithGuildsJourney, openHome; smokes for pins, guild-heal, companion DM sidebar.

Phase 655 (v0.8.628): Headless runDmFriendOpenComposerFocusJourney, runGroupDmRenameJourney; smokes test:agentctl-dm-friend-focus-phase655, test:agentctl-group-rename-phase655. Prior: runDmSidebarSearchJourney (v0.8.627).

Phase 654 (50 swarm/repl/sync items): Primary autonomous testing vehicle per core rules.

Mission

Enable autonomous agents (and developers) to drive Pearcord like a real user without clicking the Electron UI: register, create guilds, select channels, send messages, and assert on platform state.

Modes

Mode When How
Attached Desktop pear run with PEARCORD_AGENTCTL=1 TCP JSON-lines on 127.0.0.1:39482 (configurable)
Headless CI, smokes, agent scripts HeadlessSession + pearcord-platform + pearcord-ui-flow in-process

Both modes use pearcord-ui-flow dispatchUiMessage — the same handler as apps/pearcord/index.js.

v0.8.610 (Phase 638): Headless runGuildSyncDiagnosticsJourney(guildId) — refresh health counts, getGuildSyncHealth, exportGuildSyncDiagnostics (discovery join debugging). Smoke: npm run test:agentctl-guild-sync-diagnostics.

v0.8.611 (Phase 639): Headless runSettingsMeshHealthJourney(guildId)syncSettingsMesh, getGuildSyncHealth, view.settingsMeshStats. Smoke: npm run test:agentctl-settings-mesh-health. Bundle: npm run test:phase639-settings-mesh.

v0.8.612 (Phase 640): Headless runAuditSidecarExportJourney(guildId)exportAuditSidecar, view.auditSidecar. Smoke: npm run test:agentctl-audit-sidecar. Bundle: npm run test:phase640-audit-sidecar.

v0.8.613 (Phase 641): Headless runOfflineRecoverySyncJourney, runMeshStabilityJourney; mesh connectGuildMeshTripleGroup (3-peer). Smokes: npm run test:agentctl-offline-recovery, npm run test:agentctl-mesh-3peer. Bundle: npm run test:phase641-mesh-stability.

v0.8.615 (Phase 643): Mesh churn spans (guild.mesh.churn); IPC get-mesh-stability-stats / export-mesh-stability-stats; offline recovery refreshes discovery mesh. Bundle: npm run test:phase643-mesh-churn (chains Phase 642). See MESH_CHURN.md.

v0.8.616 (Phase 644): runReplicationCompactJourney (create thread → archive → sparse compact); UI archive-thread IPC wired in thread bar. Bundle: npm run test:phase644-replication-crdt.

v0.8.617 (Phase 645): runLargeGuildMemberJourney (seed 120+ members → partial bundle → member page request); IPC request-member-page. Bundle: npm run test:phase645-large-guild-mesh. See LARGE_GUILD_MESH.md.

v0.8.623 (Phase 651): Partition heal asserts discoveryScoped; runFederationHubIngestJourney. Bundle: npm run test:phase651-swarm-replication.

v0.8.622 (Phase 650): runFederationStabilitySoakJourney (PEARCORD_FEDERATION_SOAK_MS), runFederationHubIngestJourney; async exportFederationSyncDiagnostics. Bundle: npm run test:phase650-live-federation-mesh.

v0.8.621 (Phase 649): runFederationMeshSoakJourney (multi-guild + listing refresh + federation export); exportFederationSyncDiagnostics. Bundle: npm run test:phase649-federation-discovery. See FEDERATION_MESH.md.

v0.8.620 (Phase 648): runMultiGuildMeshSoakJourney (two guilds, switch, multi export); exportMultiGuildSyncDiagnostics. Bundle: npm run test:phase648-multi-guild-mesh. See MULTI_GUILD_MESH.md.

v0.8.619 (Phase 647): runProductionMeshSoakJourney (stability + heal + message + diagnostics); exportPartitionHealDiagnostics. Bundle: npm run test:phase647-production-mesh. See PRODUCTION_MESH.md.

v0.8.624 (Phase 652): runPartitionHeal3PeerLiveJourney, runMeshChurnScaleSoakJourney (PEARCORD_MESH_CHURN_SOAK_MS). Bundle: npm run test:phase652-live-mesh-churn. See MESH_CHURN_SCALE.md.

v0.8.618 (Phase 646): runPartitionHealJourney (split-brain presence → heal → diagnostics); IPC run-partition-heal-sync. Bundle: npm run test:phase646-partition-heal. See PARTITION_HEAL.md.

AgentClient resolves RPC replies before treating { event: "state" | "sidecar" } push lines as events (fixes wait-event responses that include an event field).

v0.8.574 (Phase 611): Headless createThreadFromLastMessage refreshView re-verified for threads hub bundle. Bundle: npm run test:agentctl-phase611-threads (chains test:agentctl-phase484-threads).

v0.8.573 (Phase 610): Headless toggleGuildReaction + staged sticker send refreshView re-verified for expression hub bundle. Bundle: npm run test:agentctl-phase610-expression (chains test:agentctl-phase581-expression).

v0.8.572 (Phase 609): Headless upsertGuildSticker/removeGuildSticker refreshView re-verified for stickers hub bundle. Bundle: npm run test:agentctl-phase609-stickers (chains test:agentctl-phase580-stickers).

v0.8.571 (Phase 608): Headless upsertGuildEmoji/removeGuildEmoji refreshView re-verified for emoji hub bundle. Bundle: npm run test:agentctl-phase608-emoji (chains test:agentctl-phase579-emoji).

v0.8.570 (Phase 607): Headless upsertGuildAutomationHook/deleteGuildAutomationHook/dryRunGuildAutomationHook/exportGuildAutomationManifest refreshView re-verified for automation hub bundle. Bundle: npm run test:agentctl-phase607-automation (chains test:agentctl-phase578-automation).

v0.8.569 (Phase 606): Headless installGuildBotFromToken/verifyGuildBotToken/sendGuildBotMessage refreshView re-verified for bots hub bundle. Bundle: npm run test:agentctl-phase606-bots (chains test:agentctl-phase577-bots).

v0.8.568 (Phase 605): Headless registerGuildSlashCommands/deleteGuildSlashCommand/executeGuildSlashCommand refreshView re-verified for slash hub bundle. Bundle: npm run test:agentctl-phase605-slash (chains test:agentctl-phase576-slash).

v0.8.567 (Phase 604): Headless createGuildChannelWebhook/deleteGuildChannelWebhook/executeGuildChannelWebhook refreshView re-verified for webhooks hub bundle. Bundle: npm run test:agentctl-phase604-webhooks (chains test:agentctl-phase575-webhooks).

v0.8.566 (Phase 603): Headless exportGuildAuditLog/fetchGuildAuditExportArchive/setGuildDigestExportSchedule refreshView re-verified for compliance hub bundle. Bundle: npm run test:agentctl-phase603-compliance (chains test:agentctl-phase574-compliance).

v0.8.565 (Phase 602): Headless exportGuildAuditLog/setAuditLogExportFilter/setAuditExportSchedule refreshView re-verified for audit hub bundle. Bundle: npm run test:agentctl-phase602-audit (chains test:agentctl-phase573-audit).

v0.8.564 (Phase 601): Headless banGuildMember/kickGuildMember/timeoutGuildMember/setAutomodConfig refreshView re-verified for moderation hub bundle. Bundle: npm run test:agentctl-phase601-moderation (chains test:agentctl-phase572-moderation).

v0.8.563 (Phase 600): Headless createGuildCustomRole/updateGuildCustomRole/reorderGuildCustomRoles/setMemberCustomRoles refreshView re-verified for roles hub bundle. Bundle: npm run test:agentctl-phase600-roles (chains test:agentctl-phase571-roles).

v0.8.562 (Phase 599): Headless createGuildCustomRole/updateGuildCustomRole/deleteGuildCustomRole/upsertChannelPermissionOverwrite refreshView re-verified for permissions hub bundle. Bundle: npm run test:agentctl-phase599-permissions (chains test:agentctl-phase570-permissions).

v0.8.561 (Phase 598): Headless updateUserPrefs, updateNotificationPrefs, and updateGuildSettings refreshView re-verified for settings hub bundle. Bundle: npm run test:agentctl-phase598-settings (chains test:agentctl-phase568-settings).

v0.8.560 (Phase 597): Headless start and loadGuild refreshView re-verified for session hub bundle. Bundle: npm run test:agentctl-phase597-session (chains test:agentctl-phase569-session).

v0.8.559 (Phase 596): Headless registerUser, createGuild, and joinGuildInvite refreshView re-verified for onboarding hub bundle. Bundle: npm run test:agentctl-phase596-onboarding (chains test:agentctl-phase567-onboarding).

v0.8.558 (Phase 595): Headless openDmWithPeer, createGroupDm, and sendDmMessage refreshView re-verified for DMs hub bundle. Bundle: npm run test:agentctl-phase595-dms (chains test:agentctl-phase565-dms).

v0.8.557 (Phase 594): Headless sendFriendRequest, acceptFriendRequest, and blockContact refreshView re-verified for contacts hub bundle. Bundle: npm run test:agentctl-phase594-contacts (chains test:agentctl-phase564-contacts).

v0.8.556 (Phase 593): Headless listPublicDiscovery, joinPublicDiscovery, and setDiscoveryFilter refreshView re-verified for discovery hub bundle. Bundle: npm run test:agentctl-phase593-discovery (chains test:agentctl-phase563-discovery).

v0.8.555 (Phase 592): Headless setPresenceStatus, setCustomStatus, and setGuildActivity refreshView re-verified for presence hub bundle. Bundle: npm run test:agentctl-phase592-presence (chains test:agentctl-phase562-presence).

v0.8.554 (Phase 591): Headless playGuildSoundboardSound and upsertGuildSound refreshView re-verified for soundboard hub bundle. Bundle: npm run test:agentctl-phase591-soundboard (chains test:agentctl-phase561-soundboard).

v0.8.524 (Phase 561): Headless playGuildSoundboardSound and removeGuildSound refreshView re-verified. Bundle: npm run test:agentctl-phase561-soundboard (chains test:agentctl-phase543-soundboard).

v0.8.525 (Phase 562): Headless setPresenceStatus and setCustomStatus refreshView re-verified. Bundle: npm run test:agentctl-phase562-presence (chains test:agentctl-phase544-presence).

v0.8.526 (Phase 563): Headless joinPublicDiscovery and refreshPublicDiscovery refreshView re-verified. Bundle: npm run test:agentctl-phase563-discovery (chains test:agentctl-phase545-discovery).

v0.8.527 (Phase 564): Headless sendFriendRequest and acceptFriendRequest refreshView re-verified. Bundle: npm run test:agentctl-phase564-contacts (chains test:agentctl-phase546-contacts).

v0.8.544 (Phase 581): Headless toggleGuildReaction + sendMessageWithStagedStickers refreshView re-verify. Bundle: npm run test:agentctl-phase581-expression (chains test:agentctl-phase580-stickers).

v0.8.543 (Phase 580): Headless upsertGuildSticker/removeGuildSticker refreshView re-verify. Bundle: npm run test:agentctl-phase580-stickers (chains test:agentctl-phase579-emoji).

v0.8.542 (Phase 579): Headless upsertGuildEmoji/removeGuildEmoji refreshView re-verify. Bundle: npm run test:agentctl-phase579-emoji (chains test:agentctl-phase578-automation).

v0.8.541 (Phase 578): Headless dryRunGuildAutomationHook/exportGuildAutomationManifest refreshView re-verify. Bundle: npm run test:agentctl-phase578-automation (chains test:agentctl-phase577-bots).

v0.8.540 (Phase 577): Headless installGuildBotFromToken/sendGuildBotMessage/verifyGuildBotToken refreshView re-verify. Bundle: npm run test:agentctl-phase577-bots (chains test:agentctl-phase576-slash).

v0.8.539 (Phase 576): Headless registerGuildSlashCommands/deleteGuildSlashCommand/executeGuildSlashCommand refreshView re-verify. Bundle: npm run test:agentctl-phase576-slash (chains test:agentctl-phase575-webhooks).

v0.8.538 (Phase 575): Headless createGuildChannelWebhook/deleteGuildChannelWebhook/executeGuildChannelWebhook refreshView re-verify. Bundle: npm run test:agentctl-phase575-webhooks (chains test:agentctl-phase574-compliance).

v0.8.537 (Phase 574): Headless fetchGuildAuditExportArchive/setGuildDigestExportSchedule + refreshView. Bundle: npm run test:agentctl-phase574-compliance (chains test:agentctl-phase573-audit).

v0.8.536 (Phase 573): Headless exportGuildAuditLog/setAuditLogExportFilter + refreshView. Bundle: npm run test:agentctl-phase573-audit (chains test:agentctl-phase552-compliance).

v0.8.535 (Phase 572): Headless banGuildMember/kickGuildMember/timeoutGuildMember refreshView re-verified. Bundle: npm run test:agentctl-phase572-moderation (chains test:agentctl-phase551-moderation).

v0.8.534 (Phase 571): Headless updateGuildCustomRole/reorderGuildCustomRoles/setMemberCustomRoles + refreshView. Bundle: npm run test:agentctl-phase571-roles (chains test:agentctl-phase570-permissions).

v0.8.533 (Phase 570): Headless createGuildCustomRole/deleteGuildCustomRole/upsertChannelPermissionOverwrite refreshView re-verified. Bundle: npm run test:agentctl-phase570-permissions (chains test:agentctl-phase534-roles).

v0.8.532 (Phase 569): Headless loadGuild refreshView re-verified. Bundle: npm run test:agentctl-phase569-session (chains test:agentctl-phase456-onboarding).

v0.8.531 (Phase 568): Headless updateUserPrefs/updateNotificationPrefs/updateGuildSettings refreshView re-verified. Bundle: npm run test:agentctl-phase568-settings (chains test:agentctl-phase512-settings).

v0.8.530 (Phase 567): Headless registerUser/createGuild/joinGuildInvite refreshView re-verified. Bundle: npm run test:agentctl-phase567-onboarding (chains test:agentctl-phase511-onboarding).

v0.8.529 (Phase 566): Headless createGuildInvite/joinGuildInvite/revokeGuildInvite refreshView re-verified. Bundle: npm run test:agentctl-phase566-invites (chains test:agentctl-phase548-invites).

v0.8.528 (Phase 565): Headless openDmWithPeer and sendDmMessage refreshView re-verified. Bundle: npm run test:agentctl-phase565-dms (chains test:agentctl-phase547-dms).

v0.8.523 (Phase 560): Headless startGuildScreenShare and stopGuildScreenShare call refreshView after mutations. Bundle: npm run test:agentctl-phase560-screen (chains test:agentctl-phase526-screen).

v0.8.522 (Phase 559): Headless joinGuildStageChannel, requestGuildStageSpeak, and approveGuildStageSpeaker call refreshView after mutations. Bundle: npm run test:agentctl-phase559-stage (chains test:agentctl-phase525-stage).

v0.8.521 (Phase 558): Headless joinGuildVoiceChannel, leaveGuildVoiceChannel, and setGuildVoiceMute call refreshView after mutations. Bundle: npm run test:agentctl-phase558-voice (chains test:agentctl-phase524-voice).

v0.8.590 (Phase 627): Headless searchGuildMessages refreshView re-verified for search hub depth bundle. Bundle: npm run test:agentctl-phase627-search (chains test:agentctl-phase613-search + smoke-agentctl-search-phase627).

v0.8.589 (Phase 626): Headless toggleGuildReaction refreshView re-verified for reaction hub depth bundle. Bundle: npm run test:agentctl-phase626-reactions (chains test:agentctl-phase612-reactions + smoke-agentctl-reaction-phase626).

v0.8.588 (Phase 625): Headless createThreadFromLastMessage refreshView re-verified for threads hub depth bundle. Bundle: npm run test:agentctl-phase625-threads (chains test:agentctl-phase611-threads + smoke-agentctl-threads-phase625).

v0.8.587 (Phase 624): Headless toggleGuildReaction/sendMessageWithStagedStickers refreshView re-verified for expression hub depth bundle. Bundle: npm run test:agentctl-phase624-expression (chains test:agentctl-phase610-expression).

v0.8.586 (Phase 623): Headless upsertGuildSticker/removeGuildSticker/sendMessageWithStagedStickers refreshView re-verified for stickers hub depth bundle. Bundle: npm run test:agentctl-phase623-stickers (chains test:agentctl-phase609-stickers).

v0.8.584 (Phase 621): Headless upsertGuildAutomationHook/deleteGuildAutomationHook/dryRunGuildAutomationHook/exportGuildAutomationManifest refreshView re-verified for automation hub depth bundle. Bundle: npm run test:agentctl-phase621-automation (chains test:agentctl-phase607-automation).

v0.8.583 (Phase 620): Headless installGuildBotFromToken/verifyGuildBotToken/sendGuildBotMessage refreshView re-verified for bots hub depth bundle. Bundle: npm run test:agentctl-phase620-bots (chains test:agentctl-phase606-bots).

v0.8.582 (Phase 619): Headless registerGuildSlashCommands/deleteGuildSlashCommand/executeGuildSlashCommand refreshView re-verified for slash hub depth bundle. Bundle: npm run test:agentctl-phase619-slash (chains test:agentctl-phase605-slash).

v0.8.581 (Phase 618): Headless createGuildChannelWebhook/deleteGuildChannelWebhook/executeGuildChannelWebhook refreshView re-verified for webhooks hub depth bundle. Bundle: npm run test:agentctl-phase618-webhooks (chains test:agentctl-phase604-webhooks).

v0.8.580 (Phase 617): Headless exportGuildAuditLog/fetchGuildAuditExportArchive/setGuildDigestExportSchedule refreshView re-verified for compliance hub depth bundle. Bundle: npm run test:agentctl-phase617-compliance (chains test:agentctl-phase603-compliance).

v0.8.579 (Phase 616): Headless exportGuildAuditLog/setAuditLogExportFilter/setAuditExportSchedule refreshView re-verified for audit hub depth bundle. Bundle: npm run test:agentctl-phase616-audit (chains test:agentctl-phase602-audit).

v0.8.578 (Phase 615): Headless banGuildMember/kickGuildMember/timeoutGuildMember/setAutomodConfig refreshView re-verified for moderation hub depth bundle. Bundle: npm run test:agentctl-phase615-moderation (chains test:agentctl-phase601-moderation).

v0.8.577 (Phase 614): Headless pinGuildMessage / unpinGuildMessage refreshView re-verified for pins hub depth bundle. Bundle: npm run test:agentctl-phase614-pins (chains test:agentctl-phase587-pins).

v0.8.576 (Phase 613): Headless searchGuildMessages refreshView re-verified for search hub depth bundle. Bundle: npm run test:agentctl-phase613-search (chains test:agentctl-phase586-search).

v0.8.575 (Phase 612): Headless toggleGuildReaction refreshView re-verified for reaction hub depth bundle. Bundle: npm run test:agentctl-phase612-reactions (chains test:agentctl-phase585-reactions).

v0.8.549 (Phase 586): Headless searchGuildMessages refreshView re-verified for search hub bundle. Bundle: npm run test:agentctl-phase586-search (chains test:agentctl-phase553-search).

v0.8.553 (Phase 590): Headless start/stop screen share refreshView re-verified for screen hub bundle. Bundle: npm run test:agentctl-phase590-screen (chains test:agentctl-phase526-screen).

v0.8.552 (Phase 589): Headless join/approve stage refreshView re-verified for stage hub bundle. Bundle: npm run test:agentctl-phase589-stage (chains test:agentctl-phase525-stage).

v0.8.551 (Phase 588): Headless join/leave/mute refreshView re-verified for voice hub bundle. Bundle: npm run test:agentctl-phase588-voice (chains test:agentctl-phase524-voice).

v0.8.550 (Phase 587): Headless pinGuildMessage / unpinGuildMessage call refreshView after mutations. Bundle: npm run test:agentctl-phase587-pins (chains test:agentctl-pin-jump).

v0.8.548 (Phase 585): Headless toggleGuildReaction refreshView re-verified for reaction hub bundle. Bundle: npm run test:agentctl-phase585-reactions (chains test:agentctl-phase555-reactions).

v0.8.547 (Phase 584): Headless sendGuildMessage/editGuildMessage/deleteGuildMessage refreshView re-verified for messaging hub bundle. Bundle: npm run test:agentctl-phase584-messaging (chains test:agentctl-phase554-messaging).

v0.8.546 (Phase 583): Headless stageGuildAttachment and sendGuildMessageWithAttachments refreshView re-verified for attachment hub bundle. Bundle: npm run test:agentctl-phase583-attachments (chains test:agentctl-phase556-attachments).

v0.8.545 (Phase 582): Headless sendGuildEmbedMessage and resolveGuildEmbed refreshView re-verified for embed hub bundle. Bundle: npm run test:agentctl-phase582-embeds (chains test:agentctl-phase557-embeds).

v0.8.519 (Phase 556): Headless stageGuildAttachment and sendGuildMessageWithAttachments call refreshView after mutations. Bundle: npm run test:agentctl-phase556-attachments (chains test:agentctl-phase522-attachments).

v0.8.518 (Phase 555): Headless toggleGuildReaction calls refreshView after toggle. Bundle: npm run test:agentctl-phase555-reactions (chains test:agentctl-phase521-reactions).

v0.8.517 (Phase 554): Headless sendGuildMessage/editGuildMessage/deleteGuildMessage call refreshView after mutations. Bundle: npm run test:agentctl-phase554-messaging (chains test:agentctl-phase520-messaging).

v0.8.516 (Phase 553): Headless searchGuildMessages calls refreshView after search. Bundle: npm run test:agentctl-phase553-search (chains test:agentctl-phase519-search).

v0.8.515 (Phase 552): Headless exportGuildAuditLog refreshView re-verified for compliance automation. Bundle: npm run test:agentctl-phase552-compliance (chains test:agentctl-phase536-compliance).

v0.8.513 (Phase 550): Headless deleteGuildCustomRole and upsertChannelPermissionOverwrite refreshView re-verified. Bundle: npm run test:agentctl-phase550-roles (chains test:agentctl-phase534-roles).

v0.8.512 (Phase 549): Headless createGuildChannel selects new channel + refreshView; reorderGuildChannels refreshView re-verified. Bundle: npm run test:agentctl-phase549-guild-admin (chains test:agentctl-phase533-guild-admin).

v0.8.511 (Phase 548): Headless revokeGuildInvite calls refreshView after revoke. Bundle: npm run test:agentctl-phase548-invites (chains test:agentctl-phase532-invites).

v0.8.510 (Phase 547): Headless sendDmMessage calls refreshView after send. Bundle: npm run test:agentctl-phase547-dms (chains test:agentctl-phase531-dms).

v0.8.509 (Phase 546): Headless contacts ops call refreshView after send/accept/decline. Bundle: npm run test:agentctl-phase546-contacts (chains test:agentctl-phase530-contacts).

v0.8.508 (Phase 545): Headless discovery ops call refreshView after list/publish/refresh/filter. Bundle: npm run test:agentctl-phase545-discovery (chains test:agentctl-phase529-discovery).

v0.8.507 (Phase 544): Headless presence ops call refreshView after status/activity changes. Bundle: npm run test:agentctl-phase544-presence (chains test:agentctl-phase528-presence).

v0.8.506 (Phase 543): Headless soundboard ops call refreshView after play/upload/delete. Bundle: npm run test:agentctl-phase543-soundboard (chains test:agentctl-phase527-soundboard).

v0.8.505 (Phase 542): Headless upsertGuildSticker/removeGuildSticker for sticker testing. Bundle: npm run test:agentctl-phase542-stickers (chains test:agentctl-phase431-emoji).

v0.8.504 (Phase 541): Headless upsertGuildEmoji/removeGuildEmoji for emoji testing. Bundle: npm run test:agentctl-phase541-emoji (chains test:agentctl-phase431-emoji).

v0.8.503 (Phase 540): Headless upsertGuildAutomationHook/deleteGuildAutomationHook/dryRunGuildAutomationHook/exportGuildAutomationManifest for automation testing. Bundle: npm run test:agentctl-phase540-automation (chains test:agentctl-phase491-automation).

v0.8.502 (Phase 539): Headless createGuildBotInstallToken/installGuildBotFromToken/sendGuildBotMessage/verifyGuildBotToken for bot automation. Bundle: npm run test:agentctl-phase539-bots (chains test:agentctl-phase490-bots).

v0.8.501 (Phase 538): Headless registerGuildSlashCommands/deleteGuildSlashCommand/executeGuildSlashCommand for slash automation. Bundle: npm run test:agentctl-phase538-slash (chains test:agentctl-phase489-slash).

v0.8.500 (Phase 537): Headless createGuildChannelWebhook/deleteGuildChannelWebhook/executeGuildChannelWebhook for webhook automation. Bundle: npm run test:agentctl-phase537-webhooks (chains test:agentctl-phase488-webhooks).

v0.8.499 (Phase 536): Headless exportGuildAuditLog(opts) wraps platform.exportAuditLog for compliance automation. Bundle: npm run test:agentctl-phase536-compliance (chains test:agentctl-phase487-compliance).

v0.8.486 (Phase 523): Headless sendGuildEmbedMessage(content) and resolveGuildEmbed(content) for link-preview automation. Bundle: npm run test:agentctl-phase523-embeds (app repo; chains test:embed + test:agentctl-embed-message).

v0.8.485 (Phase 522): Headless stageGuildAttachment(opts) and sendGuildMessageWithAttachments(content, attachmentIds, opts) for attachment automation. Bundle: npm run test:agentctl-phase522-attachments (app repo; chains test:attachments + test:agentctl-phase481-attachments).

v0.8.484 (Phase 521): Headless toggleGuildReaction(messageId, emoji) for reaction automation. Bundle: npm run test:agentctl-phase521-reactions (app repo; chains test:reactions + test:agentctl-reaction-toggle).

v0.8.483 (Phase 520): Headless sendGuildMessage(content, opts), editGuildMessage(messageId, content), and deleteGuildMessage(messageId) for messaging automation. Bundle: npm run test:agentctl-phase520-messaging (app repo; chains test:agentctl-phase482-messaging).

v0.8.482 (Phase 519): Headless searchGuildMessages(query, opts) and setSearchScope(scope) for guild search automation. Bundle: npm run test:agentctl-phase519-search (app repo; chains test:parse-search-query + test:search-ranking).

v0.8.391 (Phase 428): Assert keys auditLogMin, auditLogExportFilter, auditLogIncludesAction; sidecar auditExportCountMin, bodyIncludes. Bundle: npm run test:agentctl-phase428-audit.

v0.8.390 (Phase 427): expectIpcError step, wait.banForUserId (DB ban row), waitEvent with automodBlocked, assert keys automodEnabled, automodBlockedKeywordsMin, memberTimeoutFor. Bundle: npm run test:agentctl-phase427-moderation.

Quick start

1. Start Pearcord with the control server

cd apps/pearcord
PEARCORD_AGENTCTL=1 pear run

If startup fails with missing pearcord-* modules, reinstall local module links:

cd ../../modules/pearcord-platform && npm install
cd ../pearcord-agentctl && npm install

Worker logs: agentctl listening {"host":"127.0.0.1","port":39482}.

2. Ping from another terminal

cd apps/pearcord
node ../../modules/pearcord-agentctl/bin/agentctl.cjs preflight
node ../../modules/pearcord-agentctl/bin/agentctl.cjs doctor
npm run agentctl:ping
# or
bare ../../modules/pearcord-agentctl/bin/agentctl.cjs ping
bare ../../modules/pearcord-agentctl/bin/agentctl.cjs wait-ready --timeout 20000

ping output includes host, port, tokenMode, and handshake metadata (appVersion, platformVersion, moduleGraphHash, pearcordModuleCount) for runtime graph verification. doctor includes listeningEvidence from pearcord.log, surfacing the most recent worker-side agentctl listening line and host/port match status.

One-shot live harness:

cd apps/pearcord && \
PEARCORD_AGENTCTL=1 pear run & \
sleep 3 && \
bare ../../modules/pearcord-agentctl/bin/agentctl.cjs wait-ready --timeout 30000 && \
bare ../../modules/pearcord-agentctl/bin/agentctl.cjs ping --wait-listening && \
bare ../../modules/pearcord-agentctl/bin/agentctl.cjs view --light

3. Drive IPC

npm run agentctl:ipc -- '{"type":"register","username":"agent1","displayName":"Agent One"}'
npm run agentctl:wait -- '{"onboarded":true}' --timeout 30000
npm run agentctl:ipc -- '{"type":"create-guild","name":"Agent Guild"}'
npm run agentctl:wait -- '{"mode":"guild"}'
npm run agentctl:view

4. Headless scenario (no GUI)

npm run agentctl:headless -- scenarios/agentctl-onboard.json

Protocol (TCP)

One JSON object per line (newline-delimited).

Requests

op Fields Description
ping Health check
ipc payload UI IPC object (type, …)
view light? Current platform view
wait match, timeoutMs?, light? Block until view matches partial spec
wait-event match, timeoutMs?, since? Block until sidecar error / log event
run scenario Run scenario JSON on attached worker
log-tail lines? Last N lines of pearcord.log
shutdown Close agentctl server

Responses

{ "id": 1, "ok": true, "pong": true, "version": "0.8.638", "handshake": { "moduleGraphHash": "..." } }
{ "id": 2, "ok": false, "error": "wait timeout", "view": { ... } }

Events (server → client, no id)

{ "event": "state", "view": { ... } }
{ "event": "sidecar", "payload": { "type": "error", "message": "..." }, "at": 1734567890123 }
{ "event": "sidecar", "payload": { "type": "agentctl-heartbeat", "mode": "guild", "sessionReady": true, "at": 1734567890123 }, "at": 1734567890123 }
{ "event": "sidecar", "payload": { "type": "agentctl-startup", "phase": "agentctl-listening", "bindLatencyMs": 42 }, "at": 1734567890123 }

Set PEARCORD_AGENTCTL_TOKEN to require the same secret on every request when the server is enabled.

Environment

Variable Default Role
PEARCORD_AGENTCTL off 1 enables TCP server in worker
PEARCORD_AGENTCTL_HOST 127.0.0.1 Bind/connect host
PEARCORD_AGENTCTL_PORT 39482 TCP port
PEARCORD_STORAGE ~/.config/pearcord Log tail path
PEARCORD_LOG_LEVEL info Headless session logging

API

const { AgentServer, AgentClient, HeadlessSession, matchView } = require('pearcord-agentctl')

See docs/AGENTCTL.md for full reference, security notes, and scenario format.

Security

  • Binds localhost only — not exposed to the LAN.
  • Optional PEARCORD_AGENTCTL_TOKEN shared secret; still localhost-only.
  • Can execute any UI IPC type (moderation, guild admin, etc.) — same power as the logged-in user session.

v0.8.498 (Phase 535): Headless helpers banGuildMember(userId, reason), kickGuildMember(userId, reason), and timeoutGuildMember(userId, durationMinutes, reason) for moderation automation. Bundle: npm run test:phase535-moderation (app repo).

v0.8.497 (Phase 534): Headless helpers createGuildCustomRole(name, opts), deleteGuildCustomRole(roleId), and upsertChannelPermissionOverwrite(channelId, payload) for roles automation. Bundle: npm run test:phase534-roles (app repo).

v0.8.496 (Phase 533): Headless helpers createGuildChannel(name, opts), deleteGuildChannel(channelId), and reorderGuildChannels(parentId, channelIds) for guild-admin automation. Bundle: npm run test:phase533-guild-admin (app repo).

v0.8.495 (Phase 532): Headless helpers createGuildInvite(), joinGuildInvite(code), and revokeGuildInvite(code) for invite automation. Bundle: npm run test:phase532-invites (app repo).

v0.8.494 (Phase 531): Headless helpers openDmWithPeer(peerUserId, peerDisplayName), createGroupDm(peerUserIds, name), and sendDmMessage(content, opts) for DM automation. Bundle: npm run test:phase531-dms (app repo).

v0.8.493 (Phase 530): Headless helpers sendFriendRequest(opts), acceptFriendRequest(peerUserId), and declineFriendRequest(peerUserId) for contacts automation. Bundle: npm run test:phase530-contacts (app repo).

v0.8.492 (Phase 529): Headless helpers refreshPublicDiscovery() and setDiscoveryFilter(filter) for explore mesh refresh and filter automation (plus existing listPublicDiscovery, publishDiscoveryListing, joinPublicDiscovery). Bundle: npm run test:phase529-discovery (app repo).

v0.8.491 (Phase 528): Headless helpers setGuildActivity(activity) and clearGuildActivity() for rich-presence automation (plus existing setPresenceStatus, setCustomStatus). Bundle: npm run test:phase528-presence (app repo).

v0.8.490 (Phase 527): Headless helpers playGuildSoundboardSound, upsertGuildSound, removeGuildSound for soundboard roundtrip automation. Bundle: npm run test:phase527-soundboard (app repo).

v0.8.489 (Phase 526): Headless helpers startGuildScreenShare, stopGuildScreenShare for screen share roundtrip automation. Bundle: npm run test:phase526-screen (app repo).

v0.8.488 (Phase 525): Headless helpers joinGuildStageChannel, requestGuildStageSpeak, approveGuildStageSpeaker for stage roundtrip automation. Bundle: npm run test:phase525-stage (app repo).

v0.8.487 (Phase 524): Headless helpers joinGuildVoiceChannel, leaveGuildVoiceChannel, setGuildVoiceMute for voice roundtrip automation. Bundle: npm run test:phase524-voice (app repo).

Smoke tests

cd apps/pearcord
npm run test:agentctl-headless
npm run test:agentctl-slash
npm run test:agentctl-dm-voice
npm run test:agentctl-wait-event
npm run test:agentctl-server-wire
npm run test:agentctl-leave-voice-noop
npm run test:agentctl-settings-deep-link
npm run test:agentctl-settings-navigate
npm run test:agentctl-settings-guild-deep-link
npm run test:agentctl-mesh-channel-mention
npm run test:agentctl-composer-channel-mention

Bundled scenarios under apps/pearcord/scenarios/:

File Purpose
agentctl-onboard.json Register + onboard
agentctl-slash.json Slash command roundtrip
agentctl-dm.json DM open
agentctl-voice.json Join first voice channel
agentctl-deep-link.json pearcord://explore navigate
agentctl-composer-mention.json @everyone message
agentctl-leave-voice-noop.json leave-voice when disconnected (v0.8.257)
agentctl-settings-deep-link.json format-settings-deep-link IPC (v0.8.257)
agentctl-settings-navigate.json navigate-deep-linkpearcord://settings (v0.8.258)
agentctl-settings-guild-deep-link.json Register + guild + pearcord://settings?scope=guild&guildId=… (v0.8.259)
agentctl-composer-channel-mention.json Send @channel message (v0.8.258)
agentctl-guild-search.json Guild-wide update-search hit (v0.8.260)
agentctl-thread-mesh.json Host thread + reply; guest mesh sync (v0.8.260)
agentctl-forum-search.json Forum channel + post + forum-scoped search (v0.8.261)
agentctl-mark-channel-read.json markActiveChannelRead on guild text channel (v0.8.261)
agentctl-forum-search-mesh.json Forum search with includeMesh: true (v0.8.262)
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)
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-channel-search-cache.json Channel search empty after switching text channels (v0.8.266)
agentctl-search-unchanged.json Duplicate update-searchsearchUnchanged + cached (v0.8.270)
agentctl-notif-thread-place.json Thread notification place includes parent channel (v0.8.270)
agentctl-search-recent-dedupe.json Guild + channel recent rows for same query (v0.8.271)
agentctl-mark-all-notifications.json Seed inbox + mark-all-notifications-read (v0.8.272)
agentctl-forum-search-refresh.json Forum refresh-search with mesh off (v0.8.272)
agentctl-guild-search-refresh.json Guild refresh-search with mesh off (v0.8.273)
agentctl-thread-inbox-mark-read.json Thread inbox seed + markLatestNotificationRead (v0.8.273)
agentctl-channel-search-refresh.json Channel refresh-search with mesh off (v0.8.274)
agentctl-thread-parent-mark-read.json Thread parent select + markActiveChannelRead (v0.8.274)
agentctl-thread-mark-read-parent-roundtrip.json Thread mark-read, parent nav, return + markThreadAndParentRead (v0.8.275)
agentctl-guild-search-mesh-toggle.json Guild search mesh-off then mesh-on (v0.8.276)
agentctl-thread-inbox-mark-channel-read.json Thread inbox + parent markActiveChannelRead (v0.8.276)
agentctl-channel-search-mesh-toggle.json Channel search mesh-off then mesh-on (v0.8.277)
agentctl-forum-thread-parent-mark-read.json Forum post thread + parent mark-read (v0.8.277)
agentctl-forum-search-mesh-toggle.json Forum search mesh-off then mesh-on (v0.8.278)
agentctl-thread-inbox-mark-thread-parent.json Thread inbox + markThreadAndParentRead (v0.8.278)
agentctl-forum-search-refresh-cache-hit.json Forum search refresh with warm cache (v0.8.279)
agentctl-thread-mesh-mark-read.json Thread mesh + markThreadAndParentRead (v0.8.279; live mesh)
agentctl-thread-search-mesh-mark-read.json Thread search mesh toggle + mark-read fallback (v0.8.279)
agentctl-forum-thread-parent-navigate-mark-read.json Forum thread inbox navigate + parent mark-read (v0.8.280)
agentctl-thread-inbox-navigate-mark-thread-parent.json Thread inbox open-notification + mark-thread-parent (v0.8.281)
agentctl-thread-mesh-navigate-mark-thread-parent.json Mesh thread sync + inbox navigate + mark-thread-parent (v0.8.282)
agentctl-channel-search-mesh-stale-refresh.json Channel mesh-off/on + refresh-search (v0.8.283)
agentctl-guild-search-mesh-stale-refresh.json Guild mesh-off/on + refresh-search (v0.8.284)
agentctl-forum-search-mesh-stale-refresh.json Forum mesh-off/on + refresh-search (v0.8.285)
agentctl-voice-leave-roundtrip.json Join first voice channel then leave-voice clears occupancy (v0.8.333)
agentctl-attachment-send.json Fixture stage + send message with attachmentIds (v0.8.384)
agentctl-attachment-preview.json PNG stage + preview IPC event (v0.8.384)
agentctl-stage-join.json Create stage channel + join-stage (v0.8.385)
agentctl-role-create.json Create custom guild role (v0.8.389)
agentctl-channel-deny-send.json Channel overwrite deny send for @everyone (v0.8.389)
agentctl-presence-idle-custom.json Set idle + custom status (v0.8.388)
agentctl-activity-playing.json Set playing activity (v0.8.388)
agentctl-emoji-unicode.json Send message with unicode 🎉 (v0.8.386)
agentctl-sticker-send.json stageFixtureSticker + sticker message (v0.8.386)

v0.8.604 (Phase 632): PearcordMeshCluster (require('pearcord-agentctl/mesh-cluster')) runs scenarios/mesh-guild-sync.json — host onboard + create guild, guest join-invite, mesh wire, marker message. App smoke: npm run test:agentctl-mesh-guild-sync.

mesh.connectGuildMeshThread(scenarioPath) — optional markThreadAndParentRead: true in scenario JSON (v0.8.279). host steps + invite + create-thread + reply; guest must receive threadReply token.

Scenario step extras (headless + attached run): joinFirstVoice, joinFirstStage, stageFixtureSticker, sendMessageWithStagedStickers, openDmPeer, selectFirstForumChannel, selectSecondForumChannel, selectFirstTextChannel, selectSecondTextChannel, selectChannelNamed, selectChannelOtherThanActive, selectParentOfActiveThread, selectActiveThread, threadName with selectActiveThread, markActiveChannelRead, seedInboxNotification, markLatestNotificationRead, openLatestNotification, seedMentionAlertForActiveChannel, createThreadFromLastMessage, markThreadAndParentRead, toggleReactionOnLastMessage (emoji string or { emoji }), stageFixtureAttachment ({ image: true } for PNG), sendMessageWithStagedAttachments, requestPreviewForStagedAttachment, messagesMin, messageContentIncludes, searchResultsMin, searchResultsMax, searchResultsCached, searchUnchanged, searchRecentIncludes, mentionAlertCountMax, notificationUnreadMin, notificationUnreadMax, reactionCountMin, reactionsInclude, attachmentsOnLastMessageMin, stickersOnLastMessageMin, activeChannelName, parentChannelPermissions on wait, and waitLogContains (messageIncludes/contains and optional regex/lines) for structured log verification. waitEvent supports payloadType (e.g. attachment-preview).

Dependencies

  • pearcord-platform, pearcord-ui-flow, pearcord-log
  • bare-tcp for attached mode
S
Description
Pearcord module: agent TCP/headless control plane for live app + CI scenarios
Readme
26 MiB
Languages
JavaScript 100%