Desktop skill discovery skips symlinked skill directories
Summary
Claude Code Desktop explicitly skips symlinked entries when discovering skills in ~/.claude/skills/, while the CLI follows them normally. This causes skills installed via symlinks (e.g. by gstack's setup script) to be invisible in Desktop.
Relevant code
In the Desktop app's bundled JS (app.asar → .vite/build/index.js), two locations skip symlinks:
Skill frontmatter reading (qIt function):
if ((await Be.lstat(t)).isSymbolicLink())
return C.warn(`${dk} Skipping symlinked SKILL.md: "${t}"`), { userInvocable: true };
Directory scanning (f4e function):
if (i.isSymbolicLink()) {
C.debug(`${Yo} Skipping symlinked entry in skill directory: ${ge.join(t, i.name)}`);
continue;
}
Expected behavior
Skills symlinked into ~/.claude/skills/ should be discovered by Desktop the same way the CLI discovers them. This is a common installation pattern — gstack, for example, clones to ~/.claude/skills/gstack/ and symlinks each skill directory (e.g. browse -> gstack/browse).
Workaround
Replace symlinks with copies:
cd ~/.claude/skills
for link in $(find . -maxdepth 1 -type l); do
target=$(readlink "$link")
rm "$link"
cp -R "$target" "$link"
done
Environment
- macOS (Darwin 25.3.0, arm64)
- Claude Code Desktop v2.1.81
- gstack v0.9.9.0
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗