fix: macOS Node.js install fallback when Homebrew is unavailable, bump v0.17.6

Problem:
- Install wizard on macOS failed with "Homebrew not found" when user
  didn't have Homebrew installed, blocking Claude Code installation entirely

Fix (electron/main.ts):
- Add fallback: when Homebrew is not found, download official Node.js v22.12.0
  binary tarball from nodejs.org and extract to ~/.codepilot/node/
- No Homebrew or sudo required — curl + tar only
- Detects architecture (arm64/x64) via process.arch
- Add ~/.codepilot/node/bin to getExpandedShellPath() so the downloaded
  Node.js is found by subsequent install steps and server launcher

Install flow now: Homebrew found → brew install node (existing)
                  Homebrew missing → download tarball to ~/.codepilot/node/ (new)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-27 15:17:53 +08:00
1 parent 132fdeb255
commit 7fa10cd954
3 files changed
+19 -12

No files matched your search

+16 -9
View File
@@ -199,7 +199,7 @@ function getExpandedShellPath(): string {
return [...new Set(allParts)].join(sep);
} else {
const basePath = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin`;
const raw = `${basePath}:${home}/.npm-global/bin:${home}/.local/bin:${home}/.claude/bin:${shellPath}`;
const raw = `${basePath}:${home}/.npm-global/bin:${home}/.local/bin:${home}/.claude/bin:${home}/.codepilot/node/bin:${shellPath}`;
const allParts = raw.split(':').filter(Boolean);
return [...new Set(allParts)].join(':');
}
@@ -528,17 +528,24 @@ app.whenReady().then(async () => {
let args: string[];
if (isMac) {
// Try Homebrew
// Try Homebrew first, fallback to official tarball download
const brewPaths = ['/opt/homebrew/bin/brew', '/usr/local/bin/brew'];
const brewPath = brewPaths.find(p => fs.existsSync(p));
if (!brewPath) {
addLog('Homebrew not found. Cannot auto-install Node.js on macOS without Homebrew.');
resolve(false);
return;
if (brewPath) {
cmd = brewPath;
args = ['install', 'node'];
addLog(`Running: ${brewPath} install node`);
} else {
// Fallback: download official Node.js binary tarball (no Homebrew/sudo needed)
const arch = process.arch === 'arm64' ? 'arm64' : 'x64';
const nodeVersion = 'v22.12.0';
const nodeDir = path.join(home, '.codepilot', 'node');
const tarballUrl = `https://nodejs.org/dist/${nodeVersion}/node-${nodeVersion}-darwin-${arch}.tar.gz`;
addLog(`Homebrew not found. Downloading Node.js ${nodeVersion} from nodejs.org...`);
addLog(`Architecture: ${arch}, Target: ${nodeDir}`);
cmd = 'sh';
args = ['-c', `mkdir -p "${nodeDir}" && curl -fsSL "${tarballUrl}" | tar xz --strip-components=1 -C "${nodeDir}"`];
}
cmd = brewPath;
args = ['install', 'node'];
addLog(`Running: ${brewPath} install node`);
} else if (isWin) {
cmd = 'winget';
args = ['install', '-e', '--id', 'OpenJS.NodeJS.LTS', '--accept-source-agreements', '--accept-package-agreements'];
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "codepilot",
"version": "0.17.5",
"version": "0.17.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codepilot",
"version": "0.17.5",
"version": "0.17.6",
"dependencies": {
"@ai-sdk/anthropic": "^3.0.47",
"@ai-sdk/google": "^3.0.31",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "codepilot",
"version": "0.17.5",
"version": "0.17.6",
"private": true,
"author": {
"name": "op7418",