Skip to content

Commit e234235

Browse files
committed
fix: use original-fs and temp dir for lightweight update on macOS
- Download update files to temp directory first - Use original-fs to bypass Electron ASAR interception when copying - Fallback to cp command for macOS permission issues - Clean up temp files after update
1 parent 1ffd81d commit e234235

3 files changed

Lines changed: 32 additions & 5 deletions

File tree

electron/main.cjs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const fs = require('node:fs')
2+
const originalFs = require('original-fs') // bypass Electron's ASAR interception
23
const os = require('node:os')
34
const path = require('node:path')
45
const https = require('node:https')
@@ -713,6 +714,12 @@ async function applyLightweightUpdate() {
713714
throw new Error('No downloadable assets found in release')
714715
}
715716

717+
// Download all files to a temp directory first
718+
const tempDir = path.join(app.getPath('temp'), 'copilot-proxy-update')
719+
if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir, { recursive: true })
720+
721+
const downloadedFiles = []
722+
716723
for (const { asset, key } of filesToUpdate) {
717724
const progressBase = (filesDone / filesToUpdate.length) * 100
718725
const progressRange = 100 / filesToUpdate.length
@@ -730,11 +737,31 @@ async function applyLightweightUpdate() {
730737
}
731738
}
732739

733-
const dest = path.join(resourcesPath, key)
734-
fs.writeFileSync(dest, data)
740+
const tempFile = path.join(tempDir, key)
741+
fs.writeFileSync(tempFile, data)
742+
downloadedFiles.push({ tempFile, destFile: path.join(resourcesPath, key), key })
735743
filesDone++
736744
}
737745

746+
// Copy files from temp to resources using original-fs (bypasses ASAR interception)
747+
for (const { tempFile, destFile, key } of downloadedFiles) {
748+
try {
749+
originalFs.copyFileSync(tempFile, destFile)
750+
} catch (copyErr) {
751+
// On macOS, /Applications may need elevated permissions
752+
if (process.platform === 'darwin' && (copyErr.code === 'EACCES' || copyErr.code === 'EPERM')) {
753+
// Use cp command with shell as fallback
754+
const { execSync } = require('node:child_process')
755+
execSync(`cp "${tempFile}" "${destFile}"`)
756+
} else {
757+
throw copyErr
758+
}
759+
}
760+
}
761+
762+
// Clean up temp files
763+
try { fs.rmSync(tempDir, { recursive: true, force: true }) } catch { /* ignore */ }
764+
738765
updateState = { ...updateState, downloading: false, progress: 100 }
739766
notifyUpdateState()
740767

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "copilot-proxy-gui",
33
"private": true,
4-
"version": "0.2.5",
4+
"version": "0.2.6",
55
"description": "Desktop GUI for copilot-proxy — Electron + React + Vite",
66
"type": "module",
77
"main": "electron/main.cjs",

0 commit comments

Comments
 (0)