/** @internal Exported for testing. */
export function looksLikeArchive(name: string): boolean { return name.endsWith(".tar.gz") || name.endsWith(".tgz") || name.endsWith(".zip");
}
/** * Pick a native release asset from the official GitHub releases. * * The official signal-cli releases only publish native (GraalVM) binaries for * x86-64 Linux. On architectures where no native asset is available this * returns `undefined` so the caller can fall back to a different install * strategy (e.g. Homebrew).
*/ /** @internal Exported for testing. */
export function pickAsset(
assets: ReleaseAsset[],
platform: NodeJS.Platform,
arch: string,
): NamedAsset | undefined { const withName = assets.filter((asset): asset is NamedAsset => Boolean(asset.name && asset.browser_download_url),
);
if (platform === "linux") { // The official "Linux-native" asset is an x86-64 GraalVM binary. // On non-x64 architectures it will fail with "Exec format error", // so only select it when the host architecture matches. if (arch === "x64") { return byName(/linux-native/) || byName(/linux/) || archives[0];
} // No native release for this arch — caller should fall back. return undefined;
}
if (platform === "darwin") { return byName(/macos|osx|darwin/) || archives[0];
}
if (platform === "win32") { return byName(/windows|win/) || archives[0];
}
// --------------------------------------------------------------------------- // Brew-based install (used on architectures without an official native build) // ---------------------------------------------------------------------------
async function resolveBrewSignalCliPath(brewExe: string): Promise<string | null> { try { const result = await runPluginCommandWithTimeout({
argv: [brewExe, "--prefix", "signal-cli"],
timeoutMs: 10_000,
}); if (result.code === 0 && result.stdout.trim()) { const prefix = result.stdout.trim(); // Homebrew installs the wrapper script at <prefix>/bin/signal-cli const candidate = path.join(prefix, "bin", "signal-cli"); try {
await fs.access(candidate); return candidate;
} catch { // Fall back to searching the prefix return findSignalCliBinary(prefix);
}
}
} catch { // ignore
} returnnull;
}
async function installSignalCliViaBrew(runtime: RuntimeEnv): Promise<SignalInstallResult> { const brewExe = resolveBrewExecutable(); if (!brewExe) { return {
ok: false,
error:
`No native signal-cli build is available for ${process.arch}. ` + "Install Homebrew (https://brew.sh) and try again, or install signal-cli manually.",
};
}
runtime.log(`Installing signal-cli via Homebrew (${brewExe})…`); const result = await runPluginCommandWithTimeout({
argv: [brewExe, "install", "signal-cli"],
timeoutMs: 15 * 60_000, // brew builds from source; can take a while
});
const cliPath = await resolveBrewSignalCliPath(brewExe); if (!cliPath) { return {
ok: false,
error: "brew install succeeded but signal-cli binary was not found.",
};
}
// Extract version from the installed binary.
let version: string | undefined; try { const vResult = await runPluginCommandWithTimeout({
argv: [cliPath, "--version"],
timeoutMs: 10_000,
}); // Output is typically "signal-cli 0.13.24"
version = vResult.stdout.trim().replace(/^signal-cli\s+/, "") || undefined;
} catch { // non-critical; leave version undefined
}
return { ok: true, cliPath, version };
}
// --------------------------------------------------------------------------- // Direct download install (used when an official native asset is available) // ---------------------------------------------------------------------------
const cliPath = await findSignalCliBinary(installRoot); if (!cliPath) { return {
ok: false,
error: `signal-cli binary not found after extracting ${asset.name}`,
};
}
await fs.chmod(cliPath, 0o755).catch(() => {});
return { ok: true, cliPath, version };
}
// --------------------------------------------------------------------------- // Public entry point // ---------------------------------------------------------------------------
export async function installSignalCli(runtime: RuntimeEnv): Promise<SignalInstallResult> { if (process.platform === "win32") { return {
ok: false,
error: "Signal CLI auto-install is not supported on Windows yet.",
};
}
// The official signal-cli GitHub releases only ship a native binary for // x86-64 Linux. On other architectures (arm64, armv7, etc.) we delegate // to Homebrew which builds from source and bundles the JRE automatically. const hasNativeRelease = process.platform !== "linux" || process.arch === "x64";
if (hasNativeRelease) { return installSignalCliFromRelease(runtime);
}
return installSignalCliViaBrew(runtime);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet am 2026-06-05)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.