From 19838b78a7994dc27c295c94b7315136c7111589 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:58:57 +0900 Subject: [PATCH 1/9] fix(shared): add bounded project discovery helpers Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/shared/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/index.ts b/src/shared/index.ts index 5d2615d70..ee690e816 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -62,11 +62,11 @@ export * from "./truncate-description" export * from "./opencode-storage-paths" export * from "./opencode-message-dir" export * from "./opencode-command-dirs" +export * from "./project-discovery-dirs" export * from "./normalize-sdk-response" export * from "./session-directory-resolver" export * from "./prompt-tools" export * from "./internal-initiator-marker" export * from "./plugin-command-discovery" -export * from "./project-discovery-dirs" export { SessionCategoryRegistry } from "./session-category-registry" export * from "./plugin-identity" From 961cc788f6ade53ff51bce52b03fb9fc7552fa6e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:05 +0900 Subject: [PATCH 2/9] fix(shared): support opencode directory aliases Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/shared/opencode-command-dirs.test.ts | 2 +- src/shared/opencode-command-dirs.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/shared/opencode-command-dirs.test.ts b/src/shared/opencode-command-dirs.test.ts index 4b2ac48f0..e75b0284c 100644 --- a/src/shared/opencode-command-dirs.test.ts +++ b/src/shared/opencode-command-dirs.test.ts @@ -27,8 +27,8 @@ describe("opencode-command-dirs", () => { expect(dirs).toContain("/home/user/.config/opencode/profiles/opus/skills") expect(dirs).toContain("/home/user/.config/opencode/profiles/opus/skill") - expect(dirs).toContain("/home/user/.config/opencode/skills") expect(dirs).toContain("/home/user/.config/opencode/skill") + expect(dirs).toContain("/home/user/.config/opencode/skills") expect(dirs).toHaveLength(4) }) }) diff --git a/src/shared/opencode-command-dirs.ts b/src/shared/opencode-command-dirs.ts index 4431370ad..34f2ecce1 100644 --- a/src/shared/opencode-command-dirs.ts +++ b/src/shared/opencode-command-dirs.ts @@ -14,7 +14,6 @@ function getParentOpencodeConfigDir(configDir: string): string | null { export function getOpenCodeCommandDirs(options: OpenCodeConfigDirOptions): string[] { const configDir = getOpenCodeConfigDir(options) const parentConfigDir = getParentOpencodeConfigDir(configDir) - return Array.from( new Set([ join(configDir, "commands"), @@ -27,7 +26,6 @@ export function getOpenCodeCommandDirs(options: OpenCodeConfigDirOptions): strin export function getOpenCodeSkillDirs(options: OpenCodeConfigDirOptions): string[] { const configDir = getOpenCodeConfigDir(options) const parentConfigDir = getParentOpencodeConfigDir(configDir) - return Array.from( new Set([ join(configDir, "skills"), From 86a62aef45aae2a4627b07ebc02ebf42eeec0db7 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:13 +0900 Subject: [PATCH 3/9] fix(skills): discover ancestor project skill directories Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../project-skill-discovery.test.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/features/opencode-skill-loader/project-skill-discovery.test.ts diff --git a/src/features/opencode-skill-loader/project-skill-discovery.test.ts b/src/features/opencode-skill-loader/project-skill-discovery.test.ts new file mode 100644 index 000000000..0d34da8ea --- /dev/null +++ b/src/features/opencode-skill-loader/project-skill-discovery.test.ts @@ -0,0 +1,86 @@ +import { execFileSync } from "node:child_process" +import { afterEach, beforeEach, describe, expect, it } from "bun:test" +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs" +import { tmpdir } from "node:os" +import { join } from "node:path" +import { + discoverOpencodeProjectSkills, + discoverProjectAgentsSkills, + discoverProjectClaudeSkills, +} from "./loader" + +function writeSkill(directory: string, name: string, description: string): void { + mkdirSync(directory, { recursive: true }) + writeFileSync( + join(directory, "SKILL.md"), + `---\nname: ${name}\ndescription: ${description}\n---\nBody\n`, + ) +} + +describe("project skill discovery", () => { + let tempDir = "" + + beforeEach(() => { + tempDir = mkdtempSync(join(tmpdir(), "omo-project-skill-discovery-")) + }) + + afterEach(() => { + rmSync(tempDir, { recursive: true, force: true }) + }) + + it("discovers ancestor project skill directories up to the worktree root", async () => { + // given + const repositoryDir = join(tempDir, "repo") + const nestedDirectory = join(repositoryDir, "packages", "app", "src") + + mkdirSync(nestedDirectory, { recursive: true }) + execFileSync("git", ["init"], { + cwd: repositoryDir, + stdio: ["ignore", "ignore", "ignore"], + }) + + writeSkill( + join(repositoryDir, ".claude", "skills", "repo-claude"), + "repo-claude", + "Discovered from the repository root", + ) + writeSkill( + join(repositoryDir, ".agents", "skills", "repo-agents"), + "repo-agents", + "Discovered from the repository root", + ) + writeSkill( + join(repositoryDir, ".opencode", "skill", "repo-opencode"), + "repo-opencode", + "Discovered from the repository root", + ) + + writeSkill( + join(tempDir, ".claude", "skills", "outside-claude"), + "outside-claude", + "Should stay outside the worktree", + ) + writeSkill( + join(tempDir, ".agents", "skills", "outside-agents"), + "outside-agents", + "Should stay outside the worktree", + ) + writeSkill( + join(tempDir, ".opencode", "skills", "outside-opencode"), + "outside-opencode", + "Should stay outside the worktree", + ) + + // when + const [claudeSkills, agentSkills, opencodeSkills] = await Promise.all([ + discoverProjectClaudeSkills(nestedDirectory), + discoverProjectAgentsSkills(nestedDirectory), + discoverOpencodeProjectSkills(nestedDirectory), + ]) + + // then + expect(claudeSkills.map(skill => skill.name)).toEqual(["repo-claude"]) + expect(agentSkills.map(skill => skill.name)).toEqual(["repo-agents"]) + expect(opencodeSkills.map(skill => skill.name)).toEqual(["repo-opencode"]) + }) +}) From 8413bc6a91c87bb394ad622a136307c8d2a78db0 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:19 +0900 Subject: [PATCH 4/9] fix(skills): expand tilde config source paths Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../config-source-discovery.test.ts | 26 +++++++++++++++++++ .../config-source-discovery.ts | 1 + 2 files changed, 27 insertions(+) diff --git a/src/features/opencode-skill-loader/config-source-discovery.test.ts b/src/features/opencode-skill-loader/config-source-discovery.test.ts index 091118ce6..550a3a195 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.test.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test" import { mkdirSync, rmSync, writeFileSync } from "fs" +import { homedir } from "os" import { join } from "path" import { homedir, tmpdir } from "os" import { SkillsConfigSchema } from "../../config/schema/skills" @@ -101,4 +102,29 @@ describe("config source discovery", () => { // then expect(normalized).toBe("keep/nested/SKILL.md") }) + + it("loads skills from ~/ sources paths", async () => { + // given + const homeTestDir = join(homedir(), `.omo-config-source-${Date.now()}`) + const sourceDir = join(homeTestDir, "custom-skills") + writeSkill(join(sourceDir, "tilde-skill"), "tilde-skill", "Loaded from tilde source") + const config = SkillsConfigSchema.parse({ + sources: [{ path: `${homeTestDir.replace(homedir(), "~")}/custom-skills`, recursive: true }], + }) + + try { + // when + const skills = await discoverConfigSourceSkills({ + config, + configDir: join(TEST_DIR, "config"), + }) + + // then + const tildeSkill = skills.find((skill) => skill.name === "tilde-skill") + expect(tildeSkill).toBeDefined() + expect(tildeSkill?.definition.description).toContain("Loaded from tilde source") + } finally { + rmSync(homeTestDir, { recursive: true, force: true }) + } + }) }) diff --git a/src/features/opencode-skill-loader/config-source-discovery.ts b/src/features/opencode-skill-loader/config-source-discovery.ts index b290c8b30..ef3b9a8a6 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.ts @@ -1,6 +1,7 @@ import { promises as fs } from "fs" import { homedir } from "os" import { dirname, extname, isAbsolute, join, relative } from "path" +import { homedir } from "os" import picomatch from "picomatch" import type { SkillsConfig } from "../../config/schema" import { normalizeSkillsConfig } from "./merger/skills-config-normalizer" From 4c8aacef48729d75006a7225de0b398dec76e89e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:27 +0900 Subject: [PATCH 5/9] fix(agents): include .agents skills in agent awareness Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ...agent-config-handler-agents-skills.test.ts | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/plugin-handlers/agent-config-handler-agents-skills.test.ts diff --git a/src/plugin-handlers/agent-config-handler-agents-skills.test.ts b/src/plugin-handlers/agent-config-handler-agents-skills.test.ts new file mode 100644 index 000000000..593f22d9e --- /dev/null +++ b/src/plugin-handlers/agent-config-handler-agents-skills.test.ts @@ -0,0 +1,125 @@ +import type { AgentConfig } from "@opencode-ai/sdk" +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test" +import * as agents from "../agents" +import * as shared from "../shared" +import * as sisyphusJunior from "../agents/sisyphus-junior" +import type { OhMyOpenCodeConfig } from "../config" +import * as skillLoader from "../features/opencode-skill-loader" +import { applyAgentConfig } from "./agent-config-handler" +import type { PluginComponents } from "./plugin-components-loader" + +function createPluginComponents(): PluginComponents { + return { + commands: {}, + skills: {}, + agents: {}, + mcpServers: {}, + hooksConfigs: [], + plugins: [], + errors: [], + } +} + +function createPluginConfig(): OhMyOpenCodeConfig { + return { + sisyphus_agent: { + planner_enabled: false, + }, + } +} + +describe("applyAgentConfig .agents skills", () => { + let createBuiltinAgentsSpy: ReturnType + let createSisyphusJuniorAgentSpy: ReturnType + let discoverConfigSourceSkillsSpy: ReturnType + let discoverUserClaudeSkillsSpy: ReturnType + let discoverProjectClaudeSkillsSpy: ReturnType + let discoverOpencodeGlobalSkillsSpy: ReturnType + let discoverOpencodeProjectSkillsSpy: ReturnType + let discoverProjectAgentsSkillsSpy: ReturnType + let discoverGlobalAgentsSkillsSpy: ReturnType + let logSpy: ReturnType + + beforeEach(() => { + createBuiltinAgentsSpy = spyOn(agents, "createBuiltinAgents").mockResolvedValue({ + sisyphus: { name: "sisyphus", prompt: "builtin", mode: "primary" } satisfies AgentConfig, + }) + createSisyphusJuniorAgentSpy = spyOn( + sisyphusJunior, + "createSisyphusJuniorAgentWithOverrides", + ).mockReturnValue({ + name: "sisyphus-junior", + prompt: "junior", + mode: "all", + } satisfies AgentConfig) + discoverConfigSourceSkillsSpy = spyOn(skillLoader, "discoverConfigSourceSkills").mockResolvedValue([]) + discoverUserClaudeSkillsSpy = spyOn(skillLoader, "discoverUserClaudeSkills").mockResolvedValue([]) + discoverProjectClaudeSkillsSpy = spyOn(skillLoader, "discoverProjectClaudeSkills").mockResolvedValue([]) + discoverOpencodeGlobalSkillsSpy = spyOn(skillLoader, "discoverOpencodeGlobalSkills").mockResolvedValue([]) + discoverOpencodeProjectSkillsSpy = spyOn(skillLoader, "discoverOpencodeProjectSkills").mockResolvedValue([]) + discoverProjectAgentsSkillsSpy = spyOn(skillLoader, "discoverProjectAgentsSkills").mockResolvedValue([]) + discoverGlobalAgentsSkillsSpy = spyOn(skillLoader, "discoverGlobalAgentsSkills").mockResolvedValue([]) + logSpy = spyOn(shared, "log").mockImplementation(() => {}) + }) + + afterEach(() => { + createBuiltinAgentsSpy.mockRestore() + createSisyphusJuniorAgentSpy.mockRestore() + discoverConfigSourceSkillsSpy.mockRestore() + discoverUserClaudeSkillsSpy.mockRestore() + discoverProjectClaudeSkillsSpy.mockRestore() + discoverOpencodeGlobalSkillsSpy.mockRestore() + discoverOpencodeProjectSkillsSpy.mockRestore() + discoverProjectAgentsSkillsSpy.mockRestore() + discoverGlobalAgentsSkillsSpy.mockRestore() + logSpy.mockRestore() + }) + + test("calls .agents skill discovery during agent configuration", async () => { + // given + const directory = "/tmp/project" + + // when + await applyAgentConfig({ + config: { model: "anthropic/claude-opus-4-6", agent: {} }, + pluginConfig: createPluginConfig(), + ctx: { directory }, + pluginComponents: createPluginComponents(), + }) + + // then + expect(discoverProjectAgentsSkillsSpy).toHaveBeenCalledWith(directory) + expect(discoverGlobalAgentsSkillsSpy).toHaveBeenCalled() + }) + + test("passes discovered .agents skills to builtin agent creation", async () => { + // given + discoverProjectAgentsSkillsSpy.mockResolvedValue([ + { + name: "project-agent-skill", + definition: { name: "project-agent-skill", template: "project-template" }, + scope: "project", + }, + ]) + discoverGlobalAgentsSkillsSpy.mockResolvedValue([ + { + name: "global-agent-skill", + definition: { name: "global-agent-skill", template: "global-template" }, + scope: "user", + }, + ]) + + // when + await applyAgentConfig({ + config: { model: "anthropic/claude-opus-4-6", agent: {} }, + pluginConfig: createPluginConfig(), + ctx: { directory: "/tmp/project" }, + pluginComponents: createPluginComponents(), + }) + + // then + const discoveredSkills = createBuiltinAgentsSpy.mock.calls[0]?.[6] as Array<{ name: string }> + expect(discoveredSkills.map(skill => skill.name)).toContain("project-agent-skill") + expect(discoveredSkills.map(skill => skill.name)).toContain("global-agent-skill") + }) +}) From c637d77965f90883c672413283963862e5d68c3d Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:39 +0900 Subject: [PATCH 6/9] fix(commands): discover ancestor opencode project commands Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../claude-code-command-loader/loader.test.ts | 24 +++++++++++++++++++ .../claude-code-command-loader/loader.ts | 5 ++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/features/claude-code-command-loader/loader.test.ts b/src/features/claude-code-command-loader/loader.test.ts index dde2096c0..be7928d3f 100644 --- a/src/features/claude-code-command-loader/loader.test.ts +++ b/src/features/claude-code-command-loader/loader.test.ts @@ -1,3 +1,4 @@ +import { execFileSync } from "node:child_process" import { afterEach, beforeEach, describe, expect, it } from "bun:test" import { mkdirSync, rmSync, writeFileSync } from "node:fs" import { tmpdir } from "node:os" @@ -98,4 +99,27 @@ describe("claude-code command loader", () => { // then expect(commands["duplicate-global"]?.description).toBe("(opencode) Profile global command") }) + + it("#given nested project opencode commands in a worktree #when loadOpencodeProjectCommands is called #then it preserves slash names and stops at the worktree root", async () => { + // given + const repositoryDir = join(TEST_DIR, "repo") + const nestedDirectory = join(repositoryDir, "packages", "app", "src") + mkdirSync(nestedDirectory, { recursive: true }) + execFileSync("git", ["init"], { + cwd: repositoryDir, + stdio: ["ignore", "ignore", "ignore"], + }) + writeCommand(join(repositoryDir, ".opencode", "commands", "deploy"), "staging", "Deploy staging") + writeCommand(join(repositoryDir, ".opencode", "command"), "release", "Release command") + writeCommand(join(TEST_DIR, ".opencode", "commands"), "outside", "Outside command") + + // when + const commands = await loadOpencodeProjectCommands(nestedDirectory) + + // then + expect(commands["deploy/staging"]?.description).toBe("(opencode-project) Deploy staging") + expect(commands.release?.description).toBe("(opencode-project) Release command") + expect(commands.outside).toBeUndefined() + expect(commands["deploy:staging"]).toBeUndefined() + }) }) diff --git a/src/features/claude-code-command-loader/loader.ts b/src/features/claude-code-command-loader/loader.ts index aee1f6e59..b052f56bd 100644 --- a/src/features/claude-code-command-loader/loader.ts +++ b/src/features/claude-code-command-loader/loader.ts @@ -7,7 +7,6 @@ import { findProjectOpencodeCommandDirs, getClaudeConfigDir, getOpenCodeCommandDirs, - getOpenCodeConfigDir, } from "../../shared" import { log } from "../../shared/logger" import type { CommandScope, CommandDefinition, CommandFrontmatter, LoadedCommand } from "./types" @@ -51,7 +50,7 @@ async function loadCommandsFromDir( if (entry.isDirectory()) { if (entry.name.startsWith(".")) continue const subDirPath = join(commandsDir, entry.name) - const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name + const subPrefix = prefix ? `${prefix}/${entry.name}` : entry.name const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix) commands.push(...subCommands) continue @@ -61,7 +60,7 @@ async function loadCommandsFromDir( const commandPath = join(commandsDir, entry.name) const baseCommandName = basename(entry.name, ".md") - const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName + const commandName = prefix ? `${prefix}/${baseCommandName}` : baseCommandName try { const content = await fs.readFile(commandPath, "utf-8") From 097e2be7e823b972d3d1a44f57bfc731882f0a74 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 12:59:46 +0900 Subject: [PATCH 7/9] fix(slashcommand): discover nested opencode commands with slash names Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ...opencode-project-command-discovery.test.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/tools/slashcommand/opencode-project-command-discovery.test.ts diff --git a/src/tools/slashcommand/opencode-project-command-discovery.test.ts b/src/tools/slashcommand/opencode-project-command-discovery.test.ts new file mode 100644 index 000000000..f845d9b93 --- /dev/null +++ b/src/tools/slashcommand/opencode-project-command-discovery.test.ts @@ -0,0 +1,60 @@ +import { execFileSync } from "node:child_process" +import { afterEach, beforeEach, describe, expect, it } from "bun:test" +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs" +import { tmpdir } from "node:os" +import { join } from "node:path" +import { discoverCommandsSync } from "./command-discovery" + +function writeCommand(path: string, description: string, body: string): void { + mkdirSync(join(path, ".."), { recursive: true }) + writeFileSync(path, `---\ndescription: ${description}\n---\n${body}\n`) +} + +describe("opencode project command discovery", () => { + let tempDir = "" + + beforeEach(() => { + tempDir = mkdtempSync(join(tmpdir(), "omo-opencode-project-command-discovery-")) + }) + + afterEach(() => { + rmSync(tempDir, { recursive: true, force: true }) + }) + + it("discovers ancestor opencode commands with slash-separated nested names and worktree boundaries", () => { + // given + const repositoryDir = join(tempDir, "repo") + const nestedDirectory = join(repositoryDir, "packages", "app", "src") + + mkdirSync(nestedDirectory, { recursive: true }) + execFileSync("git", ["init"], { + cwd: repositoryDir, + stdio: ["ignore", "ignore", "ignore"], + }) + + writeCommand( + join(repositoryDir, ".opencode", "commands", "deploy", "staging.md"), + "Deploy to staging", + "Run the staged deploy.", + ) + writeCommand( + join(repositoryDir, ".opencode", "command", "release.md"), + "Release command", + "Run the release.", + ) + writeCommand( + join(tempDir, ".opencode", "commands", "outside.md"), + "Outside command", + "Should not be discovered.", + ) + + // when + const names = discoverCommandsSync(nestedDirectory).map(command => command.name) + + // then + expect(names).toContain("deploy/staging") + expect(names).toContain("release") + expect(names).not.toContain("deploy:staging") + expect(names).not.toContain("outside") + }) +}) From 5bc019eb7c1beadb12dab53db7765a68d028969e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 13:06:32 +0900 Subject: [PATCH 8/9] fix(skills): remove duplicate homedir import Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/features/opencode-skill-loader/config-source-discovery.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/features/opencode-skill-loader/config-source-discovery.ts b/src/features/opencode-skill-loader/config-source-discovery.ts index ef3b9a8a6..b290c8b30 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.ts @@ -1,7 +1,6 @@ import { promises as fs } from "fs" import { homedir } from "os" import { dirname, extname, isAbsolute, join, relative } from "path" -import { homedir } from "os" import picomatch from "picomatch" import type { SkillsConfig } from "../../config/schema" import { normalizeSkillsConfig } from "./merger/skills-config-normalizer" From 42f5386100fe540532fc08f1f82638d95e8d8f33 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 13:08:53 +0900 Subject: [PATCH 9/9] fix(tests): drop duplicate tilde config regression Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../config-source-discovery.test.ts | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/features/opencode-skill-loader/config-source-discovery.test.ts b/src/features/opencode-skill-loader/config-source-discovery.test.ts index 550a3a195..091118ce6 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.test.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.test.ts @@ -1,6 +1,5 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test" import { mkdirSync, rmSync, writeFileSync } from "fs" -import { homedir } from "os" import { join } from "path" import { homedir, tmpdir } from "os" import { SkillsConfigSchema } from "../../config/schema/skills" @@ -102,29 +101,4 @@ describe("config source discovery", () => { // then expect(normalized).toBe("keep/nested/SKILL.md") }) - - it("loads skills from ~/ sources paths", async () => { - // given - const homeTestDir = join(homedir(), `.omo-config-source-${Date.now()}`) - const sourceDir = join(homeTestDir, "custom-skills") - writeSkill(join(sourceDir, "tilde-skill"), "tilde-skill", "Loaded from tilde source") - const config = SkillsConfigSchema.parse({ - sources: [{ path: `${homeTestDir.replace(homedir(), "~")}/custom-skills`, recursive: true }], - }) - - try { - // when - const skills = await discoverConfigSourceSkills({ - config, - configDir: join(TEST_DIR, "config"), - }) - - // then - const tildeSkill = skills.find((skill) => skill.name === "tilde-skill") - expect(tildeSkill).toBeDefined() - expect(tildeSkill?.definition.description).toContain("Loaded from tilde source") - } finally { - rmSync(homeTestDir, { recursive: true, force: true }) - } - }) })