Expose parseOpenSlashRegistryJsonQuery and parseOpenSlashInvokeAuditJsonQuery for Phase 723 dedicated slash export modals on guild-channel navigation. Co-authored-by: Cursor <[email protected]>
pearcord-shared
Cross-cutting constants, topic naming, RPC framing, permission helpers, message formatting, and deep-link utilities shared by every Pearcord module.
Phase 668 (v0.8.643): unfurl-policy.js — unfurlSuppressReason, isEmbedDomainBlocked, embedHostnameFromUrl for domain deny/allowlist and dev unfurl reason badge. Bundle: npm run test:ci-phase668.
Phase 667 (v0.8.642): unfurl-policy.js — markdown-aware URL extraction for embed unfurl (extractUnfurlUrls, spoiler/code/md-link suppression, first-line policy, layout gates). Re-exported from format-message.js and main index.js. Bundle: npm run test:ci-phase667.
Phase 659 (v0.8.638): Added DM poll payload helpers — parseDmPollCreateCommand (supports /poll, /pollm, /polla, /pollma, --expires), buildDmPollMessageContent, parseDmPollMessageContent, pollVoteEmoji, and poll option constants (DM_POLL_MAX_OPTIONS, DM_POLL_EMOJIS, DM_POLL_DEFAULT_EXPIRES_MS).
Phase 659 (v0.8.638+): DM scheduled-message helpers — parseDmScheduleCreateCommand, parseDmScheduleDelaySpec, normalizeDmScheduledMessagePayload, plus dm-scheduled-policy.js (queue cap, retry backoff, recurrence presets, tomorrow9am shortcut, timezone preview helper).
Phase 410 (v0.8.638): Added paste/navigation validation — validatePastedNavigationInput, pasteValidationToast, decodePortableInvitePayload, and PASTE_NAV_MAX_LEN for invite/deep-link gates before IPC and navigateDeepLink.
Mission
Provide a single source of truth for HyperDB collection names, channel and member enums, gossip RPC method IDs, Hyperswarm topic strings, and local permission bitmask checks. Avoid duplicating wire formats or ID generation across guild, DM, platform, and bot packages.
When to use / not
Use when:
- You need
COLLECTIONS,RPC,CHANNEL_TYPES, or topic helpers (guildTopic,dmTopic,encodeRpc). - You enforce send/view/voice permissions with
memberCanParticipate,memberHasPermission, orcanModifyMessage. - You parse or emit
pearcord://deep links or format message HTML / mentions.
Do not use when:
- You need persistence — use
pearcord-db. - You need Hyperswarm sessions — use
pearcord-guildorpearcord-dm. - You need a full app API — use
pearcord-platform.
Public API
| Export | Role |
|---|---|
COLLECTIONS |
HyperDB / JSON collection keys (@pearcord/users, …) |
CHANNEL_TYPES, USER_STATUS, MEMBER_ROLES |
Domain enums |
v0.8.611 (Phase 639): RPC.GUILD_SYNC_HEALTH (94) and RPC.SETTINGS_READ_RECEIPT_SYNC (95) for multi-device settings mesh health + read receipt gossip.
v0.8.612 (Phase 640): RPC.PRESENCE_VECTOR_SYNC (96) for cross-device guild presence vector max-seq merge on settings mesh.
| PERMISSION, ROLE_PERMISSIONS | Bitmask permission model |
| memberCanParticipate, memberCanViewChannel, memberCanConnectVoice, memberCanSpeakInVoice, memberCanJoinVoiceListenOnly | Effective-mask aware checks |
| memberHasPermission, roleHasPermission, canModifyMessage | Moderation / edit rules |
| RPC | Numeric gossip method IDs (1–79) |
| id, discriminator, now | ID and timestamp helpers |
| guildTopic, dmTopic, groupDmTopic, contactsTopic, settingsTopic, userPrefsTopic, profileCosmeticsTopic, deviceSyncTopic | Hyperswarm topic strings |
| dmChannelId, groupDmChannelId, normalizeGroupParticipants, GROUP_DM_MIN, GROUP_DM_MAX | DM / group DM identity |
| topicToBuffer | Hash topic → swarm discovery key |
| encodeRpc, decodeRpc | compact-encoding RPC frame (uint8 method + uint length + raw payload) |
| formatMessageContent, extractMentionNames, extractFirstUrl, linkPreviewMeta, buildLinkPreviewHtml, buildRichEmbedHtml, linkifyMessageHtml | Message rendering |
| resolveMentionedUserIds | @name → user id resolution |
| PEARCORD_SCHEME, isPearcordDeepLink, findPearcordDeepLinkInArgv, parsePearcordDeepLink, formatPearcordDeepLink, formatGuildDeepLink, formatInviteDeepLink, formatDevicePairDeepLink, formatExploreBaselineDeepLink | OS / argv deep links |
| DEVICE_PAIR_PREFIX | pcdv_ device pairing codes |
Submodules: ./format-message, ./mentions, ./deep-links (re-exported from index.js).
P2P surface
| Surface | Detail |
|---|---|
| RPC framing | encodeRpc(method, payloadBuf) / decodeRpc(buf) — used by guild gossip (pearcord-gossip-v1), DM mesh, contacts, settings |
| Topics | Deterministic strings hashed via topicToBuffer for Hyperswarm join |
| RPC constants | Payloads are JSON inside frames; method IDs defined in RPC |
No network code lives in this package.
Storage
None. Pure utilities and constants.
Platform integration
pearcord-platform imports a large subset for permissions, deep links, search indexing helpers (id, now), and inbound message policy (canModifyMessage, memberCanParticipate, COLLECTIONS).
Other modules (pearcord-guild, pearcord-message, pearcord-invite, pearcord-identity, smoke scripts) depend on this package directly.
UI / IPC
Not used by IPC directly. UI receives permission outcomes and formatted HTML from the platform sidecar, which uses these helpers internally.
Deep-link argv parsing is used by companion and desktop startup flows via platform + pearcord-protocol.
Related docs
- MODULES.md — package map
- PERMISSIONS.md — role bitmask semantics
- ROLE_PERMISSIONS.md — built-in roles
- CHANNEL_PERMISSIONS.md — overwrites + effective mask
- PEARCORD_PROTOCOL.md —
pearcord://URLs - MESSAGE_DEEP_LINKS.md — jump links
- INVITE_DEEP_LINKS.md — invite URLs
- GUILD_SYNC.md —
RPC.GUILD_SYNCpayload - HOLEPUNCH_STACK.md — Hyperswarm stack context
Tests
No unit tests in this package. Exercised indirectly via apps/pearcord smoke scripts that import RPC, COLLECTIONS, CHANNEL_TYPES, or deep-link helpers (for example smoke-voice-speaking-mesh.cjs, smoke-device-pair-deep-link.cjs, smoke-guild-sync.cjs).
Code example
const {
RPC,
guildTopic,
topicToBuffer,
encodeRpc,
memberCanParticipate,
id
} = require('pearcord-shared')
const b4a = require('b4a')
const guildId = id()
const topic = guildTopic(guildId)
const discoveryKey = topicToBuffer(topic)
const frame = encodeRpc(RPC.MESSAGE_CREATE, b4a.from(JSON.stringify({
id: id(),
channelId: 'ch1',
content: 'hello'
})))
const allowed = memberCanParticipate(
{ roles: 'member', customRoleIds: [] },
[],
null
)
Repository
Part of Pearcord — peer-to-peer community chat on Pear.
- Org:
pearcord - Clone:
git clone https://git.ssh.surf/pearcord/pearcord-shared.git - Install:
npm install git+https://git.ssh.surf/pearcord/pearcord-shared.git#main