fix(desktop): warn about Rosetta installs on Apple Silicon (#621)

* fix(desktop): warn about Rosetta installs on Apple Silicon

* docs: note workspace build sync before type fixes
This commit is contained in:
Mohamed Boudra
2026-04-30 13:13:30 +08:00
committed by GitHub
parent f0a8f207f8
commit 6a61066e2c
8 changed files with 261 additions and 0 deletions
@@ -38,6 +38,7 @@ import {
type DesktopCommandHandler,
} from "../settings/desktop-settings-commands.js";
import { getDesktopSettingsStore } from "../settings/desktop-settings-electron.js";
import { isRunningUnderARM64Translation } from "../system/arm64-translation.js";
const DAEMON_LOG_FILENAME = "daemon.log";
const PID_POLL_INTERVAL_MS = 100;
@@ -525,6 +526,10 @@ async function resolveRequestedReleaseChannel(
export function createDaemonCommandHandlers(): Record<string, DesktopCommandHandler> {
return {
...createDesktopSettingsCommandHandlers({ settingsStore: getDesktopSettingsStore() }),
desktop_get_runtime_info: () => ({
appVersion: resolveDesktopAppVersion(),
runningUnderARM64Translation: isRunningUnderARM64Translation(),
}),
desktop_daemon_status: () => resolveDesktopDaemonStatus(),
start_desktop_daemon: () => startDaemon(),
stop_desktop_daemon: () => stopDesktopDaemon(),
@@ -0,0 +1,59 @@
import { describe, expect, it, vi } from "vitest";
import { detectRunningUnderARM64Translation } from "./arm64-translation";
describe("detectRunningUnderARM64Translation", () => {
it("returns false outside macOS without probing sysctl", () => {
const execFileSyncImpl = vi.fn();
expect(
detectRunningUnderARM64Translation({
platform: "linux",
electronReportedTranslation: true,
execFileSyncImpl,
}),
).toBe(false);
expect(execFileSyncImpl).not.toHaveBeenCalled();
});
it("trusts Electron when it reports ARM64 translation", () => {
const execFileSyncImpl = vi.fn();
expect(
detectRunningUnderARM64Translation({
platform: "darwin",
electronReportedTranslation: true,
execFileSyncImpl,
}),
).toBe(true);
expect(execFileSyncImpl).not.toHaveBeenCalled();
});
it("falls back to sysctl when Electron does not report translation", () => {
const execFileSyncImpl = vi.fn(() => "1\n");
expect(
detectRunningUnderARM64Translation({
platform: "darwin",
electronReportedTranslation: false,
execFileSyncImpl,
}),
).toBe(true);
expect(execFileSyncImpl).toHaveBeenCalledWith("sysctl", ["-in", "sysctl.proc_translated"], {
encoding: "utf-8",
timeout: 1000,
});
});
it("treats missing sysctl support as not translated", () => {
const execFileSyncImpl = vi.fn(() => {
throw new Error("unknown oid");
});
expect(
detectRunningUnderARM64Translation({
platform: "darwin",
execFileSyncImpl,
}),
).toBe(false);
});
});
@@ -0,0 +1,44 @@
import { execFileSync } from "node:child_process";
import { app } from "electron";
const SYSCTL_TRANSLATED_KEY = "sysctl.proc_translated";
let cachedRunningUnderARM64Translation: boolean | null = null;
export function detectRunningUnderARM64Translation(input: {
platform: NodeJS.Platform;
electronReportedTranslation?: boolean;
execFileSyncImpl?: typeof execFileSync;
}): boolean {
if (input.platform !== "darwin") {
return false;
}
if (input.electronReportedTranslation === true) {
return true;
}
const execImpl = input.execFileSyncImpl ?? execFileSync;
try {
const output = execImpl("sysctl", ["-in", SYSCTL_TRANSLATED_KEY], {
encoding: "utf-8",
timeout: 1000,
});
return output.trim() === "1";
} catch {
return false;
}
}
export function isRunningUnderARM64Translation(): boolean {
if (cachedRunningUnderARM64Translation !== null) {
return cachedRunningUnderARM64Translation;
}
cachedRunningUnderARM64Translation = detectRunningUnderARM64Translation({
platform: process.platform,
electronReportedTranslation: app.runningUnderARM64Translation,
});
return cachedRunningUnderARM64Translation;
}