Skip to content

fix(npm): make the Dart fallback usable on Windows and diagnose failures - #63

Merged
charliewwdev merged 1 commit into
mainfrom
fix/dart-fallback-robustness
Sep 1, 2026
Merged

fix(npm): make the Dart fallback usable on Windows and diagnose failures#63
charliewwdev merged 1 commit into
mainfrom
fix/dart-fallback-robustness

Conversation

@charliewwdev

Copy link
Copy Markdown
Member

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 .bat scripts, and CreateProcess refuses to execute them directly. It fails with exactly the spawn UNKNOWN reported 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, so dart pub get can never resolve it:

Because flutter_skill requires the Flutter SDK, version solving failed.
Flutter users should use `flutter pub` instead of `dart pub`.

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 get failures were swallowed

catch (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

createWriteStream opens 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 was fs.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:

  • No Flutter, no DartError: Flutter SDK not found with the install link (was: crash or a package-resolution error)
  • Dart present, Flutter absent — the flutter-skill crashes on Apple Silicon macOS with spawn Unknown system error -8 #49 setup → names the Flutter SDK as the prerequisite instead of Couldn't resolve the package 'flutter_skill'
  • flutter pub get fails (broken pubspec) → prints `flutter pub get` failed in <dir> followed by pub's actual output, then exits
  • Full chain: planted a corrupt cached native binary → Native binary failed to launch (ENOEXEC), falling back to Dart runtime → Dart server starts and answers initialize
  • node -c on both bin/cli.js and scripts/postinstall.js

The Windows shell path is reasoned from CreateProcess semantics and is not exercised on this machine.

Note

The full-chain test also shows why #61 matters — the fallback answers with:

"serverInfo":{"name":"flutter-skill","version":"0.2.0"}

It then prints its own "update available" banner against itself. The vendored Dart tree is that stale; #61 regenerates it.

🤖 Generated with Claude Code

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.
@charliewwdev
charliewwdev merged commit 6f9cd00 into main Sep 1, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant