chore: Finalize PR #116 stability and privacy improvements

- Hardened IPC with safety guards for all webContents.send calls
- Scrubbed sensitive absolute paths from caption logs
- Realigned Windows artifact naming logic
This commit is contained in:
Mahdy Arief
2026-03-27 23:14:12 +07:00
51 changed files with 2518 additions and 807 deletions
+46 -19
View File
@@ -1,5 +1,5 @@
import { execSync } from "node:child_process";
import { existsSync, mkdirSync } from "node:fs";
import { existsSync, mkdirSync, rmSync } from "node:fs";
import path from "node:path";
const projectRoot = process.cwd();
@@ -31,29 +31,47 @@ function findCmake() {
return `"${localCmake}"`;
}
// VS 2022 bundled CMake
const vsEditions = ["Community", "Professional", "Enterprise", "BuildTools"];
for (const edition of vsEditions) {
const cmakePath = path.join(
"C:",
"Program Files",
"Microsoft Visual Studio",
"2022",
edition,
"Common7",
"IDE",
"CommonExtensions",
"Microsoft",
"CMake",
"CMake",
"bin",
"cmake.exe",
);
// Standalone CMake paths
const standaloneCmakePaths = [
path.join("C:", "Program Files", "CMake", "bin", "cmake.exe"),
path.join("C:", "Program Files (x86)", "CMake", "bin", "cmake.exe"),
];
for (const cmakePath of standaloneCmakePaths) {
if (existsSync(cmakePath)) {
return `"${cmakePath}"`;
}
}
// VS 2022/2019 bundled CMake
const vsRoots = [
path.join("C:", "Program Files", "Microsoft Visual Studio"),
path.join("C:", "Program Files (x86)", "Microsoft Visual Studio"),
];
const vsEditions = ["Community", "Professional", "Enterprise", "BuildTools"];
const vsVersions = ["2022", "2019"];
for (const root of vsRoots) {
for (const version of vsVersions) {
for (const edition of vsEditions) {
const cmakePath = path.join(
root,
version,
edition,
"Common7",
"IDE",
"CommonExtensions",
"Microsoft",
"CMake",
"CMake",
"bin",
"cmake.exe",
);
if (existsSync(cmakePath)) {
return `"${cmakePath}"`;
}
}
}
}
return null;
}
@@ -66,9 +84,17 @@ if (!cmake) {
}
mkdirSync(buildDir, { recursive: true });
const cacheFile = path.join(buildDir, "CMakeCache.txt");
const cacheDir = path.join(buildDir, "CMakeFiles");
function clearCmakeCache() {
rmSync(cacheFile, { force: true });
rmSync(cacheDir, { recursive: true, force: true });
}
console.log("[build-cursor-monitor] Configuring CMake...");
try {
clearCmakeCache();
execSync(`${cmake} .. -G "Visual Studio 17 2022" -A x64`, {
cwd: buildDir,
stdio: "inherit",
@@ -77,6 +103,7 @@ try {
} catch {
console.log("[build-cursor-monitor] VS 2022 generator not found, trying VS 2019...");
try {
clearCmakeCache();
execSync(`${cmake} .. -G "Visual Studio 16 2019" -A x64`, {
cwd: buildDir,
stdio: "inherit",
+69 -22
View File
@@ -10,6 +10,11 @@ const nativeRoot = path.join(projectRoot, "electron", "native");
const cacheRoot = path.join(projectRoot, ".tmp", "whisper-runtime");
const archivePath = path.join(cacheRoot, `${whisperVersion}.tar.gz`);
const extractRoot = path.join(cacheRoot, `src-${whisperVersion}`);
function getHostArch() {
return process.arch === "arm64" ? "arm64" : "x64";
}
function getNativeArchTag(platform, arch) {
if (platform === "darwin") {
return arch === "arm64" ? "darwin-arm64" : "darwin-x64";
@@ -26,29 +31,66 @@ function getNativeArchTag(platform, arch) {
throw new Error(`[build-whisper-runtime] Unsupported platform: ${platform}/${arch}`);
}
function getTargetConfigs() {
if (process.platform === "darwin") {
return [
{
platform: "darwin",
arch: "arm64",
archTag: getNativeArchTag("darwin", "arm64"),
buildRoot: path.join(cacheRoot, "build-darwin-arm64"),
outputDir: path.join(nativeRoot, "bin", getNativeArchTag("darwin", "arm64")),
configureArgs: ["-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_OSX_ARCHITECTURES=arm64"],
},
{
platform: "darwin",
arch: "x64",
archTag: getNativeArchTag("darwin", "x64"),
buildRoot: path.join(cacheRoot, "build-darwin-x64"),
outputDir: path.join(nativeRoot, "bin", getNativeArchTag("darwin", "x64")),
configureArgs: ["-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_OSX_ARCHITECTURES=x86_64"],
},
];
function getRequestedArchitectures(platform) {
const hostArch = getHostArch();
const configured = process.env.WHISPER_RUNTIME_ARCHS?.trim();
if (!configured) {
return [hostArch];
}
const arch = process.arch === "arm64" ? "arm64" : "x64";
if (configured === "all") {
return ["arm64", "x64"];
}
const supported = new Set(["arm64", "x64"]);
const requested = configured
.split(",")
.map((entry) => entry.trim())
.filter(Boolean);
if (requested.length === 0) {
return [hostArch];
}
const invalid = requested.filter((arch) => !supported.has(arch));
if (invalid.length > 0) {
throw new Error(
`[build-whisper-runtime] Unsupported ${platform} target architecture request: ${invalid.join(", ")}`,
);
}
return [...new Set(requested)];
}
function createDarwinTarget(arch) {
const targetArch = arch === "arm64" ? "arm64" : "x64";
const isCrossCompile = targetArch !== getHostArch();
const configureArgs = [
"-DCMAKE_BUILD_TYPE=Release",
`-DCMAKE_OSX_ARCHITECTURES=${targetArch === "arm64" ? "arm64" : "x86_64"}`,
];
if (isCrossCompile) {
configureArgs.push("-DGGML_NATIVE=OFF");
}
return {
platform: "darwin",
arch: targetArch,
archTag: getNativeArchTag("darwin", targetArch),
buildRoot: path.join(cacheRoot, `build-darwin-${targetArch}`),
outputDir: path.join(nativeRoot, "bin", getNativeArchTag("darwin", targetArch)),
configureArgs,
};
}
function getTargetConfigs() {
if (process.platform === "darwin") {
return getRequestedArchitectures("darwin").map((arch) => createDarwinTarget(arch));
}
const arch = getHostArch();
const archTag = getNativeArchTag(process.platform, arch);
if (process.platform === "win32") {
@@ -326,8 +368,13 @@ async function main() {
}
const sourceDir = await ensureSourceTree();
const targets = getTargetConfigs();
for (const target of getTargetConfigs()) {
console.log(
`[build-whisper-runtime] Target architectures for ${process.platform}: ${targets.map((target) => target.archTag).join(", ")}`,
);
for (const target of targets) {
if (await shouldSkipBuild(target)) {
console.log(
`[build-whisper-runtime] Whisper runtime ${whisperVersion} already staged for ${target.archTag}.`,
+106 -66
View File
@@ -1,96 +1,136 @@
import { execSync } from 'node:child_process';
import { mkdirSync, existsSync } from 'node:fs';
import path from 'node:path';
import { execSync } from "node:child_process";
import { mkdirSync, existsSync, rmSync } from "node:fs";
import path from "node:path";
const projectRoot = process.cwd();
const sourceDir = path.join(projectRoot, 'electron', 'native', 'wgc-capture');
const buildDir = path.join(sourceDir, 'build');
const sourceDir = path.join(projectRoot, "electron", "native", "wgc-capture");
const buildDir = path.join(sourceDir, "build");
if (process.platform !== 'win32') {
console.log('[build-windows-capture] Skipping native Windows capture build: host platform is not Windows.');
process.exit(0);
if (process.platform !== "win32") {
console.log("[build-windows-capture] Skipping native Windows capture build: host platform is not Windows.");
process.exit(0);
}
if (!existsSync(path.join(sourceDir, 'CMakeLists.txt'))) {
console.error('[build-windows-capture] CMakeLists.txt not found at', sourceDir);
process.exit(1);
if (!existsSync(path.join(sourceDir, "CMakeLists.txt"))) {
console.error("[build-windows-capture] CMakeLists.txt not found at", sourceDir);
process.exit(1);
}
function findCmake() {
// Check PATH first
try {
execSync('cmake --version', { stdio: 'pipe' });
return 'cmake';
} catch {
// not on PATH
}
// Check PATH first
try {
execSync("cmake --version", { stdio: "pipe" });
return "cmake";
} catch {
// not on PATH
}
// Local .cmake_ext path
const localCmake = path.join(projectRoot, '.cmake_ext', 'cmake-4.3.0-windows-x86_64', 'bin', 'cmake.exe');
if (existsSync(localCmake)) {
return `"${localCmake}"`;
}
// Local .cmake_ext path
const localCmake = path.join(projectRoot, ".cmake_ext", "cmake-4.3.0-windows-x86_64", "bin", "cmake.exe");
if (existsSync(localCmake)) {
return `"${localCmake}"`;
}
// VS 2022 bundled CMake
const vsEditions = ['Community', 'Professional', 'Enterprise', 'BuildTools'];
for (const edition of vsEditions) {
const cmakePath = path.join(
'C:', 'Program Files', 'Microsoft Visual Studio', '2022', edition,
'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'CMake', 'CMake', 'bin', 'cmake.exe'
);
if (existsSync(cmakePath)) {
return `"${cmakePath}"`;
}
}
// Standalone CMake paths
const standaloneCmakePaths = [
path.join("C:", "Program Files", "CMake", "bin", "cmake.exe"),
path.join("C:", "Program Files (x86)", "CMake", "bin", "cmake.exe"),
];
for (const cmakePath of standaloneCmakePaths) {
if (existsSync(cmakePath)) {
return `"${cmakePath}"`;
}
}
return null;
// VS 2022/2019 bundled CMake
const vsRoots = [
path.join("C:", "Program Files", "Microsoft Visual Studio"),
path.join("C:", "Program Files (x86)", "Microsoft Visual Studio"),
];
const vsEditions = ["Community", "Professional", "Enterprise", "BuildTools"];
const vsVersions = ["2022", "2019"];
for (const root of vsRoots) {
for (const version of vsVersions) {
for (const edition of vsEditions) {
const cmakePath = path.join(
root,
version,
edition,
"Common7",
"IDE",
"CommonExtensions",
"Microsoft",
"CMake",
"CMake",
"bin",
"cmake.exe",
);
if (existsSync(cmakePath)) {
return `"${cmakePath}"`;
}
}
}
}
return null;
}
const cmake = findCmake();
if (!cmake) {
console.error('[build-windows-capture] CMake not found. Install Visual Studio with C++ CMake tools or standalone CMake.');
process.exit(1);
console.error(
"[build-windows-capture] CMake not found. Install Visual Studio with C++ CMake tools or standalone CMake.",
);
process.exit(1);
}
mkdirSync(buildDir, { recursive: true });
const cacheFile = path.join(buildDir, "CMakeCache.txt");
const cacheDir = path.join(buildDir, "CMakeFiles");
console.log('[build-windows-capture] Configuring CMake...');
function clearCmakeCache() {
rmSync(cacheFile, { force: true });
rmSync(cacheDir, { recursive: true, force: true });
}
console.log("[build-windows-capture] Configuring CMake...");
try {
execSync(`${cmake} .. -G "Visual Studio 17 2022" -A x64`, {
cwd: buildDir,
stdio: 'inherit',
timeout: 120000,
});
clearCmakeCache();
execSync(`${cmake} .. -G "Visual Studio 17 2022" -A x64`, {
cwd: buildDir,
stdio: "inherit",
timeout: 120000,
});
} catch {
console.log('[build-windows-capture] VS 2022 generator not found, trying VS 2019...');
try {
execSync(`${cmake} .. -G "Visual Studio 16 2019" -A x64`, {
cwd: buildDir,
stdio: 'inherit',
timeout: 120000,
});
} catch (innerError) {
console.error('[build-windows-capture] CMake configure failed:', innerError.message);
process.exit(1);
}
console.log("[build-windows-capture] VS 2022 generator not found, trying VS 2019...");
try {
clearCmakeCache();
execSync(`${cmake} .. -G "Visual Studio 16 2019" -A x64`, {
cwd: buildDir,
stdio: "inherit",
timeout: 120000,
});
} catch (innerError) {
console.error("[build-windows-capture] CMake configure failed:", innerError.message);
process.exit(1);
}
}
console.log('[build-windows-capture] Building native Windows capture helper...');
console.log("[build-windows-capture] Building native Windows capture helper...");
try {
execSync(`${cmake} --build . --config Release`, {
cwd: buildDir,
stdio: 'inherit',
timeout: 300000,
});
execSync(`${cmake} --build . --config Release`, {
cwd: buildDir,
stdio: "inherit",
timeout: 300000,
});
} catch (error) {
console.error('[build-windows-capture] Build failed:', error.message);
process.exit(1);
console.error("[build-windows-capture] Build failed:", error.message);
process.exit(1);
}
const exePath = path.join(buildDir, 'Release', 'wgc-capture.exe');
const exePath = path.join(buildDir, "Release", "wgc-capture.exe");
if (existsSync(exePath)) {
console.log(`[build-windows-capture] Built successfully: ${exePath}`);
console.log(`[build-windows-capture] Built successfully: ${exePath}`);
} else {
console.error('[build-windows-capture] Expected exe not found at', exePath);
process.exit(1);
console.error("[build-windows-capture] Expected exe not found at", exePath);
process.exit(1);
}
+53
View File
@@ -0,0 +1,53 @@
import { spawnSync } from "node:child_process";
const npmExecPath = process.env.npm_execpath;
const hasNpmExecPath = typeof npmExecPath === "string" && npmExecPath.length > 0;
const npmInvoker = hasNpmExecPath
? {
command: process.execPath,
argsPrefix: [npmExecPath],
shell: false,
}
: {
command: process.platform === "win32" ? "npm.cmd" : "npm",
argsPrefix: [],
shell: process.platform === "win32",
};
function runScript(scriptName) {
console.log(`[postinstall] Running npm script: ${scriptName}`);
const result = spawnSync(npmInvoker.command, [...npmInvoker.argsPrefix, "run", scriptName], {
stdio: "inherit",
env: process.env,
shell: npmInvoker.shell,
});
if (result.error) {
console.error(
`[postinstall] Failed to start "${scriptName}" (${result.error.message}).`,
);
return false;
}
if (result.signal) {
console.error(`[postinstall] "${scriptName}" was terminated by signal ${result.signal}.`);
return false;
}
if (result.status !== 0) {
console.error(
`[postinstall] "${scriptName}" exited with code ${result.status}.`,
);
return false;
}
return true;
}
if (!runScript("rebuild:native")) {
process.exit(1);
}
if (!runScript("build:platform-native-helpers")) {
process.exit(1);
}