From 2aac60697907f0cdec2edd652696dd8f2c98ef5d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 25 Nov 2025 04:40:57 +0100 Subject: [PATCH] chore: fix type regressions and helpers --- src/auto-reply/claude.ts | 4 ++-- src/cli/program.ts | 8 ++++++++ src/commands/up.ts | 2 +- src/process/exec.ts | 17 +++++++++++++---- src/provider-web.ts | 9 +++++---- src/twilio/monitor.ts | 2 +- src/twilio/typing.ts | 2 +- src/twilio/webhook.ts | 2 +- 8 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/auto-reply/claude.ts b/src/auto-reply/claude.ts index f4c9ce13a..5da400ae1 100644 --- a/src/auto-reply/claude.ts +++ b/src/auto-reply/claude.ts @@ -70,8 +70,8 @@ const ClaudeJsonSchema = z num_turns: z.number().optional(), session_id: z.string().optional(), total_cost_usd: z.number().optional(), - usage: z.record(z.any()).optional(), - modelUsage: z.record(z.any()).optional(), + usage: z.record(z.string(), z.any()).optional(), + modelUsage: z.record(z.string(), z.any()).optional(), }) .passthrough() .refine( diff --git a/src/cli/program.ts b/src/cli/program.ts index 48a847049..72d91e03a 100644 --- a/src/cli/program.ts +++ b/src/cli/program.ts @@ -197,6 +197,10 @@ With Tailscale: const deps = createDefaultDeps(); try { const server = await webhookCommand(opts, deps, defaultRuntime); + if (!server) { + defaultRuntime.log(info("Webhook dry-run complete; no server started.")); + return; + } process.on("SIGINT", () => { server.close(() => { console.log("\nšŸ‘‹ Webhook stopped"); @@ -227,6 +231,10 @@ With Tailscale: const deps = createDefaultDeps(); try { const { server } = await upCommand(opts, deps, defaultRuntime); + if (!server) { + defaultRuntime.log(info("Up dry-run complete; no server started.")); + return; + } process.on("SIGINT", () => { server.close(() => { console.log("\nšŸ‘‹ Webhook stopped"); diff --git a/src/commands/up.ts b/src/commands/up.ts index cdff293a4..ef31361cc 100644 --- a/src/commands/up.ts +++ b/src/commands/up.ts @@ -47,7 +47,7 @@ export async function upCommand( } const twilioClient = deps.createClient(env); const senderSid = await deps.findWhatsappSenderSid( - twilioClient, + twilioClient as unknown as import("../twilio/types.js").TwilioSenderListClient, env.whatsappFrom, env.whatsappSenderSid, runtime, diff --git a/src/process/exec.ts b/src/process/exec.ts index b96c47ee0..75c2cca30 100644 --- a/src/process/exec.ts +++ b/src/process/exec.ts @@ -1,18 +1,27 @@ import { execFile, spawn } from "node:child_process"; +import { promisify } from "node:util"; import { danger, isVerbose } from "../globals.js"; import { logDebug, logError } from "../logger.js"; +const execFileAsync = promisify(execFile); + // Simple promise-wrapped execFile with optional verbosity logging. export async function runExec( command: string, args: string[], - timeoutMs = 10_000, + opts: number | { timeoutMs?: number; maxBuffer?: number } = 10_000, ): Promise<{ stdout: string; stderr: string }> { + const options = + typeof opts === "number" + ? { timeout: opts, encoding: "utf8" as const } + : { + timeout: opts.timeoutMs, + maxBuffer: opts.maxBuffer, + encoding: "utf8" as const, + }; try { - const { stdout, stderr } = await execFile(command, args, { - timeout: timeoutMs, - }); + const { stdout, stderr } = await execFileAsync(command, args, options); if (isVerbose()) { if (stdout.trim()) logDebug(stdout.trim()); if (stderr.trim()) logError(stderr.trim()); diff --git a/src/provider-web.ts b/src/provider-web.ts index cf72534a2..38ba12902 100644 --- a/src/provider-web.ts +++ b/src/provider-web.ts @@ -25,8 +25,9 @@ const WA_WEB_AUTH_DIR = path.join(os.homedir(), ".warelay", "credentials"); export async function createWaSocket(printQr: boolean, verbose: boolean) { const logger = pino({ level: verbose ? "info" : "silent" }); // Some Baileys internals call logger.trace even when silent; ensure it's present. - if (typeof (logger as Record).trace !== "function") { - (logger as unknown as { trace: () => void }).trace = () => {}; + const loggerAny = logger as unknown as Record; + if (typeof loggerAny.trace !== "function") { + loggerAny.trace = () => {}; } await ensureDir(WA_WEB_AUTH_DIR); const { state, saveCreds } = await useMultiFileAuthState(WA_WEB_AUTH_DIR); @@ -81,7 +82,7 @@ export async function waitForWaConnection( const handler = (...args: unknown[]) => { const update = (args[0] ?? {}) as Partial< - import("baileys").ConnectionState + import("@whiskeysockets/baileys").ConnectionState >; if (update.connection === "open") { evWithOff.off?.("connection.update", handler); @@ -235,7 +236,7 @@ export async function monitorWebInbox(options: { continue; const from = jidToE164(remoteJid); if (!from) continue; - const body = extractText(msg.message); + const body = extractText(msg.message ?? undefined); if (!body) continue; const chatJid = remoteJid; const sendComposing = async () => { diff --git a/src/twilio/monitor.ts b/src/twilio/monitor.ts index 50919ea8a..6129ead1d 100644 --- a/src/twilio/monitor.ts +++ b/src/twilio/monitor.ts @@ -114,7 +114,7 @@ async function handleMessages( if (!m.from || !m.to) continue; try { await deps.autoReplyIfConfigured( - client as unknown as { + client as unknown as import("./types.js").TwilioRequester & { messages: { create: (opts: unknown) => Promise }; }, m as unknown as MessageInstance, diff --git a/src/twilio/typing.ts b/src/twilio/typing.ts index 7f353af2e..fb9d1c6d1 100644 --- a/src/twilio/typing.ts +++ b/src/twilio/typing.ts @@ -16,8 +16,8 @@ type TwilioRequester = { export async function sendTypingIndicator( client: TwilioRequester, - messageSid?: string, runtime: RuntimeEnv, + messageSid?: string, ) { // Best-effort WhatsApp typing indicator (public beta as of Nov 2025). if (!messageSid) { diff --git a/src/twilio/webhook.ts b/src/twilio/webhook.ts index 8a0fb9285..e0d3d7fa6 100644 --- a/src/twilio/webhook.ts +++ b/src/twilio/webhook.ts @@ -43,7 +43,7 @@ export async function startWebhook( replyText = await getReplyFromConfig( { Body, From, To, MessageSid }, { - onReplyStart: () => sendTypingIndicator(client, MessageSid, runtime), + onReplyStart: () => sendTypingIndicator(client, runtime, MessageSid), }, ); }