While auditing the install/deploy path end to end, I found a reproducible issue in the README-supported project install flow.
Summary
- A repo-local install at
.claude/skills/gstack can break /browse if there is no matching user-level install under ~/.claude/skills/gstack.
- Separately,
./setup can print gstack ready even when browse/dist/browse was not actually produced.
Why this matters
- The README explicitly positions project-local install as a supported path for teammates.
- In practice, a clean repo-level install can leave
/browse unusable, which makes the deploy story look successful when it is not.
Repro
- Install gstack only at the project level (for example
.claude/skills/gstack) and do not keep a user-level ~/.claude/skills/gstack install around.
- Run
./setup from that project-local gstack directory.
- Run the compiled binary from that project-local install.
Observed behavior
- The compiled CLI can fail trying to resolve
server.ts from ~/.claude/skills/gstack/browse/src/server.ts instead of from the adjacent project-local install.
- In my audit,
./setup also printed gstack ready even when browse/dist/browse was still missing.
Expected behavior
- A project-local install should be self-contained: compiled
browse should resolve its server script from the installed repo it lives in.
./setup should exit non-zero if the binary is still missing after the build step.
./setup should also rebuild when source files are newer than the compiled binary, not only when the binary is missing.
Root cause
browse/src/cli.ts falls back to path.resolve(process.env.HOME || "/tmp", ".claude/skills/gstack/browse/src/server.ts") when running from the compiled binary, so the runtime assumes a user-level install exists.
setup only checked if [ ! -x "$GSTACK_DIR/browse/dist/browse" ] before building, and it did not verify the artifact existed afterward.
I validated a fix locally by:
- resolving
server.ts from the compiled binary's adjacent browse/src/server.ts first,
- keeping the env override and HOME fallback,
- making
setup fail hard if browse/dist/browse is still missing,
- and adding regression coverage for the compiled project-install path.
While auditing the install/deploy path end to end, I found a reproducible issue in the README-supported project install flow.
Summary
.claude/skills/gstackcan break/browseif there is no matching user-level install under~/.claude/skills/gstack../setupcan printgstack readyeven whenbrowse/dist/browsewas not actually produced.Why this matters
/browseunusable, which makes the deploy story look successful when it is not.Repro
.claude/skills/gstack) and do not keep a user-level~/.claude/skills/gstackinstall around../setupfrom that project-localgstackdirectory.Observed behavior
server.tsfrom~/.claude/skills/gstack/browse/src/server.tsinstead of from the adjacent project-local install../setupalso printedgstack readyeven whenbrowse/dist/browsewas still missing.Expected behavior
browseshould resolve its server script from the installed repo it lives in../setupshould exit non-zero if the binary is still missing after the build step../setupshould also rebuild when source files are newer than the compiled binary, not only when the binary is missing.Root cause
browse/src/cli.tsfalls back topath.resolve(process.env.HOME || "/tmp", ".claude/skills/gstack/browse/src/server.ts")when running from the compiled binary, so the runtime assumes a user-level install exists.setuponly checkedif [ ! -x "$GSTACK_DIR/browse/dist/browse" ]before building, and it did not verify the artifact existed afterward.I validated a fix locally by:
server.tsfrom the compiled binary's adjacentbrowse/src/server.tsfirst,setupfail hard ifbrowse/dist/browseis still missing,