fix: use lstatSync instead of statSync for symlink detection (#32)

This commit is contained in:
Junho Yeo
2025-12-13 13:58:02 +09:00
committed by GitHub
parent 03c61bf591
commit 564c8ae8bf
2 changed files with 10 additions and 6 deletions

View File

@@ -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 { homedir } from "os"
import { join, resolve } from "path" import { join, resolve } from "path"
import { parseFrontmatter } from "../../shared/frontmatter" import { parseFrontmatter } from "../../shared/frontmatter"
@@ -22,8 +22,12 @@ function loadSkillsFromDir(skillsDir: string, scope: SkillScope): LoadedSkillAsC
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue if (!entry.isDirectory() && !entry.isSymbolicLink()) continue
let resolvedPath = skillPath let resolvedPath = skillPath
if (statSync(skillPath, { throwIfNoEntry: false })?.isSymbolicLink()) { try {
resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath)) if (lstatSync(skillPath, { throwIfNoEntry: false })?.isSymbolicLink()) {
resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath))
}
} catch {
continue
} }
const skillMdPath = join(resolvedPath, "SKILL.md") const skillMdPath = join(resolvedPath, "SKILL.md")

View File

@@ -1,5 +1,5 @@
import { tool } from "@opencode-ai/plugin" 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 { homedir } from "os"
import { join, resolve, basename } from "path" import { join, resolve, basename } from "path"
import { z } from "zod/v4" import { z } from "zod/v4"
@@ -39,7 +39,7 @@ function discoverSkillsFromDir(
if (entry.isDirectory() || entry.isSymbolicLink()) { if (entry.isDirectory() || entry.isSymbolicLink()) {
let resolvedPath = skillPath let resolvedPath = skillPath
try { try {
const stats = statSync(skillPath, { throwIfNoEntry: false }) const stats = lstatSync(skillPath, { throwIfNoEntry: false })
if (stats?.isSymbolicLink()) { if (stats?.isSymbolicLink()) {
resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath)) resolvedPath = resolve(skillPath, "..", readlinkSync(skillPath))
} }
@@ -85,7 +85,7 @@ const skillListForDescription = availableSkills
function resolveSymlink(skillPath: string): string { function resolveSymlink(skillPath: string): string {
try { try {
const stats = statSync(skillPath, { throwIfNoEntry: false }) const stats = lstatSync(skillPath, { throwIfNoEntry: false })
if (stats?.isSymbolicLink()) { if (stats?.isSymbolicLink()) {
return resolve(skillPath, "..", readlinkSync(skillPath)) return resolve(skillPath, "..", readlinkSync(skillPath))
} }