feat: one-way Discord to Linear bridge for #help threads - #61
Merged
Conversation
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 15:28
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 15:49
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 16:51
Inactive
phorcys420
force-pushed
the
phorcys/linear-bridge
branch
from
August 19, 2026 17:02
6fd36e5 to
5c6a8fa
Compare
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 17:02
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 18:49
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 19:05
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 19:08
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 19:17
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 19:22
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:06
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:16
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:23
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:26
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:30
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:33
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:39
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:43
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 20:48
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:20
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:32
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:44
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:45
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:46
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:51
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:52
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 21:53
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 22:08
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 22:14
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 19, 2026 22:15
Inactive
phorcys420
force-pushed
the
phorcys/linear-bridge
branch
from
August 20, 2026 08:29
ac72642 to
81528ee
Compare
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 08:29
Inactive
Split the Discord-baked one-way mirror into a source-agnostic core, a Discord connector, and a Linear hub connector, making way for a future GitHub Discussions bridge without changing behavior or the on-the-wire format. - core/: canonical model, Source/Target capability interfaces, orchestrating Mirror, reconciler, references, rate-limit retry. - discord/: DiscordConnector (listeners + backfill + announce) and model mapping. - linear/: hub split into client/issues/comments/reactions/labels/emojis/ attachments/state/assets behind LinearConnector. - Add src/bridge/ARCHITECTURE.md documenting the source-authoritative, Linear-as-relay-hub reconciliation model and the planned bidirectional path. - Delete the redundant one-shot sync script (superseded by startup backfill).
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 09:05
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:11
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:17
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:20
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:21
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:28
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:43
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:48
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:50
Inactive
railway-app
Bot
temporarily deployed
to
Discord bot (Codercord) / production
August 20, 2026 10:54
Inactive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One-way Discord → Linear bridge for the
#helpforum (MVP for DEVREL-329).config.linearBridge.enabledHow it's wired
discord.js has no middleware, so the help flow now emits enriched domain events on an internal typed bus (
src/lib/bus.ts, no new dep) and the bridge subscribes. The bridge never re-runsisHelpPost.helpThreadCreated,helpMessagePosted,helpThreadStatusChangedemitted fromevents/channels.ts,events/messages.ts, andlib/discord/help.ts.src/bridge/linear/(subfolder so future bridges sit beside it), using@linear/sdk.Mapping & metadata (stateless)
url= thread URL (also the issue's Link),title"Discord thread",metadata{ threadId, tagIds, tagNames, status, waiting }, readable subtitle. Lookup/dedup viaattachmentsForURL.Labels
Discord (#help)(created withteamId, never global).description= the Discord tag ID, and find-or-create matches on that (rename-safe, no dupes). Diffed on status change.config.linearBridge.labels.enabled = false→ attachment metadata only.Config
linearBridge { enabled, apiKey, teamId, labels{ enabled, groupName } }, default off.apiKeyis env-only (Codercord_linearBridge__apiKey);validateLinearBridgeConfig()exits at startup if enabled withoutapiKey/teamId.Backfill
scripts/discord-linear-sync.ts(bun run sync:linear) reuses the same lib to seed existing threads.Notes / follow-ups
MessageContentintent in code; it must be enabled in the Discord dev portal or comment bodies come through empty.closed/reopenedis emitted only from theThreadUpdatehandler (notclose.ts) since/closetriggersThreadUpdatetoo, avoiding duplicate status comments.Verification
tsc --noEmitclean (incl. script),bun lint/formatclean, runtime smoke tests for disabled/enabled/fail-fast paths pass. Bot behavior unchanged when disabled.Implementation plan
Plan: Discord to Linear bridge (codercord)
Repo
coder/codercord· branchphorcys/linear-bridge· one-way MVP for DEVREL-329.What it does
config.linearBridge.enabled.How it's wired: internal event bus
discord.js has no middleware, so the help flow emits enriched domain events and the bridge subscribes. Bridge never re-runs
isHelpPost.src/lib/bus.ts(typed EventEmitter, no new dep) with:helpThreadCreated(ctx)helpMessagePosted(ctx)helpThreadStatusChanged(ctx)Emitted from the existing handlers (
events/channels.ts,events/messages.ts,lib/discord/help.tsapplyWaitingTag,commands/util/close.ts). Emits are best-effort so a consumer error can't break the help flow.Context resolver in
lib/discord/help.ts:Linear side
New dep
@linear/sdk. Code undersrc/bridge/linear/(subfolder so future bridges live beside it):client.ts—LinearClientfromconfig.linearBridge.apiKey.api.ts— thin wrappers: find/create issue, comment, set state, attachment upsert, label group + label ensure.index.ts— orchestration:mirrorThreadCreated,mirrorMessage,mirrorStatus,ensureIssueForThread.src/events/bridge.ts—registerEvents(client); if enabled, subscribe to the bus. Wired intosrc/index.ts.Mapping & metadata (stateless)
url= thread URL (also the issue's Link),title"Discord thread", plusmetadata{ threadId, tagIds, tagNames, status, waiting }and a readablesubtitle.attachmentsForURL; in-runMapis just a cache.Labels
Discord (#help)(created withteamId, never global).description= the Discord tag ID; find-or-create matches on that (rename-safe, no dupes).ctx.tagsand diff.config.linearBridge.labels.enabled = false-> metadata only.Config (
config.ts+config.json.example)configmasher
mandatoryis static, sovalidateLinearBridgeConfig()throws at startup ifenabledbutapiKey/teamIdmissing.Backfill script
scripts/discord-linear-sync.ts(bun scripts/discord-linear-sync.ts, plus async:linearpackage script): logs in, walks active help threads likecatchUpHelpPosts, and runs the samesrc/bridge/linearlib. Keeps the always-on bot lean.Also
GatewayIntentBits.MessageContentinindex.ts(privileged; needs the Discord dev-portal toggle or comment bodies are empty).AGENTS.mdlayout + config example.Generated by Coder Agents on behalf of @phorcys420.