fix(setup): resolve hardcoded ~/.claude/skills/gstack paths for installs not named "gstack" (#1882)#2223
Open
time-attack wants to merge 1 commit into
Conversation
…stack" Every generated SKILL.md preamble hard-references the absolute self-path ~/.claude/skills/gstack/bin/... (config, telemetry, update-check, and all other bin/asset calls). When gstack is installed at ~/.claude/skills/<name> with <name> != gstack, setup's per-skill symlinks resolve correctly but those in-file references point at a non-existent ~/.claude/skills/gstack/ and fail SILENTLY at skill-invocation time (the preamble swallows the 127 via `|| echo default`), so every config read falls back to defaults and telemetry no-ops. Nothing surfaces at install; skills break later in a way that looks like the skill itself is broken. Fix: after linking the Claude host skills, plant a sibling compatibility alias <skills_dir>/gstack -> <install_dir> whenever the install dir basename isn't "gstack". Zero file edits; the hardcoded paths resolve through the alias. Claude Code already skips the repo-shaped gstack directory when building the slash-command list, so the alias is a path-resolution target only, not a duplicate skill. It no-ops when the install is already named gstack and never clobbers a real (non-symlink) gstack directory already present. Adds test/setup-gstack-compat-alias.test.ts covering the static wiring and the behavioral matrix (non-gstack install plants the alias, gstack install is a no-op, real dir not clobbered, stale symlink refreshed). Fixes garrytan#1882. Co-Authored-By: Claude Opus 4.8 (1M context) <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 |
Author
|
Closing — opened without the author's sign-off. Will re-submit only after review and explicit approval. |
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.
Fixes #1882.
The issue, in plain terms
When you install gstack,
setupputs each skill (/qa,/ship, ...) into~/.claude/skills/and points it back at your gstack checkout. That part works no matter what you name the folder you cloned into.The problem: the text inside every skill hardcodes one exact path —
~/.claude/skills/gstack/bin/.... Every skill, on every run, quietly calls things like~/.claude/skills/gstack/bin/gstack-configin its opening steps (reading your config, logging telemetry, checking for updates).So if you cloned gstack into a folder that isn't literally named
gstack(say~/.claude/skills/gstack-devor~/.claude/skills/i-gstack), those calls point at a folder that doesn't exist. And because each call ends in2>/dev/null || echo default, the failure is swallowed — nothing errors out. Every config setting silently falls back to its default, telemetry silently does nothing, the update check silently skips.The nasty part: install looks completely fine. Nothing warns you. The skills only misbehave later, when you actually run one, and it looks like the skill itself is broken rather than the folder name.
Who hits this: anyone whose install folder isn't named exactly
gstack.setupaccepts that layout (it installs the skills as siblings of whatever folder you cloned into) — it just never reconciled the hardcoded path inside the skill files. This is the folder-name sibling of #349 (which is about the~/.claudeprefix), and both point toward the dynamic-path-resolution direction from #289.Proof (before → after)
Reproduced in a throwaway
$HOMEwith the checkout copied to~/.claude/skills/i-gstack(a name that isn'tgstack) and./setup --host claude, then running the exact commands a skill's opening steps run:~/.claude/skills/gstack/bin/gstack-config get proactivetrue~/.claude/skills/gstack/bin/gstack-telemetry-log~/.claude/skills/gstack/bin/gstack-update-check~/.claude/skills/gstack-> i-gstackThe fix (issue's option #1 — a compatibility symlink)
After
setuplinks the Claude skills, if your install folder isn't namedgstackit now plants one extra symlink:~/.claude/skills/gstack -> <your install folder>. That makes every hardcoded~/.claude/skills/gstack/...path resolve, with zero edits to any skill file.Safe by design (
link_gstack_compat_aliasinsetup):gstack(paths resolve natively).gstackdirectory that's already there — that could be a separate install, and its ownbin/already works._link_or_copyhelper, so Windows-without-Developer-Mode falls back to a directory copy and the raw-lninvariant test stays green.Claude Code already skips the repo-shaped
gstackdirectory when it builds the slash-command list (seelink_claude_root_skill_alias), so this alias is purely a path-resolution target, not a duplicate skill — which resolves the caveat the issue flagged.Why not the other options: #2 (make the preamble resolve its own path at runtime) touches every generated skill and can't reliably self-locate in bash; #3 (rewrite the in-file paths for the Claude host) dirties the working tree, since that host symlinks to source instead of copying.
Tests
New:
test/setup-gstack-compat-alias.test.ts— static wiring checks plus a behavioral matrix: non-gstackinstall plants the alias,gstackinstall is a no-op, a real pre-existing dir is not clobbered, a stale symlink is refreshed.bun test test/setup-gstack-compat-alias.test.ts— passbun test test/setup-*.test.ts— 74 pass (includes the Windows raw-lninvariant)Note for maintainers
Raw bug fix only — no
VERSION/CHANGELOGbump. Leave versioning to a/shippass.🤖 Generated with Claude Code