garrytan / garrytan/gstack

setup creates absolute symlinks for vendored installs, breaks portability

Open
#954 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

## Bug

`link_claude_skill_dirs()` in `setup` (line 328) creates SKILL.md symlinks using absolute paths:

```bash
ln -snf "$gstack_dir/$dir_name/SKILL.md" "$target/SKILL.md"
```

For global installs this is fine, but for vendored/local installs (`INSTALL_TYPE=vendored`), `$gstack_dir` resolves to an absolute path like `/Users/alice/myproject/.claude/skills/gstack/qa/SKILL.md`. This means:

1. The symlinks only work on the machine that ran `./setup`
2. Other developers cloning the repo get broken symlinks
3. `git diff` shows churn converting relative → absolute on every upgrade

The comment on line 323 says "absolute path" explicitly, so this seems intentional — but it shouldn't be for vendored installs.

## Expected

For vendored installs, symlinks should be relative (e.g., `../gstack/qa/SKILL.md`), matching what would be committed to the repo.

## Repro

1. Vendored gstack in a project repo (`.claude/skills/gstack/`)
2. Run `./setup` or `/gstack-upgrade` (which runs `./setup`)
3. Check symlinks: `readlink .claude/skills/qa/SKILL.md`
4. See absolute path instead of `../gstack/qa/SKILL.md`

## Workaround

After upgrade, fix symlinks manually:

```bash
cd .claude/skills
for dir in */; do
[ "$dir" = "gstack/" ] && continue
if [ -L "${dir}SKILL.md" ]; then
target=$(readlink "${dir}SKILL.md")
if [[ "$target" == /* ]]; then
ln -sf "../gstack/${dir}SKILL.md" "${dir}SKILL.md"
fi
fi
done
```

## Version

v0.16.2.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.