fix(tools): resolve external tools on Windows - #175
Closed
jz-wilson wants to merge 1 commit into
Closed
Conversation
The tool search assumes a POSIX environment in three ways, and on Windows all three fail closed — every tool reads as "not installed on this host", so `doctor` reports no herdr and no python3 on a machine that has both on PATH, and `update` cannot classify the install because it cannot find `git` to ask. Downstream of that, the phone is told the update preflight cannot be run here. - PATH was split on ":", which on Windows does not merely miss entries but shreds each one at its drive letter (`C:\Program Files\Git\cmd` becomes `C` and `\Program Files\Git\cmd`), so the absolute-only filter drops the lot and PATH contributes nothing at all. Use node:path's `delimiter`. - A bare name was joined to each directory as-is, but on Windows the executable is `git.exe`, `herdr.exe`, `python3.exe`. `findIn` now tries each suffix within a directory, bare name first, so PATH order still decides. Off win32 the suffix list is a lone "" and the search is unchanged. - `env.PATH` misses Windows' `Path` spelling. Case-insensitivity survives only while the environment is the live `process.env` proxy, and this module is handed plain copies of it — so PATH and PATHEXT are read case-insensitively on win32. This is the one that hid the other two: the same binary passed under Git Bash, which exports the name uppercase, and failed under PowerShell. Verified on Windows 11 against a Herdr-managed checkout: `collie doctor` now resolves herdr 0.8.2, python3 and git and classifies the install, and `collie update --check` produces a real preflight. `bun test ./cli/tools.test.ts` is green on Linux, where the three win32-only assertions skip. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UDQT5GAR9qRs6ukXrmDzhL
AltanS
added a commit
that referenced
this pull request
Sep 7, 2026
The win32 branches landed in #175 read `process.platform` directly, so the only host that could exercise them was a Windows host, which we do not have. `searchDirs`, `toolExts` and `findTool` now take a trailing `platform: NodeJS.Platform = process.platform` argument, the way `bridge/config.ts`'s `defaultSocketPath` already takes its own, and the internal `envGet` takes it as a required third argument. Callers pass nothing and behave as before; off win32 every path is byte-identical. `cli/tools.test.ts` drops its four `skipIf` guards and passes the platform instead, and two new cases pin `findTool`: a `.cmd` shim on PATH resolves under `"win32"` and is not matched under `"linux"`. CHANGELOG credits @jz-wilson (#175) for the Windows tool resolution. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Owner
|
Thanks Johnzell, this lands. Your commit is on main as d80ebbe with your authorship, plus one of mine that makes the platform an injected parameter so the Windows cases run on our Linux CI instead of being skipped, and the changelog names the .cmd shim limit. It ships in 1.6.0. |
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.
What
bridge/tools.tsassumes a POSIX environment in three ways. On Windows all three fail closed, so every external tool resolves as "not installed on this host".The user-visible symptom is on the phone: "The preflight couldn't be run on this machine." The chain behind it is
findTool("git") → null→isGitCheckoutfalse → install kindunknown→collie updaterefuses.collie doctorreports the same machine as having noherdrand nopython3while both sit onPATH, andcollie update's own build step fails with bun not found.The three
PATH split on
":". Windows separates with;, so the split does not merely miss entries — it shreds each one at its drive letter (C:\Program Files\Git\cmdbecomesCand\Program Files\Git\cmd).searchDirs' absolute-only filter then drops every fragment and PATH contributes nothing at all. Nownode:path'sdelimiter.No
PATHEXT. The bare name was joined to each directory as-is, but the executable isgit.exe,herdr.exe,python3.exe.findInnow takes anextslist and tries each suffix within a directory before moving on, bare name first, so PATH order still decides. The parameter defaults to[""]andtoolExtsreturns[""]off win32 — the search is byte-for-byte unchanged on Linux and macOS.env.PATHmisses Windows'Pathspelling. Case-insensitivity survives only while the environment is the liveprocess.envproxy; this module is handed plain copies of it (the CLI merges.envover the ambient environment before buildingExec). SoPATHandPATHEXTare read case-insensitively on win32.The third one is why this was not caught earlier by anyone poking at it from a terminal: the same binary passes under Git Bash, which exports the name uppercase, and fails under PowerShell — which is what a Windows bridge actually runs under.
Verification
On Windows 11, against a Herdr-managed checkout at v1.5.3,
collie doctorgoes fromto
herdr 0.8.2,python3.EXE, andHerdr-managed checkout … (detached at 1.5.3).collie update --check --local --jsonthen produces a real preflight (bungreen,treegreen,upstreamgreen) instead ofupdate.preflight_unavailable, and the Updates page on the phone works.Checks run on Linux, all green:
bun run typecheck,cd web && bun run typecheck,bun run lint(0 warnings, 0 errors),bun test ./cli/tools.test.ts ./bridge/dial.test.ts(23 pass, 3 skip), andcd web && bun run test(181 files, 5050 pass).Notes
## [Unreleased]entry:- Fixed: external tools (git, herdr, python3, bun) now resolve on Windows, so doctor and update work there.toolExtson both sides of the platform check; the three win32-only assertionsskipIfoff Windows.buildon win32 so there is nobin/collieforcanRunUpdateto find (and abun build --compilethere emitsbin/collie.exe, not the bare name the bridge checks), anddoctor'sdiskcheck cannot read free space on Windows. Happy to follow up on either.🤖 Generated with Claude Code
https://claude.ai/code/session_01UDQT5GAR9qRs6ukXrmDzhL