refactor: migrate discord actions ownership

This commit is contained in:
Tak Hoffman 2026-03-18 14:53:30 -05:00
parent d4513b96f9
commit 2ae1dcf32b
No known key found for this signature in database
4 changed files with 48 additions and 66 deletions

View File

@ -8,13 +8,11 @@ export type {
export { export {
collectDiscordStatusIssues, collectDiscordStatusIssues,
createDiscordActionGate,
inspectDiscordAccount, inspectDiscordAccount,
listDiscordAccountIds, listDiscordAccountIds,
looksLikeDiscordTargetId, looksLikeDiscordTargetId,
normalizeDiscordMessagingTarget, normalizeDiscordMessagingTarget,
normalizeDiscordOutboundTarget, normalizeDiscordOutboundTarget,
readDiscordComponentSpec,
resolveDiscordAccount, resolveDiscordAccount,
resolveDefaultDiscordAccountId, resolveDefaultDiscordAccountId,
resolveDiscordChannelId, resolveDiscordChannelId,
@ -22,26 +20,9 @@ export {
resolveDiscordGroupToolPolicy, resolveDiscordGroupToolPolicy,
} from "../../../extensions/discord/api.js"; } from "../../../extensions/discord/api.js";
export { export {
addRoleDiscord,
auditDiscordChannelPermissions,
banMemberDiscord,
collectDiscordAuditChannelIds,
createChannelDiscord,
createScheduledEventDiscord,
createThreadDiscord,
deleteChannelDiscord,
deleteMessageDiscord,
DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS,
DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS,
discordMessageActions,
editChannelDiscord,
editMessageDiscord,
fetchChannelInfoDiscord, fetchChannelInfoDiscord,
fetchChannelPermissionsDiscord,
fetchMemberInfoDiscord,
fetchMessageDiscord,
fetchReactionsDiscord,
fetchRoleInfoDiscord,
fetchVoiceStatusDiscord, fetchVoiceStatusDiscord,
getGateway, getGateway,
getPresence, getPresence,
@ -53,25 +34,11 @@ export {
listScheduledEventsDiscord, listScheduledEventsDiscord,
listThreadsDiscord, listThreadsDiscord,
monitorDiscordProvider, monitorDiscordProvider,
moveChannelDiscord,
pinMessageDiscord,
probeDiscord, probeDiscord,
reactMessageDiscord,
readMessagesDiscord, readMessagesDiscord,
removeChannelPermissionDiscord,
removeOwnReactionsDiscord,
removeReactionDiscord,
removeRoleDiscord,
searchMessagesDiscord, searchMessagesDiscord,
sendDiscordComponentMessage,
sendMessageDiscord, sendMessageDiscord,
sendPollDiscord,
sendStickerDiscord,
sendTypingDiscord, sendTypingDiscord,
sendVoiceMessageDiscord, sendVoiceMessageDiscord,
setChannelPermissionDiscord,
timeoutMemberDiscord,
unpinMessageDiscord, unpinMessageDiscord,
uploadEmojiDiscord,
uploadStickerDiscord,
} from "../../../extensions/discord/runtime-api.js"; } from "../../../extensions/discord/runtime-api.js";

View File

@ -381,6 +381,19 @@ describe("channel import guardrails", () => {
expect(text).toMatch(/from\s+"..\/..\/extensions\/discord\/runtime-api\.js";/); 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", () => { it("keeps channel helper modules off their own SDK barrels", () => {
for (const source of SAME_CHANNEL_SDK_GUARDS) { for (const source of SAME_CHANNEL_SDK_GUARDS) {
const text = readSource(source.path); const text = readSource(source.path);

View File

@ -1,6 +1,8 @@
import { import {
createDiscordActionGate,
listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryGroupsFromConfig,
listDiscordDirectoryPeersFromConfig, listDiscordDirectoryPeersFromConfig,
readDiscordComponentSpec,
} from "../../extensions/discord/api.js"; } from "../../extensions/discord/api.js";
import type { import type {
ThreadBindingManager, ThreadBindingManager,
@ -8,20 +10,51 @@ import type {
ThreadBindingTargetKind, ThreadBindingTargetKind,
} from "../../extensions/discord/runtime-api.js"; } from "../../extensions/discord/runtime-api.js";
import { import {
addRoleDiscord,
auditDiscordChannelPermissions,
autoBindSpawnedDiscordSubagent, autoBindSpawnedDiscordSubagent,
banMemberDiscord,
collectDiscordAuditChannelIds,
createChannelDiscord,
createScheduledEventDiscord,
createThreadDiscord,
deleteChannelDiscord,
deleteMessageDiscord,
discordMessageActions,
editChannelDiscord,
editMessageDiscord,
fetchChannelPermissionsDiscord,
fetchMemberInfoDiscord,
fetchMessageDiscord,
fetchReactionsDiscord,
fetchRoleInfoDiscord,
getThreadBindingManager, getThreadBindingManager,
listDiscordDirectoryGroupsLive, listDiscordDirectoryGroupsLive,
listDiscordDirectoryPeersLive, listDiscordDirectoryPeersLive,
listThreadBindingsBySessionKey, listThreadBindingsBySessionKey,
moveChannelDiscord,
pinMessageDiscord,
reactMessageDiscord,
removeChannelPermissionDiscord,
removeOwnReactionsDiscord,
removeReactionDiscord,
removeRoleDiscord,
resolveDiscordChannelAllowlist, resolveDiscordChannelAllowlist,
resolveDiscordUserAllowlist, resolveDiscordUserAllowlist,
resolveThreadBindingIdleTimeoutMs, resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingInactivityExpiresAt, resolveThreadBindingInactivityExpiresAt,
resolveThreadBindingMaxAgeExpiresAt, resolveThreadBindingMaxAgeExpiresAt,
resolveThreadBindingMaxAgeMs, resolveThreadBindingMaxAgeMs,
sendDiscordComponentMessage,
sendPollDiscord,
sendStickerDiscord,
setThreadBindingIdleTimeoutBySessionKey, setThreadBindingIdleTimeoutBySessionKey,
setThreadBindingMaxAgeBySessionKey, setThreadBindingMaxAgeBySessionKey,
setChannelPermissionDiscord,
timeoutMemberDiscord,
unbindThreadBindingsBySessionKey, unbindThreadBindingsBySessionKey,
uploadEmojiDiscord,
uploadStickerDiscord,
} from "../../extensions/discord/runtime-api.js"; } from "../../extensions/discord/runtime-api.js";
import { normalizeExplicitDiscordSessionKey } from "../../extensions/discord/session-key-api.js"; import { normalizeExplicitDiscordSessionKey } from "../../extensions/discord/session-key-api.js";
import type { import type {
@ -33,39 +66,20 @@ import type {
} from "../channels/discord/plugin-sdk-bridge.js"; } from "../channels/discord/plugin-sdk-bridge.js";
import { import {
collectDiscordStatusIssues, collectDiscordStatusIssues,
createDiscordActionGate,
inspectDiscordAccount, inspectDiscordAccount,
listDiscordAccountIds, listDiscordAccountIds,
looksLikeDiscordTargetId, looksLikeDiscordTargetId,
normalizeDiscordMessagingTarget, normalizeDiscordMessagingTarget,
normalizeDiscordOutboundTarget, normalizeDiscordOutboundTarget,
readDiscordComponentSpec,
resolveDefaultDiscordAccountId, resolveDefaultDiscordAccountId,
resolveDiscordChannelId, resolveDiscordChannelId,
resolveDiscordGroupRequireMention, resolveDiscordGroupRequireMention,
resolveDiscordGroupToolPolicy, resolveDiscordGroupToolPolicy,
} from "../channels/discord/plugin-sdk-bridge.js"; } from "../channels/discord/plugin-sdk-bridge.js";
import { import {
addRoleDiscord,
auditDiscordChannelPermissions,
banMemberDiscord,
collectDiscordAuditChannelIds,
createChannelDiscord,
createScheduledEventDiscord,
createThreadDiscord,
deleteChannelDiscord,
deleteMessageDiscord,
DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS,
DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS,
discordMessageActions,
editChannelDiscord,
editMessageDiscord,
fetchChannelInfoDiscord, fetchChannelInfoDiscord,
fetchChannelPermissionsDiscord,
fetchMemberInfoDiscord,
fetchMessageDiscord,
fetchReactionsDiscord,
fetchRoleInfoDiscord,
fetchVoiceStatusDiscord, fetchVoiceStatusDiscord,
getGateway, getGateway,
getPresence, getPresence,
@ -77,27 +91,13 @@ import {
listScheduledEventsDiscord, listScheduledEventsDiscord,
listThreadsDiscord, listThreadsDiscord,
monitorDiscordProvider, monitorDiscordProvider,
moveChannelDiscord,
pinMessageDiscord,
probeDiscord, probeDiscord,
reactMessageDiscord,
readMessagesDiscord, readMessagesDiscord,
removeChannelPermissionDiscord,
removeOwnReactionsDiscord,
removeReactionDiscord,
removeRoleDiscord,
searchMessagesDiscord, searchMessagesDiscord,
sendDiscordComponentMessage,
sendMessageDiscord, sendMessageDiscord,
sendPollDiscord,
sendStickerDiscord,
sendTypingDiscord, sendTypingDiscord,
sendVoiceMessageDiscord, sendVoiceMessageDiscord,
setChannelPermissionDiscord,
timeoutMemberDiscord,
unpinMessageDiscord, unpinMessageDiscord,
uploadEmojiDiscord,
uploadStickerDiscord,
} from "../channels/discord/plugin-sdk-bridge.js"; } from "../channels/discord/plugin-sdk-bridge.js";
export type { export type {

View File

@ -265,7 +265,9 @@ describe("plugin-sdk subpath exports", () => {
it("exports Discord helpers", () => { it("exports Discord helpers", () => {
expect(typeof discordSdk.buildChannelConfigSchema).toBe("function"); expect(typeof discordSdk.buildChannelConfigSchema).toBe("function");
expect(typeof discordSdk.createDiscordActionGate).toBe("function");
expect(typeof discordSdk.DiscordConfigSchema).toBe("object"); expect(typeof discordSdk.DiscordConfigSchema).toBe("object");
expect(typeof discordSdk.discordMessageActions).toBe("object");
expect(typeof discordSdk.listDiscordDirectoryGroupsFromConfig).toBe("function"); expect(typeof discordSdk.listDiscordDirectoryGroupsFromConfig).toBe("function");
expect(typeof discordSdk.listDiscordDirectoryPeersFromConfig).toBe("function"); expect(typeof discordSdk.listDiscordDirectoryPeersFromConfig).toBe("function");
expect(typeof discordSdk.listDiscordDirectoryGroupsLive).toBe("function"); expect(typeof discordSdk.listDiscordDirectoryGroupsLive).toBe("function");