fix: add adaptHostSkillConfig utility for host config.skills.paths
Converts the host OpenCode config.skills object (with paths/urls arrays set by other plugins like superpowers) into the SkillsConfig format used by discoverConfigSourceSkills. Filters blank/whitespace entries and non-string values. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
|
||||||
|
import { adaptHostSkillConfig } from "./host-skill-config"
|
||||||
|
|
||||||
|
describe("adaptHostSkillConfig", () => {
|
||||||
|
test("converts paths and urls into SkillsConfig sources", () => {
|
||||||
|
// given
|
||||||
|
const hostConfig = {
|
||||||
|
paths: ["/host/skills", "/other/skills"],
|
||||||
|
urls: ["https://example.com/skills/"],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = adaptHostSkillConfig(hostConfig)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
sources: ["/host/skills", "/other/skills", "https://example.com/skills/"],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("filters blank and whitespace-only entries", () => {
|
||||||
|
// given
|
||||||
|
const hostConfig = {
|
||||||
|
paths: ["", " ", "/real/skills"],
|
||||||
|
urls: ["\n", "https://example.com/skills/"],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = adaptHostSkillConfig(hostConfig)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({
|
||||||
|
sources: ["/real/skills", "https://example.com/skills/"],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns undefined when no usable sources remain", () => {
|
||||||
|
// when
|
||||||
|
const result = adaptHostSkillConfig({ paths: ["", " "], urls: ["\t"] })
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns undefined for null input", () => {
|
||||||
|
expect(adaptHostSkillConfig(null)).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns undefined for undefined input", () => {
|
||||||
|
expect(adaptHostSkillConfig(undefined)).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns undefined for non-object input", () => {
|
||||||
|
expect(adaptHostSkillConfig("string")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("handles missing paths or urls gracefully", () => {
|
||||||
|
// when - only paths
|
||||||
|
const pathsOnly = adaptHostSkillConfig({ paths: ["/skills"] })
|
||||||
|
expect(pathsOnly).toEqual({ sources: ["/skills"] })
|
||||||
|
|
||||||
|
// when - only urls
|
||||||
|
const urlsOnly = adaptHostSkillConfig({ urls: ["https://example.com/skills/"] })
|
||||||
|
expect(urlsOnly).toEqual({ sources: ["https://example.com/skills/"] })
|
||||||
|
})
|
||||||
|
|
||||||
|
test("ignores non-string array elements", () => {
|
||||||
|
// given
|
||||||
|
const hostConfig = {
|
||||||
|
paths: ["/valid", 42, null, true, "/also-valid"],
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = adaptHostSkillConfig(hostConfig)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toEqual({ sources: ["/valid", "/also-valid"] })
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import type { SkillsConfig } from "../config/schema/skills"
|
||||||
|
|
||||||
|
type HostSkillConfig = {
|
||||||
|
paths?: unknown
|
||||||
|
urls?: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
function toStringArray(value: unknown): string[] {
|
||||||
|
if (!Array.isArray(value)) return []
|
||||||
|
return value
|
||||||
|
.filter((item): item is string => typeof item === "string")
|
||||||
|
.map((item) => item.trim())
|
||||||
|
.filter((item) => item.length > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adaptHostSkillConfig(value: unknown): SkillsConfig | undefined {
|
||||||
|
if (!value || typeof value !== "object") return undefined
|
||||||
|
|
||||||
|
const hostSkillConfig = value as HostSkillConfig
|
||||||
|
const sources = [
|
||||||
|
...toStringArray(hostSkillConfig.paths),
|
||||||
|
...toStringArray(hostSkillConfig.urls),
|
||||||
|
]
|
||||||
|
|
||||||
|
if (sources.length === 0) return undefined
|
||||||
|
|
||||||
|
return { sources } as SkillsConfig
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user