fix(npm): make the Dart fallback usable on Windows and diagnose failures - #63
Merged
Conversation
The native-binary spawn crash was fixed in #55, but the fallback it reaches was itself broken in three ways (issues #45, #49, #50). - `spawn('dart', ...)` cannot launch the Windows SDK entrypoints, which are .bat scripts CreateProcess refuses to execute. It failed with the same `spawn UNKNOWN` reported against the native path, and had no error handling, so the process crashed. Spawn through a shell on Windows, quoting arguments by hand since a shell does none, and guard both the synchronous throw and the async 'error' event. - The prerequisite check only looked for Dart. The vendored package depends on package:flutter, so `dart pub get` can never resolve it and the run died with "Couldn't resolve the package 'flutter_skill'" — which names the wrong problem. Require Flutter and say so. - `flutter pub get` failures were swallowed by an empty catch, so the real reason was discarded and the failure surfaced later as an unrelated import error. Report the output and stop. Also stops a failed binary download from poisoning later installs: a 404 or connection error left behind the empty file createWriteStream had already opened, and the "already installed" check only tested for existence, so the download was never retried. Remove the partial file on failure and treat a zero-byte file as absent.
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.
Addresses #45, #49 and #50.
Summary
#55 fixed the crash when the native binary fails to spawn, so the CLI now reaches the Dart fallback. But that fallback was itself broken, so users landed on a second failure with a misleading message.
1. The Dart fallback could not launch on Windows
spawn('dart', dartArgs)cannot start the Windows SDK entrypoints — they are.batscripts, andCreateProcessrefuses to execute them directly. It fails with exactly thespawn UNKNOWNreported in #45, and that spawn had no error handling at all, so the process crashed rather than reporting anything.Now spawns through a shell on Windows (quoting arguments by hand, since a shell does none) and guards both the synchronous throw and the async
'error'event, matching what #55 did for the native path.2. The prerequisite check named the wrong SDK
It only looked for Dart. But the vendored package depends on
package:flutter, sodart pub getcan never resolve it:The run then died with
Couldn't resolve the package 'flutter_skill'— the exact error in #49, which points at the package rather than at the missing Flutter SDK. Now requires Flutter and says so.3.
flutter pub getfailures were swallowedcatch (e) { // Ignore pub get errors }discarded the reason, and the failure resurfaced later as an unrelated import error. Now the output is printed and the process stops.4. A failed download poisoned every later install
createWriteStreamopens the destination before the status code is known, so a 404 (which is what #57 causes) or a connection error left a zero-byte file behind.postinstall's check wasfs.existsSync(localPath), so every subsequent install reported "Native binary already installed" and never retried. The partial file is now removed on failure, and a zero-byte file counts as absent.Test plan
Verified against a stubbed
PATH:Error: Flutter SDK not foundwith the install link (was: crash or a package-resolution error)spawn Unknown system error -8#49 setup → names the Flutter SDK as the prerequisite instead ofCouldn't resolve the package 'flutter_skill'flutter pub getfails (broken pubspec) → prints`flutter pub get` failed in <dir>followed by pub's actual output, then exitsNative binary failed to launch (ENOEXEC), falling back to Dart runtime→ Dart server starts and answersinitializenode -con bothbin/cli.jsandscripts/postinstall.jsThe Windows shell path is reasoned from
CreateProcesssemantics and is not exercised on this machine.Note
The full-chain test also shows why #61 matters — the fallback answers with:
It then prints its own "update available" banner against itself. The vendored Dart tree is that stale; #61 regenerates it.
🤖 Generated with Claude Code