diff --git a/src/features/opencode-skill-loader/config-source-discovery.ts b/src/features/opencode-skill-loader/config-source-discovery.ts index df3ee653..5d98cf51 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.ts @@ -53,26 +53,28 @@ async function loadSourcePath(options: { const stat = await fs.stat(absolutePath).catch(() => null) if (!stat) return [] + const realBasePath = await fs.realpath(absolutePath).catch(() => absolutePath) + if (stat.isFile()) { - if (!isMarkdownPath(absolutePath)) return [] + if (!isMarkdownPath(realBasePath)) return [] const loaded = await loadSkillFromPath({ - skillPath: absolutePath, - resolvedPath: dirname(absolutePath), - defaultName: inferSkillNameFromFileName(absolutePath), + skillPath: realBasePath, + resolvedPath: dirname(realBasePath), + defaultName: inferSkillNameFromFileName(realBasePath), scope: "config", }) if (!loaded) return [] - return filterByGlob([loaded], dirname(absolutePath), options.globPattern) + return filterByGlob([loaded], dirname(realBasePath), options.globPattern) } if (!stat.isDirectory()) return [] const directorySkills = await loadSkillsFromDir({ - skillsDir: absolutePath, + skillsDir: realBasePath, scope: "config", maxDepth: options.recursive ? MAX_RECURSIVE_DEPTH : 0, }) - return filterByGlob(directorySkills, absolutePath, options.globPattern) + return filterByGlob(directorySkills, realBasePath, options.globPattern) } export async function discoverConfigSourceSkills(options: { diff --git a/src/shared/agents-config-dir.test.ts b/src/shared/agents-config-dir.test.ts new file mode 100644 index 00000000..6b4508c6 --- /dev/null +++ b/src/shared/agents-config-dir.test.ts @@ -0,0 +1,14 @@ +import { describe, test, expect } from "bun:test" +import { getAgentsConfigDir } from "./agents-config-dir" + +describe("getAgentsConfigDir", () => { + test("returns path ending with .agents", () => { + // given agents config dir is requested + + // when getAgentsConfigDir is called + const result = getAgentsConfigDir() + + // then returns path ending with .agents + expect(result.endsWith(".agents")).toBe(true) + }) +}) diff --git a/src/shared/agents-config-dir.ts b/src/shared/agents-config-dir.ts new file mode 100644 index 00000000..d43c2918 --- /dev/null +++ b/src/shared/agents-config-dir.ts @@ -0,0 +1,6 @@ +import { homedir } from "node:os" +import { join } from "node:path" + +export function getAgentsConfigDir(): string { + return join(homedir(), ".agents") +} diff --git a/src/shared/file-utils.test.ts b/src/shared/file-utils.test.ts index 82d16dab..1ee41d21 100644 --- a/src/shared/file-utils.test.ts +++ b/src/shared/file-utils.test.ts @@ -1,10 +1,10 @@ import { describe, it, expect, beforeAll, afterAll } from "bun:test" -import { mkdirSync, writeFileSync, symlinkSync, rmSync } from "fs" +import { mkdirSync, writeFileSync, symlinkSync, rmSync, realpathSync } from "fs" import { join } from "path" import { tmpdir } from "os" import { resolveSymlink, resolveSymlinkAsync, isSymbolicLink } from "./file-utils" -const testDir = join(tmpdir(), "file-utils-test-" + Date.now()) +const testDir = join(realpathSync(tmpdir()), "file-utils-test-" + Date.now()) // Create a directory structure that mimics the real-world scenario: //