Wire MENTION_EVERYONE into permission metadata and maskToPermissionView. Co-authored-by: Cursor <[email protected]>
pearcord-guild-roles
Custom guild roles with permission bitmasks, member ↔ role links, bitmask helpers, and guild gossip / sync bundles.
Mission
Let servers define up to 24 named colored roles with Discord-style permission flags, assign them to members, resolve effective permissions (with channel overwrites via platform), and ship built-in owner/moderator/member/lurker templates for the editor UI.
When to use / not
Use when:
- Creating/updating custom roles or member role assignments.
- Converting masks to toggle views (
maskToPermissionView,PERMISSION_META). - Exporting
guildRoles+memberRoleLinksforGUILD_SYNC.
Do not use when:
- You need per-channel overwrites only — use
pearcord-channel-permissions. - You need builtin promote/demote (
MEMBER_ROLES) without custom rows — still usememberPermissionMaskfor resolution. - You need cross-server roles — roles are per
guildId.
Public API
| Export | Role |
|---|---|
PearcordGuildRoles |
JsonStore CRUD |
ROLES_COLLECTION |
'@pearcord/guild-custom-roles' |
LINKS_COLLECTION |
'@pearcord/member-custom-role-links' |
MAX_CUSTOM_ROLES |
24 |
PERMISSION_META |
UI toggle metadata |
normalizePermissionsMask |
Sanitize allow mask |
memberPermissionMask / maskToPermissionView |
./permissions |
PearcordGuildRoles (selected)
| Method | Role |
|---|---|
listRoles / getRole / createRole / updateRole / deleteRole / reorderRoles |
Role CRUD + position reorder; hoist displays members separately in sidebar (v0.8.171) |
getMemberRoleIds / setMemberRoleIds |
Member links |
attachCustomRolesToMembers |
Enrich member list |
resolvePermissions(member, customRoles) |
View object for UI |
builtinRoleTemplates() |
Read-only presets |
ingestRoleGossip / ingestRoleDelete / ingestMemberRolesGossip |
P2P |
exportSyncBundle / ingestSyncBundle |
Guild sync |
Reserved names (cannot create): owner, moderator, member, lurker.
P2P surface
| RPC | Purpose |
|---|---|
ROLE_UPSERT (59) |
Role row |
ROLE_DELETE (60) |
Remove role |
MEMBER_ROLES_UPDATE (61) |
userId + roleIds[] |
Platform guild _onGossip delegates to ingest methods.
Storage
| Collection | Engine |
|---|---|
@pearcord/guild-custom-roles |
JsonStore {storagePath}/guild-roles |
@pearcord/member-custom-role-links |
Same store |
Builtin MEMBER_ROLES from pearcord-shared are not stored as custom rows; merged at resolve time.
Platform integration
const { PearcordGuildRoles, PERMISSION_META } = require('pearcord-guild-roles')
const { memberPermissionMask, maskToPermissionView } = require('pearcord-guild-roles/permissions')
this.guildRoles = new PearcordGuildRoles({
storagePath: this.storagePath,
guildId: guild.id
})
await this.guildRoles.ready()
Voice/stage join: listRoles + memberPermissionMask with channel overwrites. Server settings role editor uses PERMISSION_META and builtinRoleTemplates().
UI / IPC
Server settings → Roles: create role, color, permission matrix, drag reorder (updates position + ROLE_UPSERT gossip), assign to members. IPC mirrors platform role APIs including reorder-guild-custom-roles.
Related docs
Tests
npm run test:role-permissionsnpm run test:voice-permissionsnpm run test:role-reorder(Phase 202 GUI drag reorder)
Code example
const { PearcordGuildRoles } = require('pearcord-guild-roles')
const { PERMISSION } = require('pearcord-shared')
const roles = new PearcordGuildRoles({
storagePath: './pearcord-storage',
guildId: 'g1'
})
await roles.ready()
const role = await roles.createRole('g1', {
name: 'DJ',
color: '#eb459e',
permissions: PERMISSION.SPEAK_IN_VOICE | PERMISSION.CONNECT_VOICE
})
await roles.setMemberRoleIds('g1', 'user-2', [role.id])
const view = roles.resolvePermissions(
{ userId: 'user-2', role: 'member', customRoleIds: [role.id] },
[role]
)
console.log(view.speakInVoice)
Repository
Part of Pearcord.
- Org:
pearcord - Clone:
git clone https://git.ssh.surf/pearcord/pearcord-guild-roles.git - Install:
npm install git+https://git.ssh.surf/pearcord/pearcord-guild-roles.git#main