Desktop app omits Windows junction/symlink skills from the / command menu (agent loader resolves them fine)
Summary
On Windows, a skill linked into ~/.claude/skills as a directory junction (or
symlink) is loaded for the model but does not appear in the desktop app's /
command menu. A real directory in the same folder appears normally. The agent
can see the skill and the menu cannot.
This matters because junctions are the default on Windows. The official
installer (npx skills, vercel-labs/skills) links each skill into~/.claude/skills with a directory junction, since real symlinks need admin
rights or Developer Mode. mklink /J produces the same thing.
Environment
- OS: Windows 11 Pro 10.0.26200
- Claude Code desktop app
- Node 24.13.1 and Bun 1.3.14 both reproduce the filesystem behavior below
Reproduce the filesystem behavior
Create a real skill directory and a junction pointing at it:
mkdir C:\tmp\jtest\real
Set-Content C:\tmp\jtest\real\SKILL.md "---`nname: demo`n---"
New-Item -ItemType Junction -Path C:\tmp\jtest\link -Target C:\tmp\jtest\real
Enumerate the parent the way a skills scan does:
const fs = require('fs');
for (const e of fs.readdirSync('C:/tmp/jtest', { withFileTypes: true })) {
console.log(e.name, 'isDirectory=' + e.isDirectory(), 'isSymbolicLink=' + e.isSymbolicLink());
}
Output, identical under Node 24 and Bun 1.3:
link isDirectory=false isSymbolicLink=true
real isDirectory=true isSymbolicLink=false
A scan that keeps only entry.isDirectory() drops the junction and keeps the
real directory.
What happens in the app
- Skills linked into
~/.claude/skillsas junctions appear in the model's
available-skills list and the agent can use them.
- The same skills are missing from the
/command menu in the desktop app. - A skill that is a real directory in the same folder does appear in the menu.
So the agent loader resolves the junction and the menu scan does not. Thenpx skills tool hits the same Node behavior and handles it in its own listing
code, with a helper that follows the link and re-checks the target
(isDirEntryOrSymlinkToDir in its installer).
Suggested fix
When enumerating ~/.claude/skills for the menu, accept an entry that is a
symlink or junction resolving to a directory, not only a plain directory:
const isSkillDir = e.isDirectory()
|| (e.isSymbolicLink() && (await stat(join(dir, e.name)).catch(() => null))?.isDirectory());
This matches what the agent loader already does and brings the two surfaces
back in line.
Workarounds for users
- Install with
--copy(npx skills add owner/repo --copy) so each skill is
written as a real directory.
- Or make
~/.claude/skillsitself a single junction to the skills store, so
the per-skill entries resolve as real directories. A scan reading through a
parent junction reports its entries as real directories, and the menu then
lists them. I verified both on Windows 11.
Related
- #34586 and #41177 cover a skill being listed but failing to invoke. This
report is about the / menu not listing junction or symlink skills in the
first place, which is a separate surface.
- #54884 covers the desktop skills pane empty state during cloud sync.
Found while debugging a Windows npx skills setup whose skills loaded for the
model but were absent from the / menu.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗