Conversation
The NSIS auto-update installer failed with "Error opening file for writing: ...\_up_\sidecar\node_modules\node-pty\prebuilds\win32-x64\ conpty.node". Windows refuses to overwrite a native module that a live process still has loaded, and the Node sidecar was still running when NSIS reached node_modules. The RunEvent::Exit kill was too late and async, racing NSIS file copies after install() force-kills the app. The updater close handler now invokes kill_sidecar_now and awaits it before install() on Windows. That command is synchronous on the Rust side: it sends the kill, then polls try_wait (capped ~5s) until the process has actually exited and released its handles. try_wait avoids the job-object wait()'s completion-port double-consume hang. macOS/Linux can replace open files in place, so they skip this. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cleanup pass over the conpty.node fix: - Promote IS_WINDOWS to lib/platform (next to IS_MAC) and reuse it in updater.ts instead of an ad-hoc /Win/i regex; dedupe the duplicate copy that shell-escape.ts carried. - Name the kill_sidecar_and_wait loop constants (POLL_INTERVAL, MAX_POLLS) so the "~5s" cap is self-documenting. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
767a852
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://16c5469a.mouseterm.pages.dev |
| Branch Preview URL: | https://repro.mouseterm.pages.dev |
dormouse-bot
approved these changes
May 29, 2026
Member
Author
|
@dormouse-bot fix the merge conflict and push to this branch |
# Conflicts: # lib/src/lib/platform/index.ts # lib/src/lib/shell-escape.test.ts
Collaborator
|
Merged
Pushed as 767a852. Watching CI. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Windows, the auto-update installer failed at quit time with:
update.install()launches the NSIS installer, which overwrites the bundled sidecar'snode_modules— including node-pty's nativeconpty.node. Windows refuses to overwrite a native module that a live process still has loaded, and the Node sidecar was still running when NSIS reached that file. The existingRunEvent::Exitsidecar kill is both too late and asynchronous — NSIS starts copying files immediately afterinstall()force-kills the app, racing the sidecar's teardown. (The auto-update spec already flagged this exact gap.)Fix
standalone/src/updater.ts— beforeinstall(), on Windows only, the close handler nowawaitsinvoke('kill_sidecar_now')so theconpty.nodehandle is released before NSIS runs.standalone/src-tauri/src/lib.rs—kill_sidecar_nowis now synchronous: it sends the kill, then pollstry_wait(capped at ~5s) until the process has actually exited.try_waitis used rather than the job-objectwait()becausewait()consumes a completion-port message the reaper thread relies on and could block forever if the sidecar had already exited.macOS/Linux can replace open files in place, so they keep relying on the existing
RunEvent::Exitcleanup — the new step is Windows-gated.Cleanup (second commit)
IS_WINDOWSintolib/platform(next toIS_MAC) and reused it inupdater.tsinstead of an ad-hoc regex; deduped the duplicate copyshell-escape.tscarried.POLL_INTERVAL,MAX_POLLS) so the "~5s" cap is self-documenting.Testing
updater.test.ts(17 tests) — added a test asserting the kill is invoked and completes before install on Windows.shell-escape.test.ts(20 tests) — updated mocks for the shared constant; all pass.cargo build+cargo testclean; both packages typecheck.🤖 Generated with Claude Code