Summary
On Windows (MSYS2/Git Bash), ./setup can never succeed. BROWSE_BIN is hardcoded without the .exe suffix, but bun build --compile emits browse.exe on Windows. The gate at setup:436 is an executable-bit test, not an existence test, so it always fails and the script exit 1s.
Because that gate sits before skill installation, the user is left with a half-install whose failure is silent by consequence: gstack/VERSION reports the new version while ~/.claude/skills/* still holds the old skill files. The version file reports a success the skills never received.
I hit this upgrading 1.43.1.0 → 1.60.1.0 (global git install). My installed skills were dated May 22 while VERSION read 1.43.1.0 — so this had been failing silently across multiple upgrades. /diagram and /spec (new in 1.60) were present in the repo but never installed.
Root cause
setup:20 sets the path with no extension:
BROWSE_BIN="$SOURCE_GSTACK_DIR/browse/dist/browse" # setup:20 (and again at :245)
Windows is detected — but only at setup:28, after the assignment, and IS_WINDOWS is never applied to BROWSE_BIN:
IS_WINDOWS=0
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*|Windows_NT) IS_WINDOWS=1 ;;
The build then produces browse.exe, so the two -x tests on the extensionless path both misfire:
setup:379 — [ ! -x "$BROWSE_BIN" ] is the staleness check, so Windows rebuilds the binary on every run (~10s wasted each time).
setup:436 — the same test is a hard gate: exit 1.
[353ms] compile browse/dist/browse.exe <- build emits .exe
gstack setup failed: browse binary missing at /c/Users/.../browse/dist/browse
ls confirms the mismatch — the built artifact and the tested path are different files:
-rwxr-xr-x 98519552 browse.exe <- freshly built, executable
-rw-r--r-- 103963473 browse <- stale leftover, NOT executable -> -x fails
Reproduce
On Windows / Git Bash, from a clean clone: ./setup → exits 1 at the gate, ~/.claude/skills/ is never updated, VERSION reads new regardless.
Proposed fix
Apply the suffix once Windows is known (and at :245, which duplicates the assignment):
BROWSE_BIN="$SOURCE_GSTACK_DIR/browse/dist/browse"
[ "$IS_WINDOWS" -eq 1 ] && BROWSE_BIN="$BROWSE_BIN.exe"
This requires moving the assignment below the IS_WINDOWS detection at setup:28, or re-applying it there.
Worth noting: the extensionless PE does execute under Git Bash — after cp -f browse.exe browse, ./browse/dist/browse status returns Status: healthy. So the skills' documented browse/dist/browse invocation path is fine; only the exec-bit test is wrong. Pointing BROWSE_BIN at .exe also fixes the redundant per-run rebuild at :379.
Workaround (for other Windows users landing here)
cd ~/.claude/skills/gstack/browse/dist
cp -f browse.exe browse && chmod +x browse
cp -f find-browse.exe find-browse && chmod +x find-browse
cd ~/.claude/skills/gstack && ./setup # now exits 0 and installs skills
⚠️ This workaround degrades the next upgrade from a loud failure into a silent one. browse/dist/ is gitignored, so the copied browse survives git reset --hard; on the next upgrade the rebuild refreshes browse.exe while the stale browse still passes -x. Setup then reports success while skills invoke the stale binary. Re-run cp -f browse.exe browse after every upgrade until this is fixed properly.
Related
Summary
On Windows (MSYS2/Git Bash),
./setupcan never succeed.BROWSE_BINis hardcoded without the.exesuffix, butbun build --compileemitsbrowse.exeon Windows. The gate atsetup:436is an executable-bit test, not an existence test, so it always fails and the scriptexit 1s.Because that gate sits before skill installation, the user is left with a half-install whose failure is silent by consequence:
gstack/VERSIONreports the new version while~/.claude/skills/*still holds the old skill files. The version file reports a success the skills never received.I hit this upgrading 1.43.1.0 → 1.60.1.0 (global git install). My installed skills were dated May 22 while
VERSIONread 1.43.1.0 — so this had been failing silently across multiple upgrades./diagramand/spec(new in 1.60) were present in the repo but never installed.Root cause
setup:20sets the path with no extension:Windows is detected — but only at
setup:28, after the assignment, andIS_WINDOWSis never applied toBROWSE_BIN:The build then produces
browse.exe, so the two-xtests on the extensionless path both misfire:setup:379—[ ! -x "$BROWSE_BIN" ]is the staleness check, so Windows rebuilds the binary on every run (~10s wasted each time).setup:436— the same test is a hard gate:exit 1.lsconfirms the mismatch — the built artifact and the tested path are different files:Reproduce
On Windows / Git Bash, from a clean clone:
./setup→ exits 1 at the gate,~/.claude/skills/is never updated,VERSIONreads new regardless.Proposed fix
Apply the suffix once Windows is known (and at
:245, which duplicates the assignment):This requires moving the assignment below the
IS_WINDOWSdetection atsetup:28, or re-applying it there.Worth noting: the extensionless PE does execute under Git Bash — after
cp -f browse.exe browse,./browse/dist/browse statusreturnsStatus: healthy. So the skills' documentedbrowse/dist/browseinvocation path is fine; only the exec-bit test is wrong. PointingBROWSE_BINat.exealso fixes the redundant per-run rebuild at:379.Workaround (for other Windows users landing here)
browse/dist/is gitignored, so the copiedbrowsesurvivesgit reset --hard; on the next upgrade the rebuild refreshesbrowse.exewhile the stalebrowsestill passes-x. Setup then reports success while skills invoke the stale binary. Re-runcp -f browse.exe browseafter every upgrade until this is fixed properly.Related
.exefix itself.browse.exeon Windows (Smart App Control / signing).