diff --git a/src/features/claude-code-skill-loader/loader.ts b/src/features/claude-code-skill-loader/loader.ts index 700c677..6de225f 100644 --- a/src/features/claude-code-skill-loader/loader.ts +++ b/src/features/claude-code-skill-loader/loader.ts @@ -1,4 +1,4 @@ -import { existsSync, readdirSync, readFileSync, statSync, readlinkSync } from "fs" +import { existsSync, readdirSync, readFileSync, lstatSync, readlinkSync } from "fs" import { homedir } from "os" import { join, resolve } from "path" import { parseFrontmatter } from "../../shared/frontmatter" @@ -22,8 +22,12 @@ function loadSkillsFromDir(skillsDir: string, scope: SkillScope): LoadedSkillAsC if (!entry.isDirectory() && !entry.isSymbolicLink()) continue let resolvedPath = skillPath - if (statSync(skillPath, { throwIfNoEntry: false })?.isSymbolicLink()) { - resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath)) + try { + if (lstatSync(skillPath, { throwIfNoEntry: false })?.isSymbolicLink()) { + resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath)) + } + } catch { + continue } const skillMdPath = join(resolvedPath, "SKILL.md") diff --git a/src/tools/skill/tools.ts b/src/tools/skill/tools.ts index 3a1ca94..bcef908 100644 --- a/src/tools/skill/tools.ts +++ b/src/tools/skill/tools.ts @@ -1,5 +1,5 @@ import { tool } from "@opencode-ai/plugin" -import { existsSync, readdirSync, statSync, readlinkSync, readFileSync } from "fs" +import { existsSync, readdirSync, lstatSync, readlinkSync, readFileSync } from "fs" import { homedir } from "os" import { join, resolve, basename } from "path" import { z } from "zod/v4" @@ -39,7 +39,7 @@ function discoverSkillsFromDir( if (entry.isDirectory() || entry.isSymbolicLink()) { let resolvedPath = skillPath try { - const stats = statSync(skillPath, { throwIfNoEntry: false }) + const stats = lstatSync(skillPath, { throwIfNoEntry: false }) if (stats?.isSymbolicLink()) { resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath)) } @@ -85,7 +85,7 @@ const skillListForDescription = availableSkills function resolveSymlink(skillPath: string): string { try { - const stats = statSync(skillPath, { throwIfNoEntry: false }) + const stats = lstatSync(skillPath, { throwIfNoEntry: false }) if (stats?.isSymbolicLink()) { return resolve(skillPath, "..", readlinkSync(skillPath)) }