From 75845606c4b905b93c00f083c0edb94dccb05594 Mon Sep 17 00:00:00 2001 From: jaydenfyi <213395523+jaydenfyi@users.noreply.github.com> Date: Sun, 25 Jan 2026 15:46:25 +0800 Subject: [PATCH] remove comments + fromat --- .claude/settings.local.json | 3 ++- extensions/twitch/README.md | 10 +++++----- extensions/twitch/src/access-control.ts | 7 ------- extensions/twitch/src/monitor.ts | 12 ------------ extensions/twitch/src/outbound.ts | 8 -------- extensions/twitch/src/probe.ts | 8 -------- extensions/twitch/src/resolver.ts | 8 -------- extensions/twitch/src/send.ts | 4 ---- extensions/twitch/src/status.ts | 17 ++--------------- extensions/twitch/src/twitch-client.test.ts | 3 ++- extensions/twitch/src/twitch-client.ts | 12 ------------ 11 files changed, 11 insertions(+), 81 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 54188b2fd..130c5188e 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,7 +1,8 @@ { "permissions": { "allow": [ - "Bash(pnpm vitest:*)" + "Bash(pnpm vitest:*)", + "Bash(git diff:*)" ] } } diff --git a/extensions/twitch/README.md b/extensions/twitch/README.md index 73789b60b..377da572a 100644 --- a/extensions/twitch/README.md +++ b/extensions/twitch/README.md @@ -30,11 +30,11 @@ Minimal config: username: "clawdbot", token: "oauth:abc123...", clientId: "your_client_id_here", - channel: "vevisk" - } - } - } - } + channel: "vevisk", + }, + }, + }, + }, } ``` diff --git a/extensions/twitch/src/access-control.ts b/extensions/twitch/src/access-control.ts index 49e899151..005dfbdf6 100644 --- a/extensions/twitch/src/access-control.ts +++ b/extensions/twitch/src/access-control.ts @@ -38,7 +38,6 @@ export function checkTwitchAccessControl(params: { }): TwitchAccessControlResult { const { message, account, botUsername } = params; - // Check mention requirement first if (account.requireMention) { const mentions = extractMentions(message.message); if (!mentions.includes(botUsername.toLowerCase())) { @@ -49,7 +48,6 @@ export function checkTwitchAccessControl(params: { } } - // Check allowlist (by user ID) if (account.allowFrom && account.allowFrom.length > 0) { const allowFrom = account.allowFrom; const senderId = message.userId; @@ -61,7 +59,6 @@ export function checkTwitchAccessControl(params: { }; } - // Check if sender is in allowlist if (!allowFrom.includes(senderId)) { return { allowed: false, @@ -69,7 +66,6 @@ export function checkTwitchAccessControl(params: { }; } - // Sender is in allowlist, no need to check role restrictions return { allowed: true, matchKey: senderId, @@ -77,7 +73,6 @@ export function checkTwitchAccessControl(params: { }; } - // Check role-based restrictions if (account.allowedRoles && account.allowedRoles.length > 0) { const allowedRoles = account.allowedRoles; @@ -90,7 +85,6 @@ export function checkTwitchAccessControl(params: { }; } - // Check if sender has any of the allowed roles const hasAllowedRole = checkSenderRoles({ message, allowedRoles, @@ -110,7 +104,6 @@ export function checkTwitchAccessControl(params: { }; } - // No restrictions configured - allow everyone return { allowed: true, }; diff --git a/extensions/twitch/src/monitor.ts b/extensions/twitch/src/monitor.ts index 97672c0e0..081503bc5 100644 --- a/extensions/twitch/src/monitor.ts +++ b/extensions/twitch/src/monitor.ts @@ -45,7 +45,6 @@ async function processTwitchMessage(params: { }): Promise { const { message, account, accountId, config, runtime, core, statusSink } = params; - // Resolve route for this message const route = core.channel.routing.resolveAgentRoute({ cfg: config as Parameters[0]["cfg"], channel: "twitch", @@ -56,7 +55,6 @@ async function processTwitchMessage(params: { }, }); - // Build message body const rawBody = message.message; const body = core.channel.reply.formatAgentEnvelope({ channel: "Twitch", @@ -68,7 +66,6 @@ async function processTwitchMessage(params: { body: rawBody, }); - // Build context payload const ctxPayload = core.channel.reply.finalizeInboundContext({ Body: body, RawBody: rawBody, @@ -89,7 +86,6 @@ async function processTwitchMessage(params: { OriginatingTo: `twitch:channel:${message.channel}`, }); - // Record session const storePath = core.channel.session.resolveStorePath( (config as Parameters[0]["cfg"])?.session?.store, { agentId: route.agentId }, @@ -103,14 +99,12 @@ async function processTwitchMessage(params: { }, }); - // Resolve markdown table mode const tableMode = core.channel.text.resolveMarkdownTableMode({ cfg: config as Parameters[0]["cfg"], channel: "twitch", accountId, }); - // Dispatch reply await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({ ctx: ctxPayload, cfg: config as Parameters< @@ -191,7 +185,6 @@ export async function monitorTwitchProvider( const core = getTwitchRuntime(); let stopped = false; - // Create logger for client manager const logger = { info: (msg: string) => runtime.log?.(`[twitch] ${msg}`), warn: (msg: string) => runtime.log?.(`[twitch] ${msg}`), @@ -199,10 +192,8 @@ export async function monitorTwitchProvider( debug: (msg: string) => runtime.log?.(`[twitch] ${msg}`), }; - // Get or create client manager const clientManager = getOrCreateClientManager(accountId, logger); - // Establish connection try { await clientManager.getClient( account, @@ -216,7 +207,6 @@ export async function monitorTwitchProvider( throw error; } - // Register message handler const unregisterHandler = clientManager.onMessage(account, async (message) => { if (stopped) return; @@ -256,13 +246,11 @@ export async function monitorTwitchProvider( } }); - // Stop function const stop = () => { stopped = true; unregisterHandler(); }; - // Handle abort signal abortSignal.addEventListener("abort", stop, { once: true }); return { stop }; diff --git a/extensions/twitch/src/outbound.ts b/extensions/twitch/src/outbound.ts index 892cee621..70a48a669 100644 --- a/extensions/twitch/src/outbound.ts +++ b/extensions/twitch/src/outbound.ts @@ -108,12 +108,10 @@ export const twitchOutbound: ChannelOutboundAdapter = { sendText: async (params: ChannelOutboundContext): Promise => { const { cfg, to, text, accountId, signal } = params; - // Check for abort signal if (signal?.aborted) { throw new Error("Outbound delivery aborted"); } - // Resolve account const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID; const account = getAccountConfig(cfg, resolvedAccountId); if (!account) { @@ -124,19 +122,16 @@ export const twitchOutbound: ChannelOutboundAdapter = { ); } - // Get channel (support target parameter override) const channel = to || account.channel; if (!channel) { throw new Error("No channel specified and no default channel in account config"); } - // Get plugin config for markdown stripping const pluginCfg = parsePluginConfig( // biome-ignore lint/suspicious/noExplicitAny: pluginConfig is not part of CoreConfig (cfg as any).pluginConfig ?? {}, ); - // Send message const result = await sendMessageTwitchInternal( normalizeTwitchChannel(channel), text, @@ -179,15 +174,12 @@ export const twitchOutbound: ChannelOutboundAdapter = { sendMedia: async (params: ChannelOutboundContext): Promise => { const { text, mediaUrl, signal } = params; - // Check for abort signal if (signal?.aborted) { throw new Error("Outbound delivery aborted"); } - // Combine text and media URL const message = mediaUrl ? `${text || ""} ${mediaUrl}`.trim() : text; - // Delegate to sendText if (!twitchOutbound.sendText) { throw new Error("sendText not implemented"); } diff --git a/extensions/twitch/src/probe.ts b/extensions/twitch/src/probe.ts index 2a6ab9394..90e34826b 100644 --- a/extensions/twitch/src/probe.ts +++ b/extensions/twitch/src/probe.ts @@ -41,10 +41,8 @@ export async function probeTwitch( let client: ChatClient | undefined; try { - // Create auth provider with the token const authProvider = new StaticAuthProvider(account.clientId ?? "", rawToken); - // Create chat client client = new ChatClient({ authProvider, }); @@ -59,7 +57,6 @@ export async function probeTwitch( const cleanup = () => { if (settled) return; settled = true; - // Remove all listeners connectListener?.unbind(); disconnectListener?.unbind(); authFailListener?.unbind(); @@ -84,20 +81,16 @@ export async function probeTwitch( }); }); - // Create timeout promise const timeout = new Promise((_, reject) => { setTimeout(() => reject(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs); }); - // Set up listeners BEFORE connecting, then race against timeout client.connect(); await Promise.race([connectionPromise, timeout]); - // Clean up connection before returning client.quit(); client = undefined; - // If we got here, connection was successful return { ok: true, connected: true, @@ -114,7 +107,6 @@ export async function probeTwitch( elapsedMs: Date.now() - started, }; } finally { - // Always clean up the client if (client) { try { client.quit(); diff --git a/extensions/twitch/src/resolver.ts b/extensions/twitch/src/resolver.ts index e257f6937..5e3a66e95 100644 --- a/extensions/twitch/src/resolver.ts +++ b/extensions/twitch/src/resolver.ts @@ -51,7 +51,6 @@ export async function resolveTwitchTargets( ): Promise { const log = createLogger(logger); - // Validate credentials if (!account.clientId || !account.token) { log.error("Missing Twitch client ID or token"); return inputs.map((input) => ({ @@ -61,20 +60,16 @@ export async function resolveTwitchTargets( })); } - // Normalize token - strip oauth: prefix if present const normalizedToken = normalizeToken(account.token); - // Create auth provider and API client const authProvider = new StaticAuthProvider(account.clientId, normalizedToken); const apiClient = new ApiClient({ authProvider }); const results: ChannelResolveResult[] = []; - // Process each input for (const input of inputs) { const normalized = normalizeUsername(input); - // Skip empty inputs if (!normalized) { results.push({ input, @@ -84,12 +79,10 @@ export async function resolveTwitchTargets( continue; } - // If it looks like a user ID (numeric), validate it exists const looksLikeUserId = /^\d+$/.test(normalized); try { if (looksLikeUserId) { - // Validate user ID by fetching the user const user = await apiClient.users.getUserById(normalized); if (user) { @@ -109,7 +102,6 @@ export async function resolveTwitchTargets( log.warn(`User ID ${normalized} not found`); } } else { - // Resolve username to user ID const user = await apiClient.users.getUserByName(normalized); if (user) { diff --git a/extensions/twitch/src/send.ts b/extensions/twitch/src/send.ts index 77c3f5808..25b720150 100644 --- a/extensions/twitch/src/send.ts +++ b/extensions/twitch/src/send.ts @@ -56,7 +56,6 @@ export async function sendMessageTwitchInternal( stripMarkdown: boolean = true, logger: Console = console, ): Promise { - // Resolve account const account = getAccountConfig(cfg, accountId); if (!account) { const availableIds = Object.keys(cfg.channels?.twitch?.accounts ?? {}); @@ -78,7 +77,6 @@ export async function sendMessageTwitchInternal( }; } - // Normalize channel (parameter override, then account channel) const normalizedChannel = channel || account.channel; if (!normalizedChannel) { return { @@ -88,7 +86,6 @@ export async function sendMessageTwitchInternal( }; } - // Strip markdown if enabled const cleanedText = stripMarkdown ? stripMarkdownForTwitch(text) : text; if (!cleanedText) { return { @@ -97,7 +94,6 @@ export async function sendMessageTwitchInternal( }; } - // Get client manager from registry const clientManager = getRegistryClientManager(accountId); if (!clientManager) { return { diff --git a/extensions/twitch/src/status.ts b/extensions/twitch/src/status.ts index 8164c431d..118b48975 100644 --- a/extensions/twitch/src/status.ts +++ b/extensions/twitch/src/status.ts @@ -35,10 +35,8 @@ export function collectTwitchStatusIssues( for (const entry of accounts) { const accountId = entry.accountId; - // Skip if not a Twitch account if (!accountId) continue; - // Get full account config if available let account: ReturnType | null = null; let cfg: Parameters[0] | undefined; if (getCfg) { @@ -52,7 +50,6 @@ export function collectTwitchStatusIssues( } } - // Check 1: Account not configured if (!entry.configured) { issues.push({ channel: "twitch", @@ -61,10 +58,9 @@ export function collectTwitchStatusIssues( message: "Twitch account is not properly configured", fix: "Add required fields: username, token, and clientId to your account configuration", }); - continue; // Skip further checks if not configured + continue; } - // Check 2: Account disabled if (entry.enabled === false) { issues.push({ channel: "twitch", @@ -73,10 +69,9 @@ export function collectTwitchStatusIssues( message: "Twitch account is disabled", fix: "Set enabled: true in your account configuration to enable this account", }); - continue; // Skip further checks if disabled + continue; } - // Check 3: Missing clientId (check if username/token present but no clientId) if (account && account.username && account.token && !account.clientId) { issues.push({ channel: "twitch", @@ -87,12 +82,10 @@ export function collectTwitchStatusIssues( }); } - // Checks that require account config const tokenResolution = cfg ? resolveTwitchToken(cfg as Parameters[0], { accountId }) : { token: "", source: "none" }; if (account && isAccountConfigured(account, tokenResolution.token)) { - // Check 4: Token format warning (normalized, but may indicate config issue) if (account.token?.startsWith("oauth:")) { issues.push({ channel: "twitch", @@ -103,7 +96,6 @@ export function collectTwitchStatusIssues( }); } - // Check 5: clientSecret provided without refreshToken if (account.clientSecret && !account.refreshToken) { issues.push({ channel: "twitch", @@ -114,7 +106,6 @@ export function collectTwitchStatusIssues( }); } - // Check 6: Access control warnings if (account.allowFrom && account.allowFrom.length === 0) { issues.push({ channel: "twitch", @@ -125,7 +116,6 @@ export function collectTwitchStatusIssues( }); } - // Check 7: Invalid role combinations if ( account.allowedRoles?.includes("all") && account.allowFrom && @@ -141,7 +131,6 @@ export function collectTwitchStatusIssues( } } - // Check 8: Runtime errors if (entry.lastError) { issues.push({ channel: "twitch", @@ -152,7 +141,6 @@ export function collectTwitchStatusIssues( }); } - // Check 9: Account never connected successfully if ( entry.configured && !entry.running && @@ -169,7 +157,6 @@ export function collectTwitchStatusIssues( }); } - // Check 10: Long-running connection may need reconnection if (entry.running && entry.lastStartAt) { const uptime = Date.now() - entry.lastStartAt; const daysSinceStart = uptime / (1000 * 60 * 60 * 24); diff --git a/extensions/twitch/src/twitch-client.test.ts b/extensions/twitch/src/twitch-client.test.ts index 5361f5a49..43bf712ac 100644 --- a/extensions/twitch/src/twitch-client.test.ts +++ b/extensions/twitch/src/twitch-client.test.ts @@ -21,7 +21,8 @@ const mockQuit = vi.fn(); const mockUnbind = vi.fn(); // Event handler storage for testing -const messageHandlers: Array<(channel: string, user: string, message: string, msg: any) => void> = []; +const messageHandlers: Array<(channel: string, user: string, message: string, msg: any) => void> = + []; const whisperHandlers: Array<(user: string, message: string, msg: any) => void> = []; // Mock functions that track handlers and return unbind objects diff --git a/extensions/twitch/src/twitch-client.ts b/extensions/twitch/src/twitch-client.ts index 5407f86ca..f1d695151 100644 --- a/extensions/twitch/src/twitch-client.ts +++ b/extensions/twitch/src/twitch-client.ts @@ -26,14 +26,11 @@ export class TwitchClientManager { } if (account.clientSecret) { - // Use RefreshingAuthProvider - can handle tokens with or without refresh tokens const authProvider = new RefreshingAuthProvider({ clientId: account.clientId, clientSecret: account.clientSecret, }); - // Use addUserForToken to figure out the user ID from the token - // This works whether we have a refresh token or not await authProvider .addUserForToken({ accessToken: normalizedToken, @@ -52,14 +49,12 @@ export class TwitchClientManager { ); }); - // Set up token refresh event listener (only fires if refreshToken is provided) authProvider.onRefresh((userId, token) => { this.logger.info( `[twitch] Access token refreshed for user ${userId} (expires in ${token.expiresIn ? `${token.expiresIn}s` : "unknown"})`, ); }); - // Set up token refresh failure listener authProvider.onRefreshFailure((userId, error) => { this.logger.error( `[twitch] Failed to refresh access token for user ${userId}: ${error.message}`, @@ -76,7 +71,6 @@ export class TwitchClientManager { return authProvider; } - // Fall back to StaticAuthProvider for backward compatibility (no clientSecret) this.logger.info( `[twitch] Using StaticAuthProvider for ${account.username} (no clientSecret provided)`, ); @@ -98,7 +92,6 @@ export class TwitchClientManager { return existing; } - // Resolve token from config or environment const tokenResolution = resolveTwitchToken(cfg, { accountId, }); @@ -119,13 +112,10 @@ export class TwitchClientManager { throw new Error("Missing Twitch client ID"); } - // Normalize token - strip oauth: prefix if present (Twurple doesn't need it) const normalizedToken = normalizeToken(tokenResolution.token); - // Create auth provider const authProvider = await this.createAuthProvider(account, normalizedToken); - // Create chat client const client = new ChatClient({ authProvider, channels: [account.channel], @@ -160,10 +150,8 @@ export class TwitchClientManager { }, }); - // Set up event handlers this.setupClientHandlers(client, account); - // Connect client.connect(); this.clients.set(key, client);