From 232c512502eb50df7a6e8901d8a9abbeeb91282c Mon Sep 17 00:00:00 2001 From: George Pickett Date: Wed, 14 Jan 2026 17:10:16 -0800 Subject: [PATCH] Format: apply oxfmt fixes --- src/agents/google-gemini-switch.live.test.ts | 127 +++++++------ src/auto-reply/command-auth.ts | 7 +- src/auto-reply/reply/agent-runner-utils.ts | 2 +- .../reply/session-reset-group.test.ts | 4 +- .../monitor/message-handler.process.ts | 169 +++++++++--------- src/discord/monitor/threading.test.ts | 18 +- src/infra/outbound/deliver.test.ts | 4 +- src/markdown/ir.ts | 17 +- src/markdown/render.ts | 4 +- src/signal/format.test.ts | 20 +-- src/signal/format.ts | 30 ++-- src/telegram/format.ts | 12 +- src/telegram/send.ts | 4 +- src/whatsapp/normalize.test.ts | 18 +- 14 files changed, 202 insertions(+), 234 deletions(-) diff --git a/src/agents/google-gemini-switch.live.test.ts b/src/agents/google-gemini-switch.live.test.ts index 4abc2b0fb..790479036 100644 --- a/src/agents/google-gemini-switch.live.test.ts +++ b/src/agents/google-gemini-switch.live.test.ts @@ -2,82 +2,77 @@ import { completeSimple, getModel } from "@mariozechner/pi-ai"; import { describe, expect, it } from "vitest"; const GEMINI_KEY = process.env.GEMINI_API_KEY ?? ""; -const LIVE = - process.env.GEMINI_LIVE_TEST === "1" || process.env.LIVE === "1"; +const LIVE = process.env.GEMINI_LIVE_TEST === "1" || process.env.LIVE === "1"; const describeLive = LIVE && GEMINI_KEY ? describe : describe.skip; describeLive("gemini live switch", () => { - it( - "handles unsigned tool calls from Antigravity when switching to Gemini 3", - async () => { - const now = Date.now(); - const model = getModel("google", "gemini-3-pro-preview"); + it("handles unsigned tool calls from Antigravity when switching to Gemini 3", async () => { + const now = Date.now(); + const model = getModel("google", "gemini-3-pro-preview"); - const res = await completeSimple( - model, - { - messages: [ - { - role: "user", - content: "Reply with ok.", - timestamp: now, - }, - { - role: "assistant", - content: [ - { - type: "toolCall", - id: "call_1", - name: "bash", - arguments: { command: "ls -la" }, - // No thoughtSignature: simulates Claude via Antigravity. - }, - ], - api: "google-gemini-cli", - provider: "google-antigravity", - model: "claude-sonnet-4-20250514", - usage: { + const res = await completeSimple( + model, + { + messages: [ + { + role: "user", + content: "Reply with ok.", + timestamp: now, + }, + { + role: "assistant", + content: [ + { + type: "toolCall", + id: "call_1", + name: "bash", + arguments: { command: "ls -la" }, + // No thoughtSignature: simulates Claude via Antigravity. + }, + ], + api: "google-gemini-cli", + provider: "google-antigravity", + model: "claude-sonnet-4-20250514", + usage: { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 0, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, - totalTokens: 0, - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - total: 0, - }, - }, - stopReason: "stop", - timestamp: now, - }, - ], - tools: [ - { - name: "bash", - description: "Run shell command", - parameters: { - type: "object", - properties: { - command: { type: "string" }, - }, - required: ["command"], + total: 0, }, }, - ], - }, - { - apiKey: GEMINI_KEY, - reasoning: "low", - maxTokens: 128, - }, - ); + stopReason: "stop", + timestamp: now, + }, + ], + tools: [ + { + name: "bash", + description: "Run shell command", + parameters: { + type: "object", + properties: { + command: { type: "string" }, + }, + required: ["command"], + }, + }, + ], + }, + { + apiKey: GEMINI_KEY, + reasoning: "low", + maxTokens: 128, + }, + ); - expect(res.stopReason).not.toBe("error"); - }, - 20000, - ); + expect(res.stopReason).not.toBe("error"); + }, 20000); }); diff --git a/src/auto-reply/command-auth.ts b/src/auto-reply/command-auth.ts index 6c8fccb94..de4b6086e 100644 --- a/src/auto-reply/command-auth.ts +++ b/src/auto-reply/command-auth.ts @@ -116,7 +116,12 @@ export function resolveCommandAuthorization(params: { const ownerCandidates = allowAll ? [] : allowFromList.filter((entry) => entry !== "*"); if (!allowAll && ownerCandidates.length === 0 && to) { - const normalizedTo = normalizeAllowFromEntry({ dock, cfg, accountId: ctx.AccountId, value: to }); + const normalizedTo = normalizeAllowFromEntry({ + dock, + cfg, + accountId: ctx.AccountId, + value: to, + }); if (normalizedTo) ownerCandidates.push(normalizedTo); } const ownerList = ownerCandidates; diff --git a/src/auto-reply/reply/agent-runner-utils.ts b/src/auto-reply/reply/agent-runner-utils.ts index 89a8ca2a8..f5a802a77 100644 --- a/src/auto-reply/reply/agent-runner-utils.ts +++ b/src/auto-reply/reply/agent-runner-utils.ts @@ -26,7 +26,7 @@ export function buildThreadingToolContext(params: { const dock = getChannelDock(provider); if (!dock?.threading?.buildToolContext) return {}; // WhatsApp context isolation keys off conversation id, not the bot's own number. - const threadingTo = provider === "whatsapp" ? sessionCtx.From ?? sessionCtx.To : sessionCtx.To; + const threadingTo = provider === "whatsapp" ? (sessionCtx.From ?? sessionCtx.To) : sessionCtx.To; return ( dock.threading.buildToolContext({ cfg: config, diff --git a/src/auto-reply/reply/session-reset-group.test.ts b/src/auto-reply/reply/session-reset-group.test.ts index 049928ec8..7cb89b1b1 100644 --- a/src/auto-reply/reply/session-reset-group.test.ts +++ b/src/auto-reply/reply/session-reset-group.test.ts @@ -9,9 +9,7 @@ import { initSessionState } from "./session.js"; describe("initSessionState reset triggers in WhatsApp groups", () => { async function createStorePath(prefix: string): Promise { - const root = await fs.mkdtemp( - path.join(os.tmpdir(), prefix), - ); + const root = await fs.mkdtemp(path.join(os.tmpdir(), prefix)); return path.join(root, "sessions.json"); } diff --git a/src/discord/monitor/message-handler.process.ts b/src/discord/monitor/message-handler.process.ts index cff059f9f..b4862edba 100644 --- a/src/discord/monitor/message-handler.process.ts +++ b/src/discord/monitor/message-handler.process.ts @@ -24,10 +24,7 @@ import { } from "./message-utils.js"; import { buildDirectLabel, buildGuildLabel, resolveReplyContext } from "./reply-context.js"; import { deliverDiscordReply } from "./reply-delivery.js"; -import { - resolveDiscordAutoThreadReplyPlan, - resolveDiscordThreadStarter, -} from "./threading.js"; +import { resolveDiscordAutoThreadReplyPlan, resolveDiscordThreadStarter } from "./threading.js"; import { sendTyping } from "./typing.js"; export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) { @@ -191,72 +188,72 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) peer: { kind: "channel", id: threadParentId }, }); } - } - const mediaPayload = buildDiscordMediaPayload(mediaList); - const threadKeys = resolveThreadSessionKeys({ - baseSessionKey, - threadId: threadChannel ? message.channelId : undefined, - parentSessionKey, - useSuffix: false, - }); - const replyPlan = await resolveDiscordAutoThreadReplyPlan({ - client, - message, - isGuildMessage, - channelConfig, - threadChannel, - baseText: baseText ?? "", - combinedBody, - replyToMode, - agentId: route.agentId, - channel: route.channel, - }); - const deliverTarget = replyPlan.deliverTarget; - const replyTarget = replyPlan.replyTarget; - const replyReference = replyPlan.replyReference; - const autoThreadContext = replyPlan.autoThreadContext; + } + const mediaPayload = buildDiscordMediaPayload(mediaList); + const threadKeys = resolveThreadSessionKeys({ + baseSessionKey, + threadId: threadChannel ? message.channelId : undefined, + parentSessionKey, + useSuffix: false, + }); + const replyPlan = await resolveDiscordAutoThreadReplyPlan({ + client, + message, + isGuildMessage, + channelConfig, + threadChannel, + baseText: baseText ?? "", + combinedBody, + replyToMode, + agentId: route.agentId, + channel: route.channel, + }); + const deliverTarget = replyPlan.deliverTarget; + const replyTarget = replyPlan.replyTarget; + const replyReference = replyPlan.replyReference; + const autoThreadContext = replyPlan.autoThreadContext; - const effectiveFrom = isDirectMessage - ? `discord:${author.id}` - : (autoThreadContext?.From ?? `group:${message.channelId}`); - const effectiveTo = autoThreadContext?.To ?? replyTarget; - if (!effectiveTo) { - runtime.error?.(danger("discord: missing reply target")); - return; - } + const effectiveFrom = isDirectMessage + ? `discord:${author.id}` + : (autoThreadContext?.From ?? `group:${message.channelId}`); + const effectiveTo = autoThreadContext?.To ?? replyTarget; + if (!effectiveTo) { + runtime.error?.(danger("discord: missing reply target")); + return; + } - const ctxPayload = { - Body: combinedBody, - RawBody: baseText, - CommandBody: baseText, - From: effectiveFrom, - To: effectiveTo, - SessionKey: autoThreadContext?.SessionKey ?? threadKeys.sessionKey, - AccountId: route.accountId, - ChatType: isDirectMessage ? "direct" : "group", - SenderName: data.member?.nickname ?? author.globalName ?? author.username, - SenderId: author.id, - SenderUsername: author.username, - SenderTag: formatDiscordUserTag(author), - GroupSubject: groupSubject, - GroupRoom: groupRoom, - GroupSystemPrompt: isGuildMessage ? groupSystemPrompt : undefined, - GroupSpace: isGuildMessage ? (guildInfo?.id ?? guildSlug) || undefined : undefined, - Provider: "discord" as const, - Surface: "discord" as const, - WasMentioned: effectiveWasMentioned, - MessageSid: message.id, - ParentSessionKey: autoThreadContext?.ParentSessionKey ?? threadKeys.parentSessionKey, - ThreadStarterBody: threadStarterBody, - ThreadLabel: threadLabel, - Timestamp: resolveTimestampMs(message.timestamp), - ...mediaPayload, - CommandAuthorized: commandAuthorized, - CommandSource: "text" as const, - // Originating channel for reply routing. - OriginatingChannel: "discord" as const, - OriginatingTo: autoThreadContext?.OriginatingTo ?? replyTarget, - }; + const ctxPayload = { + Body: combinedBody, + RawBody: baseText, + CommandBody: baseText, + From: effectiveFrom, + To: effectiveTo, + SessionKey: autoThreadContext?.SessionKey ?? threadKeys.sessionKey, + AccountId: route.accountId, + ChatType: isDirectMessage ? "direct" : "group", + SenderName: data.member?.nickname ?? author.globalName ?? author.username, + SenderId: author.id, + SenderUsername: author.username, + SenderTag: formatDiscordUserTag(author), + GroupSubject: groupSubject, + GroupRoom: groupRoom, + GroupSystemPrompt: isGuildMessage ? groupSystemPrompt : undefined, + GroupSpace: isGuildMessage ? (guildInfo?.id ?? guildSlug) || undefined : undefined, + Provider: "discord" as const, + Surface: "discord" as const, + WasMentioned: effectiveWasMentioned, + MessageSid: message.id, + ParentSessionKey: autoThreadContext?.ParentSessionKey ?? threadKeys.parentSessionKey, + ThreadStarterBody: threadStarterBody, + ThreadLabel: threadLabel, + Timestamp: resolveTimestampMs(message.timestamp), + ...mediaPayload, + CommandAuthorized: commandAuthorized, + CommandSource: "text" as const, + // Originating channel for reply routing. + OriginatingChannel: "discord" as const, + OriginatingTo: autoThreadContext?.OriginatingTo ?? replyTarget, + }; if (isDirectMessage) { const sessionCfg = cfg.session; @@ -272,20 +269,20 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) }); } - if (shouldLogVerbose()) { - const preview = truncateUtf16Safe(combinedBody, 200).replace(/\n/g, "\\n"); - logVerbose( - `discord inbound: channel=${message.channelId} deliver=${deliverTarget} from=${ctxPayload.From} preview="${preview}"`, - ); - } + if (shouldLogVerbose()) { + const preview = truncateUtf16Safe(combinedBody, 200).replace(/\n/g, "\\n"); + logVerbose( + `discord inbound: channel=${message.channelId} deliver=${deliverTarget} from=${ctxPayload.From} preview="${preview}"`, + ); + } - let didSendReply = false; - const typingChannelId = deliverTarget.startsWith("channel:") - ? deliverTarget.slice("channel:".length) - : message.channelId; - const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({ - responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix, - humanDelay: resolveHumanDelayConfig(cfg, route.agentId), + let didSendReply = false; + const typingChannelId = deliverTarget.startsWith("channel:") + ? deliverTarget.slice("channel:".length) + : message.channelId; + const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({ + responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix, + humanDelay: resolveHumanDelayConfig(cfg, route.agentId), deliver: async (payload: ReplyPayload) => { const replyToId = replyReference.use(); await deliverDiscordReply({ @@ -302,11 +299,11 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) didSendReply = true; replyReference.markSent(); }, - onError: (err, info) => { - runtime.error?.(danger(`discord ${info.kind} reply failed: ${String(err)}`)); - }, - onReplyStart: () => sendTyping({ client, channelId: typingChannelId }), - }); + onError: (err, info) => { + runtime.error?.(danger(`discord ${info.kind} reply failed: ${String(err)}`)); + }, + onReplyStart: () => sendTyping({ client, channelId: typingChannelId }), + }); const { queuedFinal, counts } = await dispatchReplyFromConfig({ ctx: ctxPayload, diff --git a/src/discord/monitor/threading.test.ts b/src/discord/monitor/threading.test.ts index 2f31c1547..580557187 100644 --- a/src/discord/monitor/threading.test.ts +++ b/src/discord/monitor/threading.test.ts @@ -93,9 +93,14 @@ describe("resolveDiscordAutoThreadReplyPlan", () => { } as unknown as Client; const plan = await resolveDiscordAutoThreadReplyPlan({ client, - message: { id: "m1", channelId: "parent" } as unknown as import("./listeners.js").DiscordMessageEvent["message"], + message: { + id: "m1", + channelId: "parent", + } as unknown as import("./listeners.js").DiscordMessageEvent["message"], isGuildMessage: true, - channelConfig: { autoThread: true } as unknown as import("./allow-list.js").DiscordChannelConfigResolved, + channelConfig: { + autoThread: true, + } as unknown as import("./allow-list.js").DiscordChannelConfigResolved, threadChannel: null, baseText: "hello", combinedBody: "hello", @@ -118,9 +123,14 @@ describe("resolveDiscordAutoThreadReplyPlan", () => { const client = { rest: { post: async () => ({ id: "thread" }) } } as unknown as Client; const plan = await resolveDiscordAutoThreadReplyPlan({ client, - message: { id: "m1", channelId: "parent" } as unknown as import("./listeners.js").DiscordMessageEvent["message"], + message: { + id: "m1", + channelId: "parent", + } as unknown as import("./listeners.js").DiscordMessageEvent["message"], isGuildMessage: true, - channelConfig: { autoThread: false } as unknown as import("./allow-list.js").DiscordChannelConfigResolved, + channelConfig: { + autoThread: false, + } as unknown as import("./allow-list.js").DiscordChannelConfigResolved, threadChannel: null, baseText: "hello", combinedBody: "hello", diff --git a/src/infra/outbound/deliver.test.ts b/src/infra/outbound/deliver.test.ts index 921681342..9cf66a924 100644 --- a/src/infra/outbound/deliver.test.ts +++ b/src/infra/outbound/deliver.test.ts @@ -86,9 +86,7 @@ describe("deliverOutboundPayloads", () => { }); it("chunks Signal markdown using the format-first chunker", async () => { - const sendSignal = vi - .fn() - .mockResolvedValue({ messageId: "s1", timestamp: 123 }); + const sendSignal = vi.fn().mockResolvedValue({ messageId: "s1", timestamp: 123 }); const cfg: ClawdbotConfig = { channels: { signal: { textChunkLimit: 20 } }, }; diff --git a/src/markdown/ir.ts b/src/markdown/ir.ts index b9a537bbe..c823381d8 100644 --- a/src/markdown/ir.ts +++ b/src/markdown/ir.ts @@ -25,13 +25,7 @@ type MarkdownToken = { attrGet?: (name: string) => string | null; }; -export type MarkdownStyle = - | "bold" - | "italic" - | "strikethrough" - | "code" - | "code_block" - | "spoiler"; +export type MarkdownStyle = "bold" | "italic" | "strikethrough" | "code" | "code_block" | "spoiler"; export type MarkdownStyleSpan = { start: number; @@ -414,11 +408,7 @@ function sliceStyleSpans( return mergeStyleSpans(sliced); } -function sliceLinkSpans( - spans: MarkdownLinkSpan[], - start: number, - end: number, -): MarkdownLinkSpan[] { +function sliceLinkSpans(spans: MarkdownLinkSpan[], start: number, end: number): MarkdownLinkSpan[] { if (spans.length === 0) return []; const sliced: MarkdownLinkSpan[] = []; for (const span of spans) { @@ -465,7 +455,8 @@ export function markdownToIR(markdown: string, options: MarkdownParseOptions = { if (span.end > codeBlockEnd) codeBlockEnd = span.end; } const finalLength = Math.max(trimmedLength, codeBlockEnd); - const finalText = finalLength === state.text.length ? state.text : state.text.slice(0, finalLength); + const finalText = + finalLength === state.text.length ? state.text : state.text.slice(0, finalLength); return { text: finalText, diff --git a/src/markdown/render.ts b/src/markdown/render.ts index 33b62e672..502ab69ef 100644 --- a/src/markdown/render.ts +++ b/src/markdown/render.ts @@ -46,9 +46,7 @@ export function renderMarkdownWithMarkers(ir: MarkdownIR, options: RenderOptions if (!text) return ""; const styleMarkers = options.styleMarkers; - const styled = sortStyleSpans( - ir.styles.filter((span) => Boolean(styleMarkers[span.style])), - ); + const styled = sortStyleSpans(ir.styles.filter((span) => Boolean(styleMarkers[span.style]))); const boundaries = new Set(); boundaries.add(0); diff --git a/src/signal/format.test.ts b/src/signal/format.test.ts index 243234cb7..7c66e3013 100644 --- a/src/signal/format.test.ts +++ b/src/signal/format.test.ts @@ -16,13 +16,9 @@ describe("markdownToSignalText", () => { }); it("renders links as label plus url when needed", () => { - const res = markdownToSignalText( - "see [docs](https://example.com) and https://example.com", - ); + const res = markdownToSignalText("see [docs](https://example.com) and https://example.com"); - expect(res.text).toBe( - "see docs (https://example.com) and https://example.com", - ); + expect(res.text).toBe("see docs (https://example.com) and https://example.com"); expect(res.styles).toEqual([]); }); @@ -34,18 +30,14 @@ describe("markdownToSignalText", () => { }); it("renders fenced code blocks with monospaced styles", () => { - const res = markdownToSignalText( - "before\n\n```\nconst x = 1;\n```\n\nafter", - ); + const res = markdownToSignalText("before\n\n```\nconst x = 1;\n```\n\nafter"); const prefix = "before\n\n"; const code = "const x = 1;\n"; const suffix = "\nafter"; expect(res.text).toBe(`${prefix}${code}${suffix}`); - expect(res.styles).toEqual([ - { start: prefix.length, length: code.length, style: "MONOSPACE" }, - ]); + expect(res.styles).toEqual([{ start: prefix.length, length: code.length, style: "MONOSPACE" }]); }); it("renders lists without extra block markup", () => { @@ -60,8 +52,6 @@ describe("markdownToSignalText", () => { const prefix = "😀 "; expect(res.text).toBe(`${prefix}bold`); - expect(res.styles).toEqual([ - { start: prefix.length, length: 4, style: "BOLD" }, - ]); + expect(res.styles).toEqual([{ start: prefix.length, length: 4, style: "BOLD" }]); }); }); diff --git a/src/signal/format.ts b/src/signal/format.ts index 122e04622..0890ce608 100644 --- a/src/signal/format.ts +++ b/src/signal/format.ts @@ -1,11 +1,11 @@ -import { chunkMarkdownIR, markdownToIR, type MarkdownIR, type MarkdownStyle } from "../markdown/ir.js"; +import { + chunkMarkdownIR, + markdownToIR, + type MarkdownIR, + type MarkdownStyle, +} from "../markdown/ir.js"; -type SignalTextStyle = - | "BOLD" - | "ITALIC" - | "STRIKETHROUGH" - | "MONOSPACE" - | "SPOILER"; +type SignalTextStyle = "BOLD" | "ITALIC" | "STRIKETHROUGH" | "MONOSPACE" | "SPOILER"; export type SignalTextStyleRange = { start: number; @@ -57,11 +57,7 @@ function mergeStyles(styles: SignalTextStyleRange[]): SignalTextStyleRange[] { const merged: SignalTextStyleRange[] = []; for (const style of sorted) { const prev = merged[merged.length - 1]; - if ( - prev && - prev.style === style.style && - style.start <= prev.start + prev.length - ) { + if (prev && prev.style === style.style && style.start <= prev.start + prev.length) { const prevEnd = prev.start + prev.length; const nextEnd = Math.max(prevEnd, style.start + style.length); prev.length = nextEnd - prev.start; @@ -73,10 +69,7 @@ function mergeStyles(styles: SignalTextStyleRange[]): SignalTextStyleRange[] { return merged; } -function clampStyles( - styles: SignalTextStyleRange[], - maxLength: number, -): SignalTextStyleRange[] { +function clampStyles(styles: SignalTextStyleRange[], maxLength: number): SignalTextStyleRange[] { const clamped: SignalTextStyleRange[] = []; for (const style of styles) { const start = Math.max(0, Math.min(style.start, maxLength)); @@ -205,10 +198,7 @@ export function markdownToSignalText(markdown: string): SignalFormattedText { return renderSignalText(ir); } -export function markdownToSignalTextChunks( - markdown: string, - limit: number, -): SignalFormattedText[] { +export function markdownToSignalTextChunks(markdown: string, limit: number): SignalFormattedText[] { const ir = markdownToIR(markdown ?? "", { linkify: true, enableSpoilers: true, diff --git a/src/telegram/format.ts b/src/telegram/format.ts index 654b6da02..7894d67f0 100644 --- a/src/telegram/format.ts +++ b/src/telegram/format.ts @@ -1,4 +1,9 @@ -import { chunkMarkdownIR, markdownToIR, type MarkdownLinkSpan, type MarkdownIR } from "../markdown/ir.js"; +import { + chunkMarkdownIR, + markdownToIR, + type MarkdownLinkSpan, + type MarkdownIR, +} from "../markdown/ir.js"; import { renderMarkdownWithMarkers } from "../markdown/render.js"; export type TelegramFormattedChunk = { @@ -50,7 +55,10 @@ export function markdownToTelegramHtml(markdown: string): string { return renderTelegramHtml(ir); } -export function markdownToTelegramChunks(markdown: string, limit: number): TelegramFormattedChunk[] { +export function markdownToTelegramChunks( + markdown: string, + limit: number, +): TelegramFormattedChunk[] { const ir = markdownToIR(markdown ?? "", { linkify: true, headingStyle: "none", diff --git a/src/telegram/send.ts b/src/telegram/send.ts index f857fb239..0d6c3fca5 100644 --- a/src/telegram/send.ts +++ b/src/telegram/send.ts @@ -432,9 +432,7 @@ export async function deleteMessageTelegram( verbose: opts.verbose, }); await request(() => api.deleteMessage(chatId, messageId), "deleteMessage"); - logVerbose( - `[telegram] Deleted message ${messageId} from chat ${chatId}`, - ); + logVerbose(`[telegram] Deleted message ${messageId} from chat ${chatId}`); return { ok: true }; } diff --git a/src/whatsapp/normalize.test.ts b/src/whatsapp/normalize.test.ts index 662c19586..8dd80743f 100644 --- a/src/whatsapp/normalize.test.ts +++ b/src/whatsapp/normalize.test.ts @@ -1,10 +1,6 @@ import { describe, expect, it } from "vitest"; -import { - isWhatsAppGroupJid, - isWhatsAppUserTarget, - normalizeWhatsAppTarget, -} from "./normalize.js"; +import { isWhatsAppGroupJid, isWhatsAppUserTarget, normalizeWhatsAppTarget } from "./normalize.js"; describe("normalizeWhatsAppTarget", () => { it("preserves group JIDs", () => { @@ -31,16 +27,10 @@ describe("normalizeWhatsAppTarget", () => { it("normalizes user JIDs with device suffix to E.164", () => { // This is the bug fix: JIDs like "41796666864:0@s.whatsapp.net" should // normalize to "+41796666864", not "+417966668640" (extra digit from ":0") - expect(normalizeWhatsAppTarget("41796666864:0@s.whatsapp.net")).toBe( - "+41796666864", - ); - expect(normalizeWhatsAppTarget("1234567890:123@s.whatsapp.net")).toBe( - "+1234567890", - ); + expect(normalizeWhatsAppTarget("41796666864:0@s.whatsapp.net")).toBe("+41796666864"); + expect(normalizeWhatsAppTarget("1234567890:123@s.whatsapp.net")).toBe("+1234567890"); // Without device suffix still works - expect(normalizeWhatsAppTarget("41796666864@s.whatsapp.net")).toBe( - "+41796666864", - ); + expect(normalizeWhatsAppTarget("41796666864@s.whatsapp.net")).toBe("+41796666864"); }); it("normalizes LID JIDs to E.164", () => {