From aaefee78de2486bf563404c8f605aed21c8532af Mon Sep 17 00:00:00 2001 From: ThanhNguyxn Date: Fri, 30 Jan 2026 17:12:02 +0700 Subject: [PATCH] fix(signal): preserve case for group IDs (base64 is case-sensitive) fix(windows): add shell option for spawn on Windows to fix npm ENOENT Fixes #4537, Fixes #4557 --- src/channels/plugins/normalize/signal.ts | 8 +++++--- src/process/exec.ts | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/channels/plugins/normalize/signal.ts b/src/channels/plugins/normalize/signal.ts index c8ff17da6..9750dba5e 100644 --- a/src/channels/plugins/normalize/signal.ts +++ b/src/channels/plugins/normalize/signal.ts @@ -8,21 +8,23 @@ export function normalizeSignalMessagingTarget(raw: string): string | undefined if (!normalized) return undefined; const lower = normalized.toLowerCase(); if (lower.startsWith("group:")) { + // Preserve case for group IDs - base64 is case-sensitive const id = normalized.slice("group:".length).trim(); - return id ? `group:${id}`.toLowerCase() : undefined; + return id ? `group:${id}` : undefined; } if (lower.startsWith("username:")) { const id = normalized.slice("username:".length).trim(); - return id ? `username:${id}`.toLowerCase() : undefined; + return id ? `username:${id.toLowerCase()}` : undefined; } if (lower.startsWith("u:")) { const id = normalized.slice("u:".length).trim(); - return id ? `username:${id}`.toLowerCase() : undefined; + return id ? `username:${id.toLowerCase()}` : undefined; } if (lower.startsWith("uuid:")) { const id = normalized.slice("uuid:".length).trim(); return id ? id.toLowerCase() : undefined; } + // Phone numbers and other targets can be lowercased return normalized.toLowerCase(); } diff --git a/src/process/exec.ts b/src/process/exec.ts index 44f8b2ce0..0e8397c64 100644 --- a/src/process/exec.ts +++ b/src/process/exec.ts @@ -85,6 +85,7 @@ export async function runCommandWithTimeout( cwd, env: resolvedEnv, windowsVerbatimArguments, + shell: process.platform === "win32", }); // Spawn with inherited stdin (TTY) so tools like `pi` stay interactive when needed. return await new Promise((resolve, reject) => {