From 4f0771f67bdcbe59dac5be781b4809dc194aff8f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 18 Jan 2026 00:59:23 +0000 Subject: [PATCH] fix(channels): clean up discord resolve typing --- src/channels/plugins/onboarding/discord.ts | 17 +++++++++----- src/discord/monitor/provider.ts | 11 ++++----- src/discord/resolve-channels.ts | 27 ++++++++++++++-------- src/discord/resolve-users.ts | 5 ++-- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/channels/plugins/onboarding/discord.ts b/src/channels/plugins/onboarding/discord.ts index ccaf07e2d..29818ac51 100644 --- a/src/channels/plugins/onboarding/discord.ts +++ b/src/channels/plugins/onboarding/discord.ts @@ -1,12 +1,16 @@ import type { ClawdbotConfig } from "../../../config/config.js"; import type { DmPolicy } from "../../../config/types.js"; +import type { DiscordGuildEntry } from "../../../config/types.discord.js"; import { listDiscordAccountIds, resolveDefaultDiscordAccountId, resolveDiscordAccount, } from "../../../discord/accounts.js"; import { normalizeDiscordSlug } from "../../../discord/monitor/allow-list.js"; -import { resolveDiscordChannelAllowlist } from "../../../discord/resolve-channels.js"; +import { + resolveDiscordChannelAllowlist, + type DiscordChannelResolution, +} from "../../../discord/resolve-channels.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js"; import { formatDocsLink } from "../../../terminal/links.js"; import type { WizardPrompter } from "../../../wizard/prompts.js"; @@ -99,14 +103,12 @@ function setDiscordGuildChannelAllowlist( accountId === DEFAULT_ACCOUNT_ID ? (cfg.channels?.discord?.guilds ?? {}) : (cfg.channels?.discord?.accounts?.[accountId]?.guilds ?? {}); - const guilds: Record }> = { - ...baseGuilds, - }; + const guilds: Record = { ...baseGuilds }; for (const entry of entries) { const guildKey = entry.guildKey || "*"; const existing = guilds[guildKey] ?? {}; if (entry.channelKey) { - const channels = { ...(existing.channels ?? {}) }; + const channels = { ...existing.channels }; channels[entry.channelKey] = { allow: true }; guilds[guildKey] = { ...existing, channels }; } else { @@ -298,7 +300,10 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = { cfg: next, accountId: discordAccountId, }); - let resolved = accessConfig.entries.map((input) => ({ input, resolved: false })); + let resolved: DiscordChannelResolution[] = accessConfig.entries.map((input) => ({ + input, + resolved: false, + })); if (accountWithTokens.token && accessConfig.entries.length > 0) { try { resolved = await resolveDiscordChannelAllowlist({ diff --git a/src/discord/monitor/provider.ts b/src/discord/monitor/provider.ts index e39116d9a..4418d896e 100644 --- a/src/discord/monitor/provider.ts +++ b/src/discord/monitor/provider.ts @@ -156,7 +156,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { token, entries: entries.map((entry) => entry.input), }); - const nextGuilds = { ...(guildEntries ?? {}) }; + const nextGuilds = { ...guildEntries }; const mapping: string[] = []; const unresolved: string[] = []; for (const entry of resolved) { @@ -173,10 +173,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { : `${entry.input}→${entry.guildId}`, ); const existing = nextGuilds[entry.guildId] ?? {}; - const mergedChannels = { - ...(sourceGuild.channels ?? {}), - ...(existing.channels ?? {}), - }; + const mergedChannels = { ...sourceGuild.channels, ...existing.channels }; const mergedGuild = { ...sourceGuild, ...existing, channels: mergedChannels }; nextGuilds[entry.guildId] = mergedGuild; if (source.channelKey && entry.channelId) { @@ -188,7 +185,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { ...mergedChannels, [entry.channelId]: { ...sourceChannel, - ...(mergedChannels?.[entry.channelId] ?? {}), + ...mergedChannels?.[entry.channelId], }, }, }; @@ -266,7 +263,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { .filter((entry) => !entry.resolved) .map((entry) => entry.input); - const nextGuilds = { ...(guildEntries ?? {}) }; + const nextGuilds = { ...guildEntries }; for (const [guildKey, guildConfig] of Object.entries(guildEntries ?? {})) { if (!guildConfig || typeof guildConfig !== "object") continue; const nextGuild = { ...guildConfig } as Record; diff --git a/src/discord/resolve-channels.ts b/src/discord/resolve-channels.ts index 05c185701..9c525c7cd 100644 --- a/src/discord/resolve-channels.ts +++ b/src/discord/resolve-channels.ts @@ -100,13 +100,19 @@ async function listGuildChannels( )) as RESTGetAPIGuildChannelsResult; return raw .filter((channel) => Boolean(channel.id) && "name" in channel) - .map((channel) => ({ - id: channel.id, - name: "name" in channel ? channel.name ?? "" : "", - guildId, - type: channel.type, - archived: "thread_metadata" in channel ? channel.thread_metadata?.archived : undefined, - })) + .map((channel) => { + const archived = + "thread_metadata" in channel + ? (channel as { thread_metadata?: { archived?: boolean } }).thread_metadata?.archived + : undefined; + return { + id: channel.id, + name: "name" in channel ? channel.name ?? "" : "", + guildId, + type: channel.type, + archived, + }; + }) .filter((channel) => Boolean(channel.name)); } @@ -231,19 +237,20 @@ export async function resolveDiscordChannelAllowlist(params: { : parsed.guild ? resolveGuildByName(guilds, parsed.guild) : undefined; - if (!guild || !parsed.channel) { + const channelQuery = parsed.channel?.trim(); + if (!guild || !channelQuery) { results.push({ input, resolved: false, guildId: parsed.guildId, guildName: parsed.guild, - channelName: parsed.channel, + channelName: channelQuery ?? parsed.channel, }); continue; } const channels = await getChannels(guild.id); const matches = channels.filter( - (channel) => normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(parsed.channel), + (channel) => normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(channelQuery), ); const match = preferActiveMatch(matches); if (match) { diff --git a/src/discord/resolve-users.ts b/src/discord/resolve-users.ts index a43bf8b56..066ef20f5 100644 --- a/src/discord/resolve-users.ts +++ b/src/discord/resolve-users.ts @@ -127,10 +127,11 @@ export async function resolveDiscordUserAllowlist(params: { continue; } + const guildName = parsed.guildName?.trim(); const guildList = parsed.guildId ? guilds.filter((g) => g.id === parsed.guildId) - : parsed.guildName - ? guilds.filter((g) => g.slug === normalizeDiscordSlug(parsed.guildName)) + : guildName + ? guilds.filter((g) => g.slug === normalizeDiscordSlug(guildName)) : guilds; let best: { member: DiscordMember; guild: DiscordGuildSummary; score: number } | null = null;