From 2ae1dcf32bbefdc9b6da4255dfc62bc576726d4a Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Wed, 18 Mar 2026 14:53:30 -0500 Subject: [PATCH] refactor: migrate discord actions ownership --- src/channels/discord/plugin-sdk-bridge.ts | 33 ---------- .../channel-import-guardrails.test.ts | 13 ++++ src/plugin-sdk/discord.ts | 66 +++++++++---------- src/plugin-sdk/subpaths.test.ts | 2 + 4 files changed, 48 insertions(+), 66 deletions(-) diff --git a/src/channels/discord/plugin-sdk-bridge.ts b/src/channels/discord/plugin-sdk-bridge.ts index 1a226a67dad..0125a9d2c98 100644 --- a/src/channels/discord/plugin-sdk-bridge.ts +++ b/src/channels/discord/plugin-sdk-bridge.ts @@ -8,13 +8,11 @@ export type { export { collectDiscordStatusIssues, - createDiscordActionGate, inspectDiscordAccount, listDiscordAccountIds, looksLikeDiscordTargetId, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, - readDiscordComponentSpec, resolveDiscordAccount, resolveDefaultDiscordAccountId, resolveDiscordChannelId, @@ -22,26 +20,9 @@ export { resolveDiscordGroupToolPolicy, } from "../../../extensions/discord/api.js"; export { - addRoleDiscord, - auditDiscordChannelPermissions, - banMemberDiscord, - collectDiscordAuditChannelIds, - createChannelDiscord, - createScheduledEventDiscord, - createThreadDiscord, - deleteChannelDiscord, - deleteMessageDiscord, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, - discordMessageActions, - editChannelDiscord, - editMessageDiscord, fetchChannelInfoDiscord, - fetchChannelPermissionsDiscord, - fetchMemberInfoDiscord, - fetchMessageDiscord, - fetchReactionsDiscord, - fetchRoleInfoDiscord, fetchVoiceStatusDiscord, getGateway, getPresence, @@ -53,25 +34,11 @@ export { listScheduledEventsDiscord, listThreadsDiscord, monitorDiscordProvider, - moveChannelDiscord, - pinMessageDiscord, probeDiscord, - reactMessageDiscord, readMessagesDiscord, - removeChannelPermissionDiscord, - removeOwnReactionsDiscord, - removeReactionDiscord, - removeRoleDiscord, searchMessagesDiscord, - sendDiscordComponentMessage, sendMessageDiscord, - sendPollDiscord, - sendStickerDiscord, sendTypingDiscord, sendVoiceMessageDiscord, - setChannelPermissionDiscord, - timeoutMemberDiscord, unpinMessageDiscord, - uploadEmojiDiscord, - uploadStickerDiscord, } from "../../../extensions/discord/runtime-api.js"; diff --git a/src/plugin-sdk/channel-import-guardrails.test.ts b/src/plugin-sdk/channel-import-guardrails.test.ts index c1645c92a87..c886f7518e8 100644 --- a/src/plugin-sdk/channel-import-guardrails.test.ts +++ b/src/plugin-sdk/channel-import-guardrails.test.ts @@ -381,6 +381,19 @@ describe("channel import guardrails", () => { expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/runtime-api\.js";/); }); + it("keeps Discord actions ownership on extension public seams", () => { + const text = readSource("src/plugin-sdk/discord.ts"); + const bridgeImports = [...text.matchAll(/import(?: type)?\s*\{[\s\S]*?\}\s*from\s+"[^"]+";/g)] + .map((match) => match[0]) + .filter((statement) => statement.includes("../channels/discord/plugin-sdk-bridge.js")) + .join("\n"); + expect(bridgeImports).not.toMatch( + /\b(?:createDiscordActionGate|readDiscordComponentSpec|discordMessageActions|addRoleDiscord|auditDiscordChannelPermissions|banMemberDiscord|collectDiscordAuditChannelIds|createChannelDiscord|createScheduledEventDiscord|createThreadDiscord|deleteChannelDiscord|deleteMessageDiscord|editChannelDiscord|editMessageDiscord|fetchChannelPermissionsDiscord|fetchMemberInfoDiscord|fetchMessageDiscord|fetchReactionsDiscord|fetchRoleInfoDiscord|moveChannelDiscord|pinMessageDiscord|reactMessageDiscord|removeChannelPermissionDiscord|removeOwnReactionsDiscord|removeReactionDiscord|removeRoleDiscord|sendDiscordComponentMessage|sendPollDiscord|sendStickerDiscord|setChannelPermissionDiscord|timeoutMemberDiscord|uploadEmojiDiscord|uploadStickerDiscord)\b/, + ); + expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/api\.js";/); + expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/runtime-api\.js";/); + }); + it("keeps channel helper modules off their own SDK barrels", () => { for (const source of SAME_CHANNEL_SDK_GUARDS) { const text = readSource(source.path); diff --git a/src/plugin-sdk/discord.ts b/src/plugin-sdk/discord.ts index 99593957075..2b4bbc3350a 100644 --- a/src/plugin-sdk/discord.ts +++ b/src/plugin-sdk/discord.ts @@ -1,6 +1,8 @@ import { + createDiscordActionGate, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, + readDiscordComponentSpec, } from "../../extensions/discord/api.js"; import type { ThreadBindingManager, @@ -8,20 +10,51 @@ import type { ThreadBindingTargetKind, } from "../../extensions/discord/runtime-api.js"; import { + addRoleDiscord, + auditDiscordChannelPermissions, autoBindSpawnedDiscordSubagent, + banMemberDiscord, + collectDiscordAuditChannelIds, + createChannelDiscord, + createScheduledEventDiscord, + createThreadDiscord, + deleteChannelDiscord, + deleteMessageDiscord, + discordMessageActions, + editChannelDiscord, + editMessageDiscord, + fetchChannelPermissionsDiscord, + fetchMemberInfoDiscord, + fetchMessageDiscord, + fetchReactionsDiscord, + fetchRoleInfoDiscord, getThreadBindingManager, listDiscordDirectoryGroupsLive, listDiscordDirectoryPeersLive, listThreadBindingsBySessionKey, + moveChannelDiscord, + pinMessageDiscord, + reactMessageDiscord, + removeChannelPermissionDiscord, + removeOwnReactionsDiscord, + removeReactionDiscord, + removeRoleDiscord, resolveDiscordChannelAllowlist, resolveDiscordUserAllowlist, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingInactivityExpiresAt, resolveThreadBindingMaxAgeExpiresAt, resolveThreadBindingMaxAgeMs, + sendDiscordComponentMessage, + sendPollDiscord, + sendStickerDiscord, setThreadBindingIdleTimeoutBySessionKey, setThreadBindingMaxAgeBySessionKey, + setChannelPermissionDiscord, + timeoutMemberDiscord, unbindThreadBindingsBySessionKey, + uploadEmojiDiscord, + uploadStickerDiscord, } from "../../extensions/discord/runtime-api.js"; import { normalizeExplicitDiscordSessionKey } from "../../extensions/discord/session-key-api.js"; import type { @@ -33,39 +66,20 @@ import type { } from "../channels/discord/plugin-sdk-bridge.js"; import { collectDiscordStatusIssues, - createDiscordActionGate, inspectDiscordAccount, listDiscordAccountIds, looksLikeDiscordTargetId, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, - readDiscordComponentSpec, resolveDefaultDiscordAccountId, resolveDiscordChannelId, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, } from "../channels/discord/plugin-sdk-bridge.js"; import { - addRoleDiscord, - auditDiscordChannelPermissions, - banMemberDiscord, - collectDiscordAuditChannelIds, - createChannelDiscord, - createScheduledEventDiscord, - createThreadDiscord, - deleteChannelDiscord, - deleteMessageDiscord, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, - discordMessageActions, - editChannelDiscord, - editMessageDiscord, fetchChannelInfoDiscord, - fetchChannelPermissionsDiscord, - fetchMemberInfoDiscord, - fetchMessageDiscord, - fetchReactionsDiscord, - fetchRoleInfoDiscord, fetchVoiceStatusDiscord, getGateway, getPresence, @@ -77,27 +91,13 @@ import { listScheduledEventsDiscord, listThreadsDiscord, monitorDiscordProvider, - moveChannelDiscord, - pinMessageDiscord, probeDiscord, - reactMessageDiscord, readMessagesDiscord, - removeChannelPermissionDiscord, - removeOwnReactionsDiscord, - removeReactionDiscord, - removeRoleDiscord, searchMessagesDiscord, - sendDiscordComponentMessage, sendMessageDiscord, - sendPollDiscord, - sendStickerDiscord, sendTypingDiscord, sendVoiceMessageDiscord, - setChannelPermissionDiscord, - timeoutMemberDiscord, unpinMessageDiscord, - uploadEmojiDiscord, - uploadStickerDiscord, } from "../channels/discord/plugin-sdk-bridge.js"; export type { diff --git a/src/plugin-sdk/subpaths.test.ts b/src/plugin-sdk/subpaths.test.ts index 4c81e3bd7c8..633d2e45117 100644 --- a/src/plugin-sdk/subpaths.test.ts +++ b/src/plugin-sdk/subpaths.test.ts @@ -265,7 +265,9 @@ describe("plugin-sdk subpath exports", () => { it("exports Discord helpers", () => { expect(typeof discordSdk.buildChannelConfigSchema).toBe("function"); + expect(typeof discordSdk.createDiscordActionGate).toBe("function"); expect(typeof discordSdk.DiscordConfigSchema).toBe("object"); + expect(typeof discordSdk.discordMessageActions).toBe("object"); expect(typeof discordSdk.listDiscordDirectoryGroupsFromConfig).toBe("function"); expect(typeof discordSdk.listDiscordDirectoryPeersFromConfig).toBe("function"); expect(typeof discordSdk.listDiscordDirectoryGroupsLive).toBe("function");