Route voice/stage user limit updates from desktop UI to platform. Co-authored-by: Cursor <[email protected]>
pearcord-ui-flow
Pearcord desktop UI IPC dispatch and automated flow scenarios for Bare smokes. Mirrors apps/pearcord pear-pipe message handling.
Mission
Centralize the msg.type → platform.* routing table used by the Pear UI sidecar so smoke tests and tooling can drive the full platform surface without duplicating hundreds of if-branches in the app entrypoint.
When to use / not
Use when:
- Running Bare smokes that send JSON IPC lines to a headless platform instance.
- Adding a new UI IPC type—implement handler here and call from app shell.
Do not use when:
- You need platform business logic — implement on
PearcordPlatforminpearcord-platform. - You build non-Pear UIs — import platform directly.
Public API
| Export | Role |
|---|---|
dispatchUiMessage(platform, msg, hooks) |
Returns true if msg.type handled |
fromBase64(str) |
Buffer for attachment/emoji bytes |
normalizeEmojiImage(image) |
Maps dataBase64 → data buffer |
Hooks
{
send: (obj) => {}, // reply events to UI pipe
pushState: () => {} // refresh serialized state
}
Returns false for unknown types (caller may log).
Coverage (grouped)
| Area | Example msg.type values |
|---|---|
| Onboarding | register, create-guild, join-invite, select-guild |
| Automation | set-automod-config, upsert-automation-hook, export-automation-manifest, dry-run-automation-hook, schedule/export/dashboard IPC |
| Bots | create-bot-install-token, install-bot-token, register-slash-commands |
| Announcements | set-announcement-crosspost, set-announcement-hub-publish, subscribe-remote-announcement-hub, follow-announcement |
| Boosts / stickers | contribute-guild-boost, upsert-guild-sticker, upsert-sticker-pack |
| Profile | update-profile-cosmetics, set-profile-banner-image, step-up PIN types |
| Voice / screen | join-voice, voice-capture-chunk, display-capture-frame |
| Workers | export-integration-worker-script, run-worker-install-trial, announce-worker-release |
| Moderation / channels | ban-member, upsert-channel-overwrite, forum/thread types |
| Search | update-search, refresh-search, remove-search-recent (v0.8.140) |
Uses USER_STATUS from pearcord-platform for presence IPC.
Dependencies
pearcord-platform—PearcordPlatforminstance (git dependency in package.json)pearcord-qr— optional QR SVG for device pair codesb4a— base64 decode in Bare
Platform integration
// apps/pearcord/index.js pattern:
const { dispatchUiMessage } = require('pearcord-ui-flow')
async function onPipeLine(line) {
const msg = JSON.parse(line)
const handled = await dispatchUiMessage(platform, msg, { send, pushState })
if (!handled) send({ type: 'error', message: `unknown type ${msg.type}` })
}
P2P surface
None directly—all mesh behavior delegated to platform methods invoked by dispatch.
Tests
Primary consumer: Bare smoke suites under apps/pearcord that spawn platform + pipe JSON lines.
Adding handlers here keeps smokes and production UI in sync.
Code example
const { dispatchUiMessage, fromBase64 } = require('pearcord-ui-flow')
const replies = []
await dispatchUiMessage(
platform,
{ type: 'dry-run-automod', content: 'discord.gg/test' },
{
send: (o) => replies.push(o),
pushState: () => {}
}
)
// replies[0].type === 'automod-dry-run'
Related modules
pearcord-platform— implementation target for every branch- All feature modules — reached indirectly through platform
Maintenance
When adding IPC in the Pear app, add the same msg.type branch here first (or simultaneously) so dispatchUiMessage remains the single routing table.