From 82425008561fedb32485217ea9559794737eb7ba Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 26 Mar 2026 11:22:00 +0900 Subject: [PATCH] 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 | 24 ++++++++++++++++++- .../config-source-discovery.ts | 9 +++++++ 2 files changed, 32 insertions(+), 1 deletion(-) 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 d10303ce0..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,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test" import { mkdirSync, rmSync, writeFileSync } from "fs" import { join } from "path" -import { tmpdir } from "os" +import { homedir, tmpdir } from "os" import { SkillsConfigSchema } from "../../config/schema/skills" import { discoverConfigSourceSkills, normalizePathForGlob } from "./config-source-discovery" @@ -69,6 +69,28 @@ describe("config source discovery", () => { expect(names).not.toContain("skip/skipped-skill") }) + it("loads skills from ~/ sources path", async () => { + // given + const homeSkillsDir = join(homedir(), `.omo-config-source-${Date.now()}`) + writeSkill(join(homeSkillsDir, "tilde-skill"), "tilde-skill", "Loaded from tilde path") + const config = SkillsConfigSchema.parse({ + sources: [{ path: `~/${homeSkillsDir.split(homedir())[1]?.replace(/^\//, "")}`, recursive: true }], + }) + + try { + // when + const skills = await discoverConfigSourceSkills({ + config, + configDir: join(TEST_DIR, "config"), + }) + + // then + expect(skills.some((skill) => skill.name === "tilde-skill")).toBe(true) + } finally { + rmSync(homeSkillsDir, { recursive: true, force: true }) + } + }) + it("normalizes windows separators before glob matching", () => { // given const windowsPath = "keep\\nested\\SKILL.md" diff --git a/src/features/opencode-skill-loader/config-source-discovery.ts b/src/features/opencode-skill-loader/config-source-discovery.ts index df3ee653e..b290c8b30 100644 --- a/src/features/opencode-skill-loader/config-source-discovery.ts +++ b/src/features/opencode-skill-loader/config-source-discovery.ts @@ -1,4 +1,5 @@ import { promises as fs } from "fs" +import { homedir } from "os" import { dirname, extname, isAbsolute, join, relative } from "path" import picomatch from "picomatch" import type { SkillsConfig } from "../../config/schema" @@ -15,6 +16,14 @@ function isHttpUrl(path: string): boolean { } function toAbsolutePath(path: string, configDir: string): string { + if (path === "~") { + return homedir() + } + + if (path.startsWith("~/")) { + return join(homedir(), path.slice(2)) + } + if (isAbsolute(path)) { return path }