pearcord-guild

Guild lifecycle, channel tree (including threads and forums), member joins, and the Hyperswarm gossip mesh for server-scoped realtime events.

Mission

Create and load guilds in local storage, join peers on pearcord:guild:{guildId} topics, fan out RPC gossip (messages, reactions, voice, roles, audit, …), and attach auxiliary protomux channels for attachments, voice media, and screen share.

When to use / not

Use when:

  • Implementing server creation, invite joins, channel CRUD, or guild-scoped P2P replication.
  • Extending gossip handlers (_onGossip) or adding new RPC.* fanout methods.

Do not use when:

  • You only need a thin channel CRUD helper without mesh — see pearcord-channel (minimal; production path is this module).
  • You need DM conversations — use pearcord-dm.
  • You need the full desktop API — use pearcord-platform, which owns PearcordGuild instances.

Public API

Export Role
PearcordGuild Main class (EventEmitter)
PearcordGuild#create({ name, iconHash? }) New guild + owner member + general text + Voice Lobby; nsfwGateEnabled defaults true (v0.8.174)
PearcordGuild#joinByInvite(invite, userId) Materialize guild/channels from invite; add member; bump invite uses
PearcordGuild#setActiveGuild(guild) Set this.guild for list/create operations
PearcordGuild#joinMesh(opts?) / #leaveMesh() Hyperswarm on topicToBuffer(guild.topic); bounded flush() via PEARCORD_GUILD_SWARM_FLUSH_MS (default 2.5s)
PearcordGuild#listChannels() / #listMembers() DB queries with thread meta attached
PearcordGuild#createChannel, #createCategory, #createThread, #createForumThread Channel tree

v0.8.530 (Phase 567): Platform guild.create span adds textChannelCount/activeChannelId; onboarding live region + agentctl createGuild helper. Bundle: npm run test:phase567-onboarding. See ONBOARDING.md.

v0.8.512 (Phase 549): Third guild-admin depth pass — platform channelCount/remainingChannelCount/reorderedAll span metadata; UI split channel list + category panels + admin modal live regions. Bundle: npm run test:phase549-guild-admin. See CHANNELS.md.

v0.8.496 (Phase 533): Second guild-admin depth pass — platform channel span end metadata (spanKind, activeChannelId); UI panel compositor wrappers + channel row aria-current=location; agentctl channel CRUD helpers. Bundle: npm run test:phase533-guild-admin. See CHANNELS.md.

v0.8.476 (Phase 513): Platform wraps reorderChannelsInParent with channel.reorder span; extended channel.create/delete metadata. UI guild-admin guild-loading compositor + dev-log clipboard channel meta. Bundle: npm run test:phase513-guild-admin. See CHANNELS.md.

v0.8.429 (Phase 466): gossipAttachmentMeta and link-embed gossip re-verified for P2P attachments. See ATTACHMENTS.md.

v0.8.428 (Phase 465): gossipMessage, gossipMessageUpdate, gossipMessageDelete, and gossipReaction re-verified for P2P messaging. See MESSAGING.md.

v0.8.427 (Phase 464): gossipRoleUpsert, gossipRoleDelete, gossipChannelOverwriteUpsert, and gossipChannelOverwriteDelete re-verified for custom roles and channel overwrites. See ROLES.md.

v0.8.426 (Phase 463): gossipAudit, gossipAuditExportSnapshot, gossipAuditExportCsvSync, and gossipAuditExportArchive re-verified for P2P audit/compliance trail. Platform compliance.snapshot span wraps export snapshot gossip. See AUDIT.md, COMPLIANCE.md.

v0.8.425 (Phase 462): gossipBan / gossipKick / gossipTimeout / gossipAutomodConfig re-verified on mesh. See MODERATION.md, AUTOMOD.md.

v0.8.424 (Phase 461): gossipSlashCommand / gossipSlashCommandDelete / gossipBotInstall re-verified; bot messages via gossipMessage. See SLASH_COMMANDS.md, BOTS.md.

v0.8.423 (Phase 460): gossipAttachmentMeta + link-embed gossip re-verified on mesh (attachment.stage, embed.resolve platform spans). See ATTACHMENTS.md, EMBEDS.md.

v0.8.422 (Phase 459): gossipEmojiUpsert / gossipStickerUpsert / gossipReaction re-verified on mesh (platform spans emoji.upsert, sticker.create, reaction.toggle with guildId). See EMOJI.md, REACTIONS.md.

v0.8.421 (Phase 458): deleteChannel + gossipChannelDelete (RPC.CHANNEL_DELETE); inbound _ingestChannelDelete on mesh.

v0.8.420 (Phase 457): Platform wraps createChannel / createCategory / renameChannel with channel.create, category.create, and channel.update spans (see CHANNELS.md). | PearcordGuild#reorderChannelsInParent | Reassign position for siblings under one category/root | | PearcordGuild#moveChannelToParent | Move channel into category (v0.8.168) | | PearcordGuild#reorderCategories | Reassign position for category rows | | PearcordGuild#updateChannel, #ingestChannel | Upsert + thread meta; voice/stage userLimit (099); nsfw flag (v0.8.173) | | PearcordGuild#setMessageHandler(fn) | Inbound RPC.MESSAGE_CREATE persistence hook (platform sets this) | | PearcordGuild#gossip* / #sendVoiceMedia / #sendScreenMedia | Outbound RPC (see index.js for full list) | | PearcordGuild#simulateGossip(method, payload) | Bare smoke injection without live peers | | PearcordGuild#getStats() | { guildId, peers, openGossip, topic } | | PearcordGuild#fetchAttachmentFromPeers | P2P attachment pull via pearcord-drive | | PearcordGuild#setVoiceMediaHub / #setScreenShareHub / #setAttachmentProvider | Wire media meshes | | ./mesh | attachGossipMesh, broadcastGossip, GOSSIP_PROTOCOL |

P2P surface

Protocol Transport Purpose
pearcord-gossip-v1 Protomux on Hyperswarm connection JSON payloads in encodeRpc frames; handler _onGossip
Drive attach mesh pearcord-drive/attach-mesh Binary attachment fetch
Voice media pearcord-voice-media Live audio frames
Screen share pearcord-screen-share Display frames

Topic: guildTopic(guildId)topicToBuffer for swarm.join. Server and client mode enabled.

Inbound events emitted include: message, message-delete, presence, typing, reaction, channel, channel-update, member, guild-sync, voice-state, peer, and many feature-specific events (audit, bots, stickers, …).

Storage

Uses shared LocalDatabase (opts.db or opts.dbPath):

  • @pearcord/guilds, channels, members, messages, invites, thread-meta, bans, etc.

Guild rows include topic: pearcord:guild:{id} for swarm discovery.

Platform integration

const { PearcordGuild } = require('pearcord-guild')

// createGuild / loadGuild / joinInvite:
this.guild = new PearcordGuild({ ownerId, userId, db: this.db })
await this.guild.ready()
this.guild.setActiveGuild(guildRecord)
this._wireGuild(this.guild)  // setMessageHandler + event bridges
await this.guild.joinMesh()

_wireGuild connects gossip to platform emit('message'), search indexing, bot fanout, and db.insert. Outbound sends use this.guild.gossipMessage(msg) from sendMessage / edits / deletes.

Channel creation in production uses guild.createChannel / createCategory, not pearcord-channel.

UI / IPC

Indirect only. IPC create-guild, select-guild, join-invite, send-message, voice join, etc. all route through platform methods that delegate to PearcordGuild.

Tests

  • apps/pearcord: npm run test:guild-syncsmoke-guild-sync.cjs

  • smoke-guild-settings.cjs, smoke-guild-deep-link.cjs

  • Many mesh smokes call platform.guild.simulateGossip(RPC.*, payload)

  • v0.8.418 (Phase 455): Server settings UI uses syncGuildSettingsPanelDuringGuildLoading during guild switch; platform guild.update span on updateGuildSettings gossip path. See GUILD_SETTINGS.md.

  • v0.8.410 (Phase 447): Custom roles and channel overwrites are platform-owned (pearcord-guild-roles + channelPermissions); gossip still fans out ROLE_UPSERT / channel overwrite RPC from PearcordGuild. Regression bundle: npm run test:phase447-roles-permissions (see ROLES.md).

Code example

const { PearcordGuild } = require('pearcord-guild')
const { LocalDatabase } = require('pearcord-db')
const Hyperswarm = require('hyperswarm')

const db = new LocalDatabase('./pearcord-storage/db')
const guild = new PearcordGuild({ ownerId: 'user-1', userId: 'user-1', db })
await guild.ready()

const { guild: g, channels } = await guild.create({ name: 'My Server' })
guild.setMessageHandler(async (msg) => {
  await db.insert(require('pearcord-shared').COLLECTIONS.MESSAGES, msg)
  return msg
})
await guild.joinMesh()
guild.gossipTyping({ userId: 'user-1', channelId: channels[0].id, guildId: g.id, at: Date.now() })

Repository

Part of Pearcord.

  • Org: pearcord
  • Clone: git clone https://git.ssh.surf/pearcord/pearcord-guild.git
  • Install: npm install git+https://git.ssh.surf/pearcord/pearcord-guild.git#main
S
Description
Pearcord module: pearcord-guild
Readme
11 MiB
Languages
JavaScript 100%