Skip to content

Commit 73f4104

Browse files
FinnaXxxclaude
andauthored
Fix Windows ARM64 installer payload corruption and modernize build (#2)
* chore: upgrade to Node 24 / Electron 43 / better-sqlite3 13, and fix the Windows arm64 installer electron 33 -> 43.4.1 (Chromium 150, Node 24.18.1), electron-builder 25 -> 26.15.3, better-sqlite3 11 -> 13.0.3, vite 6 -> 7 with electron-vite 5, @types/node and the documented toolchain to Node 24. Windows on ARM installed without its binaries. Not BCJ2, which is what the payload of the working 0.1.6 x64 installer already uses: electron-builder 26 swapped the bundled 7za 16.02 for a downloaded 7-Zip 24.09, which auto-applies the ARM64 filter (7-Zip 23.01+) to ARM64 PE files, while the NSIS side still ships the Nsis7z plugin built in 2019. The plugin answers "Unsupported Method" for exactly the nine native binaries and installs everything else. Reproduced on the real payload: without the override nine files carry method 0A and a decoder of the plugin's vintage refuses them; with it every file is BCJ LZMA2 and all 135 extract. scripts/electron-builder.cjs sets ELECTRON_BUILDER_7Z_FILTER=BCJ for Windows arm64 only, so x64 keeps the BCJ2 it already ships with and macOS, whose dmg and zip targets never reach the 7z path, is untouched. scripts/verify-windows-installer.cjs runs from afterAllArtifactBuild: it carves the embedded archive out of every .exe and re-tests it with a decoder older than the plugin, so a payload the installer cannot unpack fails the build instead of reaching a release page. CI now builds both Windows installers (arm64 packaged on the x64 runner - the payload is inspected, never executed) so the check has something to inspect on every push. better-sqlite3 13 is a Node-API addon shipping prebuilt binaries for every platform, so the cross-rebuild machinery is gone: scripts/rebuild-native.cjs, the postinstall and rebuild:native scripts, and npmRebuild. Each artifact now carries only the one prebuild it can load. Verified by loading the package's own binary under Electron 43. plist is pinned to 3.1.1: app-builder-lib pins 3.1.0, which calls parseFromString without a mime type, and the existing @xmldom/xmldom 0.9.11 override turns that into an error that fails mac packaging outright. Build targets are now written out in electron.vite.config.ts. electron-vite infers them from a table that ends at Electron 39 and falls back to its oldest entry, so Electron 43 would have compiled to a chrome94/node16 target without a word. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016qb5ER3Mq6Bq2atVoKDo6f * test: surface the child process output behind a signal death, and dump macOS crash reports tests/thread-index.test.ts dies on the macOS runner with SIGABRT and nothing else: the assertion on result.signal runs before the one that carries result.stderr, so the child's stdout and stderr are discarded and the crash has no explanation. Both Electron tests now build the transcript first and pass it to every assertion. The runner writes a stage marker straight to fd 1 before each phase. console.log to a pipe is buffered and lost when a process aborts; a synchronous write is not, so the last marker on stdout names the phase the crash happened in - fixtures, scanSessions, the thread index, or the exit itself. Diagnostic, to be removed once that is known. CI dumps the newest macOS crash reports when a job fails, decoding the .ips to the exception, the termination reason and the faulting thread's frames with the image each frame belongs to. That answers the one question worth answering: whether the process aborts inside Electron or inside better_sqlite3.node. The matrix no longer fail-fasts. A red macOS leg was cancelling the Windows leg, which is the one that builds the installers and runs the payload check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016qb5ER3Mq6Bq2atVoKDo6f * fix(test): download Electron once before the suite runs Electron 33 shipped "postinstall": "node install.js", so its binary was always on disk before tests started. Electron 43 has no install script at all - require('electron') notices the missing binary and downloads it right there, on first use. vitest runs test files in parallel, so several of them hit that at once: the CI log shows two "Downloading Electron binary..." lines, each starting its own download into the same dist/ directory, while another file was already spawning what had been written so far. macOS aborted at launch on the truncated Mach-O - dyld "segment '__TEXT' load command content extends beyond end of file", terminated at launch, which is where the SIGABRT came from. Windows failed to spawn at all. Whichever file happened to lose the race failed while its twin, arriving two seconds later, passed against a complete binary. A vitest globalSetup resolves the binary once, before the first test file, so the download can no longer overlap a spawn. Nothing in the app changed, and this is not CI-specific: a fresh clone with a cold Electron cache raced the same way locally. The stage markers added while diagnosing this are gone - the process died before any of the runner's JavaScript ran, so they never had anything to report. The two things that did the work stay: the assertion transcript, which carried the dyld message that named the cause, and the macOS crash-report decoder in CI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016qb5ER3Mq6Bq2atVoKDo6f * chore: release v0.1.7 Only this branch's work stands between v0.1.6 and this release: the Electron 43 / Node 24 / better-sqlite3 13 upgrade, the Windows arm64 installer fix, and the test and CI changes that came out of it. Nothing under electron/, src/ or shared/ was touched, so the release notes lead with the one thing users can actually feel - Electron 43 requires macOS 12, where 0.1.6 ran on macOS 11. Both numbers are read from the two Electron builds' own Info.plist. The notes say the published Windows installer is x64 only, because it is: the release workflow builds --win nsis --x64 and nothing else. The arm64 fix is described as what it is, something that matters when building your own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016qb5ER3Mq6Bq2atVoKDo6f --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b92cd47 commit 73f4104

18 files changed

Lines changed: 1188 additions & 1492 deletions

‎.github/workflows/ci.yml‎

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ concurrency:
1212
jobs:
1313
test:
1414
strategy:
15+
# One platform's failure must not cancel the other's: the Windows leg is where the
16+
# installer payload check runs, and it is worth seeing even when macOS is red.
17+
fail-fast: false
1518
matrix:
1619
os: [xcode-27, windows-latest]
1720
runs-on: ${{ matrix.os }}
@@ -22,11 +25,61 @@ jobs:
2225
version: 11.19.0
2326
- uses: actions/setup-node@v4
2427
with:
25-
node-version: 22
28+
node-version: 24
2629
cache: pnpm
2730
- run: pnpm install --frozen-lockfile
2831
- run: pnpm typecheck
2932
- run: pnpm test
33+
# Tests spawn real Electron binaries, and a process killed by a signal reports no
34+
# message of its own. macOS writes the reason to a crash report instead, so decode it
35+
# here rather than leaving a future failure as the bare word "SIGABRT".
36+
- name: Report macOS crash logs
37+
if: failure() && runner.os == 'macOS'
38+
run: |
39+
sleep 10
40+
python3 - <<'PY'
41+
import glob, json, os
42+
paths = glob.glob(os.path.expanduser('~/Library/Logs/DiagnosticReports/*.ips'))
43+
paths += glob.glob('/Library/Logs/DiagnosticReports/*.ips')
44+
paths.sort(key=os.path.getmtime)
45+
if not paths:
46+
print('no crash reports found')
47+
for path in paths[-3:]:
48+
print('=' * 70)
49+
print(path)
50+
head, _, rest = open(path, errors='replace').read().partition('\n')
51+
try:
52+
meta, body = json.loads(head), json.loads(rest)
53+
except ValueError:
54+
print(head)
55+
print(rest[:4000])
56+
continue
57+
print('process ', meta.get('app_name'), meta.get('app_version'), meta.get('bug_type'))
58+
print('exception ', body.get('exception'))
59+
print('termination', body.get('termination'))
60+
images = body.get('usedImages', [])
61+
faulting = body.get('faultingThread')
62+
for index, thread in enumerate(body.get('threads', [])):
63+
if faulting is not None and index != faulting:
64+
continue
65+
print('faulting thread', index, thread.get('name') or thread.get('queue') or '')
66+
for frame in thread.get('frames', [])[:30]:
67+
where = frame.get('imageIndex', -1)
68+
image = images[where] if 0 <= where < len(images) else {}
69+
print(' ', image.get('name', '?'), hex(frame.get('imageOffset', 0)), frame.get('symbol', ''))
70+
PY
3071
- run: pnpm build
3172
- name: Package (without publishing)
32-
run: pnpm exec electron-builder --dir
73+
if: runner.os != 'Windows'
74+
run: node scripts/electron-builder.cjs --dir
75+
# Build the real installers on Windows rather than just the unpacked app: an app payload
76+
# the NSIS extractor cannot unpack is invisible until an installer exists to inspect,
77+
# which is what scripts/verify-windows-installer.cjs checks. arm64 is packaged here on an
78+
# x64 runner on purpose — the payload is inspected, never executed, so no ARM runner is
79+
# needed to catch a filter the installer could not decode.
80+
- name: Package Windows x64 installer (without publishing)
81+
if: runner.os == 'Windows'
82+
run: node scripts/electron-builder.cjs --win nsis --x64 --publish never
83+
- name: Package Windows arm64 installer (without publishing)
84+
if: runner.os == 'Windows'
85+
run: node scripts/electron-builder.cjs --win nsis --arm64 --publish never

‎.github/workflows/release.yml‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
version: 11.19.0
3232
- uses: actions/setup-node@v4
3333
with:
34-
node-version: 22
34+
node-version: 24
3535
cache: pnpm
3636
- run: pnpm install --frozen-lockfile
3737
- name: Verify tag
@@ -40,10 +40,10 @@ jobs:
4040
- run: pnpm typecheck
4141
- run: pnpm test
4242
- run: pnpm build
43-
# Native modules are rebuilt in-place. Building both architectures in one
44-
# workspace can mutate a hard-linked module after the first app was signed.
43+
# Each arch is signed in its own workspace, so one build can never touch an
44+
# app another job already signed.
4545
- name: Package macOS (${{ matrix.electron_arch }})
46-
run: pnpm exec electron-builder --mac dmg --${{ matrix.electron_arch }} --publish never
46+
run: node scripts/electron-builder.cjs --mac dmg --${{ matrix.electron_arch }} --publish never
4747
- name: Verify packaged macOS app
4848
shell: bash
4949
env:
@@ -87,7 +87,7 @@ jobs:
8787
version: 11.19.0
8888
- uses: actions/setup-node@v4
8989
with:
90-
node-version: 22
90+
node-version: 24
9191
cache: pnpm
9292
- run: pnpm install --frozen-lockfile
9393
- name: Verify tag
@@ -96,7 +96,7 @@ jobs:
9696
- run: pnpm typecheck
9797
- run: pnpm test
9898
- run: pnpm build
99-
- run: pnpm exec electron-builder --win nsis --x64 --publish never
99+
- run: node scripts/electron-builder.cjs --win nsis --x64 --publish never
100100
- uses: actions/upload-artifact@v4
101101
with:
102102
name: windows-x64

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Thanks for helping improve Clean My Codex. Bug reports, focused fixes and well-s
1010

1111
## Development
1212

13-
The project requires Node.js 22 and pnpm 11.19.
13+
The project requires Node.js 24 and pnpm 11.19.
1414

1515
```bash
1616
pnpm install

‎README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Cleanup is written to a log — cache and leftover removals record the path and
152152

153153
## Development
154154

155-
Requires Node.js 22 and pnpm 11.19.
155+
Requires Node.js 24 and pnpm 11.19. Built on Electron 43, which runs on macOS 12+ and Windows 10+.
156156

157157
```bash
158158
pnpm install
@@ -170,6 +170,7 @@ Packaging:
170170
```bash
171171
pnpm build:mac
172172
pnpm build:win
173+
pnpm build:win-arm64
173174
```
174175

175176
## Contributing and support

‎README_CN.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Clean My Codex 跟随当前 Codex Desktop 的存储布局,建议同时使用
152152

153153
## 开发
154154

155-
需要 Node.js 22 和 pnpm 11.19。
155+
需要 Node.js 24 和 pnpm 11.19。基于 Electron 43,运行环境为 macOS 12+ 与 Windows 10+。
156156

157157
```bash
158158
pnpm install
@@ -170,6 +170,7 @@ pnpm check
170170
```bash
171171
pnpm build:mac
172172
pnpm build:win
173+
pnpm build:win-arm64
173174
```
174175

175176
## 贡献与支持

‎RELEASE_NOTES.md‎

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
1-
# Clean My Codex 0.1.6
2-
3-
## New
4-
5-
- **Plan output is now tracked as a session asset.** Codex's plan mode writes revisions under `~/.codex/plans/<thread-id>/`; each conversation's revisions collapse into one row named by the H1 of its newest revision, tagged `Plan`, and removed with the conversation that owned it.
6-
- **Workspace cleanup can delete related conversations.** A workspace folder deletion now offers the same "also delete related conversations and their session assets" option that worktrees already had, so removing `~/Documents/Codex/xxx` can take the conversations that ran there with it. The rule is unchanged — session assets follow their session; the workspace does not.
7-
- **Windows is now supported end-to-end, not just packaged.** Releases publish a Windows NSIS installer (`.exe`) alongside the macOS `.dmg`, and the app now works there:
8-
- **Desktop detection** recognizes the Codex/ChatGPT desktop app on Windows — the MSIX install under `Program Files\WindowsApps\OpenAI.Codex_<version>_\`, the legacy `Program Files\Codex` and `AppData\Local\Programs\Codex` layouts, including Electron helper processes — and excludes the crashpad handler the way macOS does. Because the Windows desktop app is tray-resident (the window × button does not quit it), the blocker now points to **File → Exit**; the auto-quit checkbox, which relies on macOS AppleScript, stays hidden off-darwin.
9-
- **CLI location** finds `codex` inside the desktop app's versioned/hash install directories (newest copy first when an upgrade left several), then falls back to `where.exe` and `PATH`, with case-insensitive environment lookup. A failed lookup is no longer cached for the session — install or upgrade Codex while Clean My Codex is open and the next operation finds it.
10-
- **Scheduled cleanup** on Windows moved off locale-dependent `schtasks /Query` output to PowerShell `Get-ScheduledTaskInfo`, which emits one invariant ISO timestamp for the next run. The repair pass that re-aligns an out-of-date launch agent on macOS now also reinstalls a Windows task whose executable, arguments, daily interval, or missed-run/battery settings no longer match this build.
11-
- **Update checks** run on Windows too (previously macOS-only), with a Windows-specific prompt to download and run the x64 installer. The Software Update row is now shown on every platform.
12-
- **Path identity** is handled through a shared layer that normalizes extended-length (`\\?\`) and UNC paths, resolves filesystem aliases through the nearest existing ancestor, and compares Windows paths case-insensitively — and is recognized on every host so the Windows behavior is regression-tested on macOS.
13-
- **Crash and exception logging.** Every IPC handler is wrapped to record failures before Electron serializes them, the main process observes fatal exceptions, and the renderer forwards uncaught errors, unhandled rejections, and React recoverable/uncaught errors to the main process. Worker errors now carry their stack. All of it lands in the existing `cleanup.log` alongside the normal operation record, so a submitted diagnostic log can explain both a wrong result and a failure that happened before one.
14-
- **Linux builds have been retired.** The AppImage target, bundled icon, `build:linux` script, and XDG fallback paths are gone; the location layer now refuses unsupported platforms explicitly rather than silently guessing.
15-
16-
## Improvements
17-
18-
- **Resource detail views are unified.** Sessions, Session Assets, Plugins, Workspace, and Worktrees now share one set of list controls:
19-
- **Sortable columns** — click a header to sort by it, click again to flip direction; an arrow shows the active direction and a faint double-chevron marks every sortable column. The old sort dropdowns are gone.
20-
- **Per-column funnel filters** replace the type/status `<select>` dropdowns. Each funnel opens a small popover with a count beside every option and fills in while a non-default filter is applied.
21-
- **Shared selection** that retains valid choices across a rescan, keeps hidden choices across a filter, and bulk-toggles only the visible rows — so toggling a filter no longer silently drops what you had selected. A native indeterminate "select all" checkbox and a single bottom action bar (selection summary + delete button, with the unsafe-git warning inline) replace each page's hand-rolled footer.
22-
- **Plugins page splits origin from version status.** The single status filter is now two funnels: **Source** (Official / Personal, derived from the scanner's `builtin` signal) and **Version status** (current / outdated / orphaned / unconfirmed). Official plugins show an "Official" pill alongside a "current" version pill, and the summary card breaks the total into Official and Personal.
23-
- **Cleanup confirmation reflects the choice you actually made.** Implementation-level child operations — the related-conversation deletion that follows a worktree or workspace removal — collapse into their container row in the result list and item count, with a failed or skipped child winning over a successful parent so a related operation that needs attention is never hidden behind a success. A cleanup failure now surfaces inside the dialog instead of duplicating in the main pane.
24-
- **One deletion warning instead of two.** The worktree and workspace git reminders merged into a single permanent-deletion-with-git notice, and the session-asset local-copy warning is now part of one permanent-deletion line, so the confirmation reads as one warning rather than competing lines.
25-
- **Closing the main window on macOS hides it.** The renderer and its completed scan stay alive so a Dock click shows the same window instead of mounting a fresh renderer and scanning again; `before-quit` still lets Quit close it normally, and `activate` restores an existing window instead of creating a second one.
26-
- **Overview sessions row** now shows the per-session rollout total separately from the shared `thread_history_*.sqlite` projection, which gets its own protected row, so the two are no longer conflated in the chart or the total.
27-
- **Plan-only-copy warning.** Deleting a Plan whose source conversation is already gone now warns that it may be the only surviving copy of that plan.
28-
- **Scan animation redrawn** with orbiting rings and a tracer dot in place of the old scan-ring/beam, and the redundant "Initial storage analysis" kicker was dropped.
29-
- **Release pipeline** splits macOS arm64 and x64 into separate build jobs (building both in one workspace could mutate a hard-linked native module after the first app was signed) that verify codesign and the Mach-O arch of the app and every bundled `.node`, then a single release job collects the macOS and Windows artifacts and publishes them.
30-
- Tightened cleanup dialog copy and button labels; worktree modification times are rounded for stable display.
1+
# Clean My Codex 0.1.7
2+
3+
A maintenance release. Nothing about how the app behaves has changed — no file under the main process, the renderer or the shared layer was touched — but the platform underneath it moved forward by ten Electron majors, and that raises the macOS version required to run it.
4+
5+
## Before you update
6+
7+
- **macOS 12 (Monterey) or later is now required.** 0.1.6 ran on macOS 11; Electron 43 does not. If you are on Big Sur, stay on 0.1.6.
8+
- **Windows 10 or later**, unchanged.
9+
- The Windows installer published here is x64, as before, and it is compressed exactly the way 0.1.6's was.
10+
11+
## Under the hood
12+
13+
- **Electron 33 → 43** (Chromium 150, Node 24.18.1), **better-sqlite3 11 → 13**, Node 24 for development and CI, and the build toolchain moved to Vite 7 with electron-vite 5.
14+
- **The native module no longer gets compiled at all.** better-sqlite3 13 is a Node-API addon that ships prebuilt binaries for every platform it supports, so the whole cross-rebuild apparatus is gone: no rebuild on install, no `electron-builder install-app-deps`, and no hand-written script for cross-building the Windows binary from macOS. Each artifact now carries only the one prebuilt binary it can actually load. This retires the failure mode where a macOS-built `.node` could end up inside the Windows installer.
15+
- **Compile targets are now written down.** electron-vite derives its target from a table of Electron versions that does not include 43, and its fallback quietly picks the *oldest* entry in that table — the app would have been compiled for a decade-old target without a word of warning. The config now names node24 and chrome150 outright.
16+
17+
## Windows on ARM
18+
19+
**A Windows arm64 installer built from this source now installs completely.** Releases still publish the x64 installer only, so this matters if you build your own with `pnpm build:win-arm64`.
20+
21+
electron-builder 26 compresses the app payload with a 2024 build of 7-Zip, which inspects every executable and chooses a compression filter for it — for ARM64 binaries that is the ARM64 filter, added in 7-Zip 23.01. The NSIS installer still unpacks that payload with a plugin built in 2019, which has never heard of it. The result was an installer that ran to completion, reported success, and wrote everything except the nine files it could not decode: the application executable and its eight DLLs. x64 was never affected — it gets the BCJ2 filter, which that plugin does understand and which 0.1.6's installer already used.
22+
23+
The build now pins the filter to one the installer can read, for Windows arm64 only; x64 and macOS are untouched. And because "the installer succeeds and silently omits the program" is not something a failed build would ever have reported, every Windows installer is now re-tested as it is built, using a 7-Zip decoder older than the one inside the installer: a payload that cannot be unpacked fails the build instead of reaching a release page. CI builds and checks both architectures on every push.
24+
25+
## Tests
26+
27+
- **A fresh clone no longer races the Electron download.** Electron 43 dropped its install script, so the binary is fetched on first use rather than at install time. Test files run in parallel, and several would start that download at once while another was already launching the half-written binary. The suite now fetches Electron once, before the first test file.
28+
- A test process killed by a signal now reports what the child actually printed instead of only the signal name, and CI decodes macOS crash reports when a job fails.

‎electron-builder.yml‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ files:
99
- "!**/node_modules/*/{CHANGELOG.md,README.md,readme.md,readme}"
1010
asar: true
1111
afterPack: ./scripts/adhoc-sign.cjs
12+
# Catches an installer whose payload the NSIS extractor cannot unpack — the failure that
13+
# otherwise only shows up as a successfully installed app with no exe. See the script.
14+
afterAllArtifactBuild: ./scripts/verify-windows-installer.cjs
1215
asarUnpack:
1316
- "**/*.node"
14-
npmRebuild: true
17+
# better-sqlite3 is a Node-API addon that ships prebuilt binaries for every platform it supports,
18+
# so there is nothing to rebuild against Electron's headers.
19+
npmRebuild: false
1520
mac:
1621
category: public.app-category.utilities
1722
target:
@@ -21,11 +26,19 @@ mac:
2126
gatekeeperAssess: false
2227
artifactName: ${productName}-${version}-${arch}.${ext}
2328
icon: Support/AppIcon.icns
29+
# Ship only the prebuilt binary this artifact can load; the other seven are dead weight
30+
# (~17MB) and would break the Mach-O arch check in the release workflow. It has to be a
31+
# single exclusion: for files under node_modules electron-builder honours "!" patterns
32+
# only, so anything excluded can never be added back by a later positive pattern.
33+
files:
34+
- "!**/node_modules/better-sqlite3/prebuilds/!(darwin-${arch}).node"
2435
win:
2536
icon: Assets/AppIcon.ico
2637
target:
2738
- nsis
2839
artifactName: ${productName}-${version}-${arch}.${ext}
40+
files:
41+
- "!**/node_modules/better-sqlite3/prebuilds/!(win32-${arch}).node"
2942
nsis:
3043
oneClick: false
3144
perMachine: false

‎electron.vite.config.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ export default defineConfig({
66
main: {
77
plugins: [externalizeDepsPlugin()],
88
build: {
9+
// electron-vite infers this from a lookup table that stops at Electron 39, and its
10+
// fallback picks the *oldest* entry rather than the newest, so an unlisted Electron
11+
// silently compiles down to a decade-old target. Electron 43 is Node 24.18 + Chromium 150.
12+
target: 'node24',
913
rollupOptions: {
1014
input: {
1115
index: resolve(__dirname, 'electron/main/index.ts'),
@@ -17,6 +21,7 @@ export default defineConfig({
1721
preload: {
1822
plugins: [externalizeDepsPlugin()],
1923
build: {
24+
target: 'node24',
2025
rollupOptions: {
2126
input: { index: resolve(__dirname, 'electron/preload/index.ts') }
2227
}
@@ -25,6 +30,7 @@ export default defineConfig({
2530
renderer: {
2631
root: 'src',
2732
build: {
33+
target: 'chrome150',
2834
rollupOptions: {
2935
input: { index: resolve(__dirname, 'src/index.html') }
3036
}

0 commit comments

Comments
 (0)