feat(code): add Discord Rich Presence integration#2453
Conversation
Add a Discord Rich Presence service that surfaces current activity in the user's Discord status. Includes a main-process service over Discord IPC, tRPC router, settings persistence, and a Discord settings section in the renderer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a DiscordPresencePreview component that mocks the Discord activity card from app primitives so it tracks the theme. It reacts to the privacy toggles, offers a Running/Idle switch inline with the Preview header, shows an elapsing green timer, and dims when the feature is off. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lock in that a DiscordIpcClient is only ever constructed/connected when the toggle is enabled: not on boot when disabled, and not when activity or privacy updates arrive while disabled. Includes an enabled-path sanity check so the assertions are meaningful. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When Rich Presence is off, the in-settings preview now stops its elapsed timer, falls back to the idle state (amber pause badge), and locks the Running/Idle toggle so the dormant integration reads clearly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
There was a problem hiding this comment.
Pull request overview
Adds a Discord Rich Presence integration to the PostHog Code desktop app, with a main-process Discord IPC client/service, tRPC endpoints, renderer boot-time subscriptions to keep presence in sync, and a new Settings UI section to control privacy and enablement.
Changes:
- Implement main-process Discord IPC client + presence service (rate-limited updates, reconnect loop, settings persistence, schemas, tests).
- Add renderer-side boot subscription to derive “presence intent” from navigation/session state and push it to the main service.
- Add Discord settings section + preview card and wire into Settings dialog navigation.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/code/vite.main.config.mts | Exposes VITE_DISCORD_CLIENT_ID to the main build via define. |
| apps/code/src/renderer/features/settings/stores/settingsDialogStore.ts | Adds a new "discord" settings category. |
| apps/code/src/renderer/features/settings/components/SettingsDialog.tsx | Adds Discord section entry/icon/title/component wiring. |
| apps/code/src/renderer/features/settings/components/sections/DiscordSettings.tsx | New Discord settings UI (enable + privacy toggles) driven by tRPC state/subscription. |
| apps/code/src/renderer/features/settings/components/sections/DiscordPresencePreview.tsx | New in-app preview card for Rich Presence appearance. |
| apps/code/src/renderer/features/discord-presence/subscriptions.ts | New renderer subscription registrar to push presence intent to main via tRPC. |
| apps/code/src/renderer/App.tsx | Registers Discord presence subscriptions once at app boot. |
| apps/code/src/main/trpc/routers/discord-presence.ts | New tRPC router exposing Discord presence service controls + status subscription. |
| apps/code/src/main/trpc/router.ts | Wires discordPresence into the root tRPC router. |
| apps/code/src/main/services/settingsStore.ts | Persists Discord presence enablement + privacy flags. |
| apps/code/src/main/services/discord-presence/service.ts | New main-process Discord presence service (connect/reconnect, rate-limit, formatting, state events). |
| apps/code/src/main/services/discord-presence/service.test.ts | Unit tests for connection gating behavior. |
| apps/code/src/main/services/discord-presence/schemas.ts | Zod schemas/types for presence state and intent. |
| apps/code/src/main/services/discord-presence/presence-format.ts | Pure formatter from intent+privacy options to Discord activity payload. |
| apps/code/src/main/services/discord-presence/presence-format.test.ts | Unit tests for formatting/privacy/truncation. |
| apps/code/src/main/services/discord-presence/discord-ipc.ts | New Node net-based Discord local IPC client implementation. |
| apps/code/src/main/services/discord-presence/constants.ts | New constants + getDiscordClientId() helper. |
| apps/code/src/main/index.ts | Eagerly instantiates the Discord presence service at startup. |
| apps/code/src/main/di/tokens.ts | Adds DI token for DiscordPresenceService. |
| apps/code/src/main/di/container.ts | Binds DiscordPresenceService into the DI container. |
| .env.example | Documents VITE_DISCORD_CLIENT_ID setup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Extend the shared TypedEventEmitter instead of hand-rolling on/emit overrides whose signatures are incompatible with Node's EventEmitter (which would error under @types/node >= 20). Events are now a typed payload map. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ion content Collapse the per-scenario it blocks into a single it.each table, and make the truncation case verify the prefix and trailing ellipsis are preserved rather than only bounding the length. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…resolves Merge optimistic toggle updates onto a default state when the panel state is still null, so the Switch reflects the change immediately instead of appearing stuck until the query/subscription updates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the placeholder TODO now that the real public "PostHog Code" Discord Application ID is set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ning Log and emit the disconnected state once per streak instead of on every 15s reconnect attempt: drop the per-attempt IPC debug line and gate the service's log/status-emit behind a `waiting` flag that resets on connect or disable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the live presence, whose title comes from the Discord application name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds a Discord Rich Presence integration that surfaces the user's current activity in their Discord status.
discord-presence/service.ts) talking to Discord over its local IPC socket (discord-ipc.ts), with presence formatting helpers (presence-format.ts) and Zod schemas (schemas.ts).routers/discord-presence.ts) exposing the service, wired into the root router and DI container.settingsStoreplus a new Discord settings section in the renderer (DiscordSettings.tsx), gated by a settings dialog entry.renderer/features/discord-presence/subscriptions.ts) wired once at app boot..env.exampleentries and avite.main.config.mtstweak for the integration.Screenshots
Test plan
presence-format.test.tsunit testspnpm typecheck(ran via pre-commit hook)🤖 Generated with Claude Code