diff --git a/package.json b/package.json index 2f862f2d5..35ce70914 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawx", - "version": "0.2.9", + "version": "0.3.0-alpha.0", "pnpm": { "onlyBuiltDependencies": [ "@discordjs/opus", @@ -15,6 +15,15 @@ "overrides": { "isbinaryfile": "^5.0.0", "https-proxy-agent": "7.0.6" + }, + "supportedArchitectures": { + "os": [ + "current" + ], + "cpu": [ + "x64", + "arm64" + ] } }, "description": "ClawX - Graphical AI Assistant based on OpenClaw", @@ -129,4 +138,4 @@ "zx": "^8.8.5" }, "packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268" -} +} \ No newline at end of file diff --git a/scripts/after-pack.cjs b/scripts/after-pack.cjs index 4bd94af1d..7c7972e36 100644 --- a/scripts/after-pack.cjs +++ b/scripts/after-pack.cjs @@ -101,16 +101,52 @@ function cleanupKoffi(nodeModulesDir, platform, arch) { // ── Platform-specific: scoped native packages ──────────────────────────────── // Packages like @napi-rs/canvas-darwin-arm64, @img/sharp-linux-x64, etc. // Only the variant matching the target platform should survive. +// +// Some packages use non-standard platform names: +// - @node-llama-cpp: "mac" instead of "darwin", "win" instead of "win32" +// - sqlite-vec: "windows" instead of "win32" (unscoped, handled separately) +// We normalise them before comparison. +const PLATFORM_ALIASES = { + darwin: 'darwin', mac: 'darwin', + linux: 'linux', linuxmusl: 'linux', + win32: 'win32', win: 'win32', windows: 'win32', +}; + +// Each regex MUST have capture group 1 = platform name and group 2 = arch name. +// Compound arch suffixes (e.g. "x64-msvc", "arm64-gnu", "arm64-metal") are OK — +// we strip the suffix after the first dash to get the base arch. const PLATFORM_NATIVE_SCOPES = { '@napi-rs': /^canvas-(darwin|linux|win32)-(x64|arm64)/, - '@img': /^sharp(?:-libvips)?-(darwin|linux|win32)-(x64|arm64)/, + '@img': /^sharp(?:-libvips)?-(darwin|linux(?:musl)?|win32)-(x64|arm64|arm|ppc64|riscv64|s390x)/, '@mariozechner': /^clipboard-(darwin|linux|win32)-(x64|arm64|universal)/, + '@snazzah': /^davey-(darwin|linux|android|freebsd|win32|wasm32)-(x64|arm64|arm|ia32|arm64-gnu|arm64-musl|x64-gnu|x64-musl|x64-msvc|arm64-msvc|ia32-msvc|arm-eabi|arm-gnueabihf|wasi)/, + '@lydell': /^node-pty-(darwin|linux|win32)-(x64|arm64)/, + '@reflink': /^reflink-(darwin|linux|win32)-(x64|arm64|x64-gnu|x64-musl|arm64-gnu|arm64-musl|x64-msvc|arm64-msvc)/, + '@node-llama-cpp': /^(mac|linux|win)-(arm64|x64|armv7l)(-metal|-cuda|-cuda-ext|-vulkan)?$/, + '@esbuild': /^(darwin|linux|win32|android|freebsd|netbsd|openbsd|sunos|aix|openharmony)-(x64|arm64|arm|ia32|loong64|mips64el|ppc64|riscv64|s390x)/, }; +// Unscoped packages that follow a -- convention. +// Each entry: { prefix, pattern } where pattern captures (platform, arch). +const UNSCOPED_NATIVE_PACKAGES = [ + // sqlite-vec uses "windows" instead of "win32" + { prefix: 'sqlite-vec-', pattern: /^sqlite-vec-(darwin|linux|windows)-(x64|arm64)$/ }, +]; + +/** + * Normalise the base arch from a potentially compound value. + * e.g. "x64-msvc" → "x64", "arm64-gnu" → "arm64", "arm64-metal" → "arm64" + */ +function baseArch(rawArch) { + const dash = rawArch.indexOf('-'); + return dash > 0 ? rawArch.slice(0, dash) : rawArch; +} + function cleanupNativePlatformPackages(nodeModulesDir, platform, arch) { let removed = 0; + // 1. Scoped packages (e.g. @snazzah/davey-darwin-arm64) for (const [scope, pattern] of Object.entries(PLATFORM_NATIVE_SCOPES)) { const scopeDir = join(nodeModulesDir, scope); if (!existsSync(scopeDir)) continue; @@ -119,8 +155,8 @@ function cleanupNativePlatformPackages(nodeModulesDir, platform, arch) { const match = entry.match(pattern); if (!match) continue; // not a platform-specific package, leave it - const pkgPlatform = match[1]; - const pkgArch = match[2]; + const pkgPlatform = PLATFORM_ALIASES[match[1]] || match[1]; + const pkgArch = baseArch(match[2]); const isMatch = pkgPlatform === platform && @@ -135,6 +171,31 @@ function cleanupNativePlatformPackages(nodeModulesDir, platform, arch) { } } + // 2. Unscoped packages (e.g. sqlite-vec-darwin-arm64) + for (const { pattern } of UNSCOPED_NATIVE_PACKAGES) { + let entries; + try { entries = readdirSync(nodeModulesDir); } catch { continue; } + + for (const entry of entries) { + const match = entry.match(pattern); + if (!match) continue; + + const pkgPlatform = PLATFORM_ALIASES[match[1]] || match[1]; + const pkgArch = baseArch(match[2]); + + const isMatch = + pkgPlatform === platform && + (pkgArch === arch || pkgArch === 'universal'); + + if (!isMatch) { + try { + rmSync(join(nodeModulesDir, entry), { recursive: true, force: true }); + removed++; + } catch { /* */ } + } + } + } + return removed; }