diff --git a/src/channels/discord/plugin-sdk-bridge.ts b/src/channels/discord/plugin-sdk-bridge.ts index 2243550e402..b2a9009458b 100644 --- a/src/channels/discord/plugin-sdk-bridge.ts +++ b/src/channels/discord/plugin-sdk-bridge.ts @@ -5,11 +5,6 @@ export type { InspectedDiscordAccount, ResolvedDiscordAccount, } from "../../../extensions/discord/api.js"; -export type { - ThreadBindingManager, - ThreadBindingRecord, - ThreadBindingTargetKind, -} from "../../../extensions/discord/runtime-api.js"; export { collectDiscordStatusIssues, @@ -29,7 +24,6 @@ export { export { addRoleDiscord, auditDiscordChannelPermissions, - autoBindSpawnedDiscordSubagent, banMemberDiscord, collectDiscordAuditChannelIds, createChannelDiscord, @@ -51,7 +45,6 @@ export { fetchVoiceStatusDiscord, getGateway, getPresence, - getThreadBindingManager, hasAnyGuildPermissionDiscord, kickMemberDiscord, listDiscordDirectoryGroupsLive, @@ -60,7 +53,6 @@ export { listGuildEmojisDiscord, listPinsDiscord, listScheduledEventsDiscord, - listThreadBindingsBySessionKey, listThreadsDiscord, monitorDiscordProvider, moveChannelDiscord, @@ -74,10 +66,6 @@ export { removeRoleDiscord, resolveDiscordChannelAllowlist, resolveDiscordUserAllowlist, - resolveThreadBindingIdleTimeoutMs, - resolveThreadBindingInactivityExpiresAt, - resolveThreadBindingMaxAgeExpiresAt, - resolveThreadBindingMaxAgeMs, searchMessagesDiscord, sendDiscordComponentMessage, sendMessageDiscord, @@ -86,15 +74,11 @@ export { sendTypingDiscord, sendVoiceMessageDiscord, setChannelPermissionDiscord, - setThreadBindingIdleTimeoutBySessionKey, - setThreadBindingMaxAgeBySessionKey, timeoutMemberDiscord, - unbindThreadBindingsBySessionKey, unpinMessageDiscord, uploadEmojiDiscord, uploadStickerDiscord, } from "../../../extensions/discord/runtime-api.js"; -export { normalizeExplicitDiscordSessionKey } from "../../../extensions/discord/session-key-api.js"; export { listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, diff --git a/src/plugin-sdk/channel-import-guardrails.test.ts b/src/plugin-sdk/channel-import-guardrails.test.ts index b5580c8b906..ca550e9c83a 100644 --- a/src/plugin-sdk/channel-import-guardrails.test.ts +++ b/src/plugin-sdk/channel-import-guardrails.test.ts @@ -352,6 +352,22 @@ function expectNoSiblingExtensionPrivateSrcImports(file: string, imports: string } describe("channel import guardrails", () => { + it("keeps Discord threading 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(?:ThreadBindingManager|ThreadBindingRecord|ThreadBindingTargetKind)\b/, + ); + expect(bridgeImports).not.toMatch( + /\b(?:autoBindSpawnedDiscordSubagent|getThreadBindingManager|listThreadBindingsBySessionKey|resolveThreadBindingIdleTimeoutMs|resolveThreadBindingInactivityExpiresAt|resolveThreadBindingMaxAgeExpiresAt|resolveThreadBindingMaxAgeMs|setThreadBindingIdleTimeoutBySessionKey|setThreadBindingMaxAgeBySessionKey|unbindThreadBindingsBySessionKey)\b/, + ); + expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/runtime-api\.js";/); + expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/session-key-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 063717815cb..ec1abd7bd0b 100644 --- a/src/plugin-sdk/discord.ts +++ b/src/plugin-sdk/discord.ts @@ -1,12 +1,27 @@ +import type { + ThreadBindingManager, + ThreadBindingRecord, + ThreadBindingTargetKind, +} from "../../extensions/discord/runtime-api.js"; +import { + autoBindSpawnedDiscordSubagent, + getThreadBindingManager, + listThreadBindingsBySessionKey, + resolveThreadBindingIdleTimeoutMs, + resolveThreadBindingInactivityExpiresAt, + resolveThreadBindingMaxAgeExpiresAt, + resolveThreadBindingMaxAgeMs, + setThreadBindingIdleTimeoutBySessionKey, + setThreadBindingMaxAgeBySessionKey, + unbindThreadBindingsBySessionKey, +} from "../../extensions/discord/runtime-api.js"; +import { normalizeExplicitDiscordSessionKey } from "../../extensions/discord/session-key-api.js"; import type { DiscordPluralKitConfig, DiscordSendComponents, DiscordSendEmbeds, InspectedDiscordAccount, ResolvedDiscordAccount, - ThreadBindingManager, - ThreadBindingRecord, - ThreadBindingTargetKind, } from "../channels/discord/plugin-sdk-bridge.js"; import { collectDiscordStatusIssues, @@ -25,7 +40,6 @@ import { import { addRoleDiscord, auditDiscordChannelPermissions, - autoBindSpawnedDiscordSubagent, banMemberDiscord, collectDiscordAuditChannelIds, createChannelDiscord, @@ -47,7 +61,6 @@ import { fetchVoiceStatusDiscord, getGateway, getPresence, - getThreadBindingManager, hasAnyGuildPermissionDiscord, kickMemberDiscord, listDiscordDirectoryGroupsLive, @@ -56,7 +69,6 @@ import { listGuildEmojisDiscord, listPinsDiscord, listScheduledEventsDiscord, - listThreadBindingsBySessionKey, listThreadsDiscord, monitorDiscordProvider, moveChannelDiscord, @@ -70,10 +82,6 @@ import { removeRoleDiscord, resolveDiscordChannelAllowlist, resolveDiscordUserAllowlist, - resolveThreadBindingIdleTimeoutMs, - resolveThreadBindingInactivityExpiresAt, - resolveThreadBindingMaxAgeExpiresAt, - resolveThreadBindingMaxAgeMs, searchMessagesDiscord, sendDiscordComponentMessage, sendMessageDiscord, @@ -82,16 +90,12 @@ import { sendTypingDiscord, sendVoiceMessageDiscord, setChannelPermissionDiscord, - setThreadBindingIdleTimeoutBySessionKey, - setThreadBindingMaxAgeBySessionKey, timeoutMemberDiscord, - unbindThreadBindingsBySessionKey, unpinMessageDiscord, uploadEmojiDiscord, uploadStickerDiscord, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, - normalizeExplicitDiscordSessionKey, } 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 ec0f4cb8d79..8de2d6d1d4c 100644 --- a/src/plugin-sdk/subpaths.test.ts +++ b/src/plugin-sdk/subpaths.test.ts @@ -266,6 +266,9 @@ describe("plugin-sdk subpath exports", () => { it("exports Discord helpers", () => { expect(typeof discordSdk.buildChannelConfigSchema).toBe("function"); expect(typeof discordSdk.DiscordConfigSchema).toBe("object"); + expect(typeof discordSdk.getThreadBindingManager).toBe("function"); + expect(typeof discordSdk.listThreadBindingsBySessionKey).toBe("function"); + expect(typeof discordSdk.normalizeExplicitDiscordSessionKey).toBe("function"); expect(typeof discordSdk.projectCredentialSnapshotFields).toBe("function"); expect("resolveDiscordAccount" in asExports(discordSdk)).toBe(false); });