feat: add Windows ARM64 support with x64-baseline CLI workaround (#2537)
* feat: add Windows ARM64 support with x64-baseline CLI workaround Windows ARM64 native opencode.exe fails with a Bun FFI/TinyCC dlopen error (anomalyco/opencode#19130). As a temporary workaround: - Bundle x64-baseline OpenCode CLI on ARM64 instead of native ARM64 (prepare-opencode-cli.mjs, env-runtime.js) - Disable OpenCode self-upgrade on ARM64 in server, VS Code, and UI (upgrade-capability.js, opencode-upgrade-runtime.ts, useUIStore.ts, OpenCodeCliSettings.tsx, search.ts, SettingsView.tsx, platform.ts) - Add ARM64 Windows cross-compile builds to release and smoke workflows (release.yml, release-desktop-smoke.yml) - Refactor Windows latest.yml to use combine-electron-manifests pattern matching macOS, since two arches now produce per-arch manifests The CI ARM64 build itself is permanent; only the x64-baseline CLI bundling and upgrade disablement are temporary and should be reverted when the upstream issue is resolved. * fix(desktop): select Windows updater by architecture --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
5792a3d2e2
commit
09f0c64839
@@ -16,6 +16,7 @@ import { reloadOpenCodeConfiguration } from '@/stores/useAgentsStore';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import { runtimeFetch } from '@/lib/runtime-fetch';
|
||||
import { isWindowsArm64 } from '@/lib/platform';
|
||||
|
||||
export const OpenCodeCliSettings: React.FC = () => {
|
||||
const { t } = useI18n();
|
||||
@@ -151,13 +152,15 @@ export const OpenCodeCliSettings: React.FC = () => {
|
||||
</SettingsFieldRow>
|
||||
|
||||
<SettingsInset className={SETTINGS_OPTION_STACK_CLASS}>
|
||||
<SettingsCheckboxRow
|
||||
settingsItem="sessions.opencode-update-notifications"
|
||||
checked={showOpenCodeUpdateNotifications}
|
||||
onChange={handleShowUpdateNotificationsChange}
|
||||
label={t('settings.openchamber.opencodeCli.field.showUpdateNotifications')}
|
||||
ariaLabel={t('settings.openchamber.opencodeCli.field.showUpdateNotificationsAria')}
|
||||
/>
|
||||
{!isWindowsArm64() && (
|
||||
<SettingsCheckboxRow
|
||||
settingsItem="sessions.opencode-update-notifications"
|
||||
checked={showOpenCodeUpdateNotifications}
|
||||
onChange={handleShowUpdateNotificationsChange}
|
||||
label={t('settings.openchamber.opencodeCli.field.showUpdateNotifications')}
|
||||
ariaLabel={t('settings.openchamber.opencodeCli.field.showUpdateNotificationsAria')}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SettingsCheckboxRow
|
||||
settingsItem="sessions.agent-control-tool"
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
} from '@/components/sections/shared/SettingsSection';
|
||||
import { useDeviceInfo } from '@/lib/device';
|
||||
import { isDesktopLocalOriginActive, isDesktopShell, isVSCodeRuntime, isWebRuntime } from '@/lib/desktop';
|
||||
import { isWindowsArm64 as isWindowsArm64Platform } from '@/lib/platform';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import { Icon } from "@/components/icon/Icon";
|
||||
import type { IconName } from "@/components/icon/icons";
|
||||
@@ -278,6 +279,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
||||
return isDesktopShell() && typeof window !== 'undefined'
|
||||
&& (window as unknown as { __OPENCHAMBER_PLATFORM__?: string }).__OPENCHAMBER_PLATFORM__ === 'linux';
|
||||
}, []);
|
||||
const isWindowsArm64 = React.useMemo(() => isWindowsArm64Platform(), []);
|
||||
|
||||
// keep platform check available for future window chrome tweaks
|
||||
|
||||
@@ -421,12 +423,12 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
||||
const settingsSearchResults = React.useMemo(() => {
|
||||
return buildSettingsSearchResults({
|
||||
query: settingsSearchQuery,
|
||||
runtimeCtx: { ...runtimeCtx, isDesktopLocalOrigin, isMac, isWindows, isLinux },
|
||||
runtimeCtx: { ...runtimeCtx, isDesktopLocalOrigin, isMac, isWindows, isLinux, isWindowsArm64 },
|
||||
visiblePageSlugs,
|
||||
t,
|
||||
getPageTitle,
|
||||
});
|
||||
}, [getPageTitle, isDesktopLocalOrigin, isMac, isWindows, isLinux, runtimeCtx, settingsSearchQuery, t, visiblePageSlugs]);
|
||||
}, [getPageTitle, isWindowsArm64, isDesktopLocalOrigin, isMac, isWindows, isLinux, runtimeCtx, settingsSearchQuery, t, visiblePageSlugs]);
|
||||
|
||||
const prepareSettingsSearchTarget = React.useCallback((result: SettingsSearchResult): string => {
|
||||
if (result.id.startsWith('agents.')) {
|
||||
|
||||
@@ -7,6 +7,39 @@ export const isCapacitorApp = (): boolean => {
|
||||
return capacitor?.isNativePlatform?.() === true || window.location.protocol === 'capacitor:';
|
||||
};
|
||||
|
||||
// TEMPORARY WORKAROUND — Windows ARM64: native opencode.exe fails with a Bun
|
||||
// FFI/TinyCC dlopen error (https://github.com/anomalyco/opencode/issues/19130).
|
||||
// Suppress OpenCode update UI on ARM64 so it can't self-upgrade to the broken
|
||||
// ARM64 build. Remove this helper and its call sites when resolved upstream.
|
||||
export const isWindowsArm64 = (): boolean => {
|
||||
if (typeof window === 'undefined') return false;
|
||||
|
||||
const electronArch = window.__OPENCHAMBER_ELECTRON__?.arch?.toLowerCase?.();
|
||||
if (electronArch === 'arm64' || electronArch === 'aarch64') {
|
||||
const platform = (navigator.platform || '').toLowerCase();
|
||||
return platform.includes('win');
|
||||
}
|
||||
|
||||
const vscodeArch = (window as { __VSCODE_CONFIG__?: { arch?: string } }).__VSCODE_CONFIG__?.arch?.toLowerCase?.();
|
||||
if (vscodeArch === 'arm64' || vscodeArch === 'aarch64') {
|
||||
const platform = (navigator.platform || '').toLowerCase();
|
||||
return platform.includes('win');
|
||||
}
|
||||
|
||||
const nav = (navigator as Navigator & { userAgentData?: { architecture?: string; platform?: string } }).userAgentData;
|
||||
if (nav?.architecture?.toLowerCase?.() === 'arm64' || nav?.architecture?.toLowerCase?.() === 'aarch64') {
|
||||
const platform = (nav.platform || navigator.platform || '').toLowerCase();
|
||||
return platform.includes('win');
|
||||
}
|
||||
|
||||
const ua = navigator.userAgent.toLowerCase();
|
||||
if ((ua.includes('aarch64') || ua.includes('arm64') || ua.includes('armv')) && ua.includes('windows')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* True when running inside the native Capacitor shell on an iPad.
|
||||
* Capacitor reports 'ios' for both iPhone and iPad; iPadOS WKWebView
|
||||
|
||||
@@ -26,6 +26,8 @@ interface SettingsSearchAvailabilityContext extends SettingsRuntimeContext {
|
||||
isWindows: boolean;
|
||||
// Linux desktop shell — for controls that only render on linux.
|
||||
isLinux: boolean;
|
||||
// Windows ARM64 — temporary workaround gate (see opencode#19130).
|
||||
isWindowsArm64: boolean;
|
||||
}
|
||||
|
||||
const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
|
||||
@@ -470,7 +472,7 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
|
||||
page: 'general',
|
||||
titleKey: 'settings.openchamber.opencodeCli.field.showUpdateNotifications',
|
||||
keywords: ['opencode', 'cli', 'updates'],
|
||||
isAvailable: (ctx) => !ctx.isVSCode,
|
||||
isAvailable: (ctx) => !ctx.isVSCode && !ctx.isWindowsArm64,
|
||||
},
|
||||
{
|
||||
id: 'sessions.agent-control-tool',
|
||||
|
||||
@@ -10,6 +10,7 @@ import { getStoredMobileKeyboardMode, type MobileKeyboardMode } from '@/lib/mobi
|
||||
import { getRuntimeKey } from '@/lib/runtime-switch';
|
||||
import type { TerminalShell } from '@/lib/api/types';
|
||||
import { useFilesViewTabsStore } from './useFilesViewTabsStore';
|
||||
import { isWindowsArm64 } from '@/lib/platform';
|
||||
|
||||
export type MainTab = 'chat' | 'plan' | 'git' | 'diff' | 'terminal' | 'files' | 'context' | 'diagram';
|
||||
export type PendingDiffScope = 'working' | 'staged' | 'turn';
|
||||
@@ -999,7 +1000,7 @@ export const useUIStore = create<UIStore>()(
|
||||
|
||||
showTerminalQuickKeysOnDesktop: false,
|
||||
persistChatDraft: true,
|
||||
showOpenCodeUpdateNotifications: true,
|
||||
showOpenCodeUpdateNotifications: !isWindowsArm64(),
|
||||
agentControlToolEnabled: true,
|
||||
inputSpellcheckEnabled: false,
|
||||
wideChatLayoutEnabled: false,
|
||||
|
||||
Reference in New Issue
Block a user