diff --git a/src/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.ts b/src/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.ts index 95e162f34..09e5e443a 100644 --- a/src/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.ts +++ b/src/agents/pi-embedded-helpers.formatrawassistanterrorforui.test.ts @@ -18,4 +18,3 @@ describe("formatRawAssistantErrorForUi", () => { expect(formatRawAssistantErrorForUi("")).toContain("unknown error"); }); }); - diff --git a/src/auto-reply/command-auth.ts b/src/auto-reply/command-auth.ts index e4ddd99fb..08fcf50e0 100644 --- a/src/auto-reply/command-auth.ts +++ b/src/auto-reply/command-auth.ts @@ -155,11 +155,7 @@ export function resolveCommandAuthorization(params: { const senderId = matchedSender ?? senderCandidates[0]; const enforceOwner = Boolean(dock?.commands?.enforceOwnerForCommands); - const isOwner = - !enforceOwner || - allowAll || - ownerList.length === 0 || - Boolean(matchedSender); + const isOwner = !enforceOwner || allowAll || ownerList.length === 0 || Boolean(matchedSender); const isAuthorizedSender = commandAuthorized && isOwner; return { diff --git a/src/channels/plugins/outbound/telegram.ts b/src/channels/plugins/outbound/telegram.ts index db6b8a421..21cbb3ff0 100644 --- a/src/channels/plugins/outbound/telegram.ts +++ b/src/channels/plugins/outbound/telegram.ts @@ -8,6 +8,17 @@ function parseReplyToMessageId(replyToId?: string | null) { return Number.isFinite(parsed) ? parsed : undefined; } +function parseThreadId(threadId?: string | number | null) { + if (threadId == null) return undefined; + if (typeof threadId === "number") { + return Number.isFinite(threadId) ? Math.trunc(threadId) : undefined; + } + const trimmed = threadId.trim(); + if (!trimmed) return undefined; + const parsed = Number.parseInt(trimmed, 10); + return Number.isFinite(parsed) ? parsed : undefined; +} + export const telegramOutbound: ChannelOutboundAdapter = { deliveryMode: "direct", chunker: markdownToTelegramHtmlChunks, @@ -25,10 +36,11 @@ export const telegramOutbound: ChannelOutboundAdapter = { sendText: async ({ to, text, accountId, deps, replyToId, threadId }) => { const send = deps?.sendTelegram ?? sendMessageTelegram; const replyToMessageId = parseReplyToMessageId(replyToId); + const messageThreadId = parseThreadId(threadId); const result = await send(to, text, { verbose: false, textMode: "html", - messageThreadId: threadId ?? undefined, + messageThreadId, replyToMessageId, accountId: accountId ?? undefined, }); @@ -37,11 +49,12 @@ export const telegramOutbound: ChannelOutboundAdapter = { sendMedia: async ({ to, text, mediaUrl, accountId, deps, replyToId, threadId }) => { const send = deps?.sendTelegram ?? sendMessageTelegram; const replyToMessageId = parseReplyToMessageId(replyToId); + const messageThreadId = parseThreadId(threadId); const result = await send(to, text, { verbose: false, mediaUrl, textMode: "html", - messageThreadId: threadId ?? undefined, + messageThreadId, replyToMessageId, accountId: accountId ?? undefined, }); diff --git a/src/channels/plugins/telegram.ts b/src/channels/plugins/telegram.ts index a2754add7..ee9eed7d4 100644 --- a/src/channels/plugins/telegram.ts +++ b/src/channels/plugins/telegram.ts @@ -36,6 +36,23 @@ import type { ChannelPlugin } from "./types.js"; const meta = getChatChannelMeta("telegram"); +function parseReplyToMessageId(replyToId?: string | null) { + if (!replyToId) return undefined; + const parsed = Number.parseInt(replyToId, 10); + return Number.isFinite(parsed) ? parsed : undefined; +} + +function parseThreadId(threadId?: string | number | null) { + if (threadId == null) return undefined; + if (typeof threadId === "number") { + return Number.isFinite(threadId) ? Math.trunc(threadId) : undefined; + } + const trimmed = threadId.trim(); + if (!trimmed) return undefined; + const parsed = Number.parseInt(trimmed, 10); + return Number.isFinite(parsed) ? parsed : undefined; +} + export const telegramPlugin: ChannelPlugin = { id: "telegram", meta: { @@ -231,29 +248,25 @@ export const telegramPlugin: ChannelPlugin = { }, sendText: async ({ to, text, accountId, deps, replyToId, threadId }) => { const send = deps?.sendTelegram ?? sendMessageTelegram; - const replyToMessageId = replyToId ? Number.parseInt(replyToId, 10) : undefined; - const resolvedReplyToMessageId = Number.isFinite(replyToMessageId) - ? replyToMessageId - : undefined; + const replyToMessageId = parseReplyToMessageId(replyToId); + const messageThreadId = parseThreadId(threadId); const result = await send(to, text, { verbose: false, - messageThreadId: threadId ?? undefined, - replyToMessageId: resolvedReplyToMessageId, + messageThreadId, + replyToMessageId, accountId: accountId ?? undefined, }); return { channel: "telegram", ...result }; }, sendMedia: async ({ to, text, mediaUrl, accountId, deps, replyToId, threadId }) => { const send = deps?.sendTelegram ?? sendMessageTelegram; - const replyToMessageId = replyToId ? Number.parseInt(replyToId, 10) : undefined; - const resolvedReplyToMessageId = Number.isFinite(replyToMessageId) - ? replyToMessageId - : undefined; + const replyToMessageId = parseReplyToMessageId(replyToId); + const messageThreadId = parseThreadId(threadId); const result = await send(to, text, { verbose: false, mediaUrl, - messageThreadId: threadId ?? undefined, - replyToMessageId: resolvedReplyToMessageId, + messageThreadId, + replyToMessageId, accountId: accountId ?? undefined, }); return { channel: "telegram", ...result }; diff --git a/src/commands/channels/add.ts b/src/commands/channels/add.ts index 04e616c3d..1844105e1 100644 --- a/src/commands/channels/add.ts +++ b/src/commands/channels/add.ts @@ -94,9 +94,9 @@ export async function channelsAddCommand( } await writeConfigFile(nextConfig); - await prompter.outro("Channels updated."); - return; - } + await prompter.outro("Channels updated."); + return; + } const channel = normalizeChannelId(opts.channel); if (!channel) { diff --git a/src/slack/monitor/context.ts b/src/slack/monitor/context.ts index 27bee0460..1b703aa1d 100644 --- a/src/slack/monitor/context.ts +++ b/src/slack/monitor/context.ts @@ -29,7 +29,12 @@ export function normalizeSlackChannelType( channelId?: string | null, ): SlackMessageEvent["channel_type"] { const normalized = channelType?.trim().toLowerCase(); - if (normalized === "im" || normalized === "mpim" || normalized === "channel" || normalized === "group") { + if ( + normalized === "im" || + normalized === "mpim" || + normalized === "channel" || + normalized === "group" + ) { return normalized; } return inferSlackChannelType(channelId) ?? "channel"; diff --git a/src/tui/tui-formatters.test.ts b/src/tui/tui-formatters.test.ts index 3e74e1e72..ae717bcb0 100644 --- a/src/tui/tui-formatters.test.ts +++ b/src/tui/tui-formatters.test.ts @@ -28,4 +28,3 @@ describe("extractTextFromMessage", () => { expect(text).toContain("unknown error"); }); }); - diff --git a/src/wizard/onboarding.finalize.ts b/src/wizard/onboarding.finalize.ts index a2946343b..b49d81786 100644 --- a/src/wizard/onboarding.finalize.ts +++ b/src/wizard/onboarding.finalize.ts @@ -141,11 +141,11 @@ export async function finalizeOnboardingWizard(options: FinalizeOnboardingOption "Gateway daemon", { doneMessage: "Gateway daemon restarted." }, async (progress) => { - progress.update("Restarting Gateway daemon…"); - await service.restart({ - profile: process.env.CLAWDBOT_PROFILE, - stdout: process.stdout, - }); + progress.update("Restarting Gateway daemon…"); + await service.restart({ + profile: process.env.CLAWDBOT_PROFILE, + stdout: process.stdout, + }); }, ); } else if (action === "reinstall") { @@ -153,8 +153,8 @@ export async function finalizeOnboardingWizard(options: FinalizeOnboardingOption "Gateway daemon", { doneMessage: "Gateway daemon uninstalled." }, async (progress) => { - progress.update("Uninstalling Gateway daemon…"); - await service.uninstall({ env: process.env, stdout: process.stdout }); + progress.update("Uninstalling Gateway daemon…"); + await service.uninstall({ env: process.env, stdout: process.stdout }); }, ); } @@ -170,40 +170,40 @@ export async function finalizeOnboardingWizard(options: FinalizeOnboardingOption "Gateway daemon", { doneMessage: "Gateway daemon installed." }, async (progress) => { - progress.update("Preparing Gateway daemon…"); - const nodePath = await resolvePreferredNodePath({ - env: process.env, - runtime: daemonRuntime, - }); - const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({ - port: settings.port, - dev: devMode, - runtime: daemonRuntime, - nodePath, - }); - if (daemonRuntime === "node") { - const systemNode = await resolveSystemNodeInfo({ env: process.env }); - const warning = renderSystemNodeWarning(systemNode, programArguments[0]); - if (warning) await prompter.note(warning, "Gateway runtime"); - } - const environment = buildServiceEnvironment({ - env: process.env, - port: settings.port, - token: settings.gatewayToken, - launchdLabel: - process.platform === "darwin" - ? resolveGatewayLaunchAgentLabel(process.env.CLAWDBOT_PROFILE) - : undefined, - }); + progress.update("Preparing Gateway daemon…"); + const nodePath = await resolvePreferredNodePath({ + env: process.env, + runtime: daemonRuntime, + }); + const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({ + port: settings.port, + dev: devMode, + runtime: daemonRuntime, + nodePath, + }); + if (daemonRuntime === "node") { + const systemNode = await resolveSystemNodeInfo({ env: process.env }); + const warning = renderSystemNodeWarning(systemNode, programArguments[0]); + if (warning) await prompter.note(warning, "Gateway runtime"); + } + const environment = buildServiceEnvironment({ + env: process.env, + port: settings.port, + token: settings.gatewayToken, + launchdLabel: + process.platform === "darwin" + ? resolveGatewayLaunchAgentLabel(process.env.CLAWDBOT_PROFILE) + : undefined, + }); - progress.update("Installing Gateway daemon…"); - await service.install({ - env: process.env, - stdout: process.stdout, - programArguments, - workingDirectory, - environment, - }); + progress.update("Installing Gateway daemon…"); + await service.install({ + env: process.env, + stdout: process.stdout, + programArguments, + workingDirectory, + environment, + }); }, ); }