fix(windows): resolveSlug silently returns "unknown", sending all decision data to projects/unknown - #2380
Open
fongwc wants to merge 1 commit into
Open
fix(windows): resolveSlug silently returns "unknown", sending all decision data to projects/unknown#2380fongwc wants to merge 1 commit into
fongwc wants to merge 1 commit into
Conversation
…rojects/unknown lib/bin-context.ts spawns the `gstack-slug` bash script directly. Windows has no shebang support, so spawnSync fails with ENOENT, stdout is null, and the slug silently falls back to "unknown". Every bun-based bin that resolves a slug this way then reads and writes ~/.gstack/projects/unknown/ instead of the real project. In practice that means gstack-decision-log writes decisions somewhere gstack-decision-search on another project can also see, and the Context Recovery block in every skill preamble never surfaces them, because it checks for decisions.active.json under the correct slug. The failure is silent: exit 0, empty results, nothing in any log. Same root cause as the spawn half of garrytan#2356, and the same class the garrytan#1731 fix addressed for gbrain. That fix used `shell: true`, which is right for gbrain because gbrain ships a .cmd shim on Windows. gstack's own bins are extensionless bash scripts, so cmd.exe answers "is not recognized as an internal or external command" and only `spawnSync("bash", [script])` starts them: spawnSync(bin) -> ENOENT spawnSync(bin, {shell: true}) -> not recognized as an internal or external command spawnSync("bash", [bin]) -> status 0 Adds spawnBashBin() and routes resolveSlug through it. The direct spawn is still attempted first, so POSIX behaviour is byte-for-byte unchanged and the bash fallback only runs on the path that is currently broken. Verified on Windows 11, bun 1.3.13, Git Bash, global git install at ~/.claude/skills/gstack: before: gstack-decision-search --json -> [] (2 decisions on disk) after: gstack-decision-search --json -> 2 decisions, from both the repo root and a subdirectory with a different git remote Test suite unchanged: test/gbrain-spawn-windows-shell.test.ts, gstack-decision.test.ts, gstack-decision-bins.test.ts, bin-windows-bun-import-paths.test.ts and gstack-slug-sanitize.test.ts report 39 pass / 18 fail both before and after this commit on Windows at a325940, so this introduces no regressions. Those 18 pre-existing failures look like separate Windows path bugs in the tests themselves and are not touched here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
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.
Summary
On Windows,
resolveSlug()inlib/bin-context.tsalways returns"unknown", so every bun-based bin that resolves a project slug reads and writes~/.gstack/projects/unknown/instead of the real project.The visible effect is that
/decisiondata is invisible:gstack-decision-logwrites into a sharedunknownbucket,gstack-decision-searchreturns[]for every project, and the Context Recovery block in every skill preamble never surfaces a decision, because it looks fordecisions.active.jsonunder the correct slug.The failure is silent. Exit code 0, empty result, nothing in any log. I only found it after noticing a project's decisions had been accumulating in
~/.gstack/projects/unknown/for weeks.Root cause
bin/gstack-slugis a#!/usr/bin/env bashscript with no file extension. Windows has no shebang support, so spawning it directly fails andr.stdoutisnull, which falls through to the"unknown"default:Measured on the real path:
Relationship to #1731 and #2356
This is the same spawn bug class as the second half of #2356, at a call site that issue does not list.
It is also the same class #1731 already fixed for gbrain, via
NEEDS_SHELL_ON_WINDOWS(shell: true). Worth being explicit about why that remedy is not reused here:shell: trueis correct for gbrain because gbrain ships a.cmdshim on Windows, whichcmd.execan run. gstack's own bins have no shim, soshell: trueroutes tocmd.exeand fails, as measured above. Only spawningbashworks.The fix
Adds
spawnBashBin()and routesresolveSlugthrough it. The direct spawn is attempted first, so POSIX behaviour is byte-for-byte unchanged; the bash fallback only runs on the path that is currently broken.Verification
Windows 11 (10.0.26200), bun 1.3.13, Git Bash, global git install at
~/.claude/skills/gstack, upstreama3259400.Correct from both the repo root and a subdirectory with a different git remote, i.e. the slug now tracks the real project rather than collapsing to
unknown.Existing tests, run before and after the change on Windows:
Identical, so no regressions. The 18 pre-existing failures look like separate Windows path bugs inside the tests themselves (for example
gstack-slug-sanitizebuilds a cache key containingC:\...and then tries to open it as a nested path). Not touched here.Deliberately not included
bin/gstack-gbrain-sync.ts:1150,1155spawnsgstack-brain-sync, which is also an extensionless bash script, usingshell: NEEDS_SHELL_ON_WINDOWS. By the measurement above that spawn cannot be working on Windows either, despite the#1731comment above it.I left it alone because
test/gbrain-spawn-windows-shell.test.tsexplicitly pins that call site to exactly twospawnSync(brainSyncPath, ...)occurrences carryingshell: NEEDS_SHELL_ON_WINDOWS. Changing it means overturning an invariant a maintainer wrote deliberately, and I have no gbrain install here to verify the end-to-end path. Happy to follow up in a separate PR, or file it as an issue, whichever you prefer.