setup creates absolute symlinks for vendored installs, breaks portability
- 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
Assessment
This issue has not been assessed yet.