Desktop app omits Windows junction/symlink skills from the / command menu (agent loader resolves them fine)

Resolved 💬 3 comments Opened Jun 13, 2026 by sum117 Closed Jun 13, 2026

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/skills as 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. The
npx 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/skills itself 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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗