Extract skill loading pipeline into single-responsibility modules: - skill-discovery.ts, skill-directory-loader.ts, skill-deduplication.ts - loaded-skill-from-path.ts, loaded-skill-template-extractor.ts - skill-template-resolver.ts, skill-definition-record.ts - git-master-template-injection.ts, allowed-tools-parser.ts - skill-mcp-config.ts, skill-resolution-options.ts - merger/ directory for skill merging logic
46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import { promises as fs } from "fs"
|
|
import { join } from "path"
|
|
import yaml from "js-yaml"
|
|
import type { SkillMcpConfig } from "../skill-mcp-manager/types"
|
|
|
|
export function parseSkillMcpConfigFromFrontmatter(content: string): SkillMcpConfig | undefined {
|
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/)
|
|
if (!frontmatterMatch) return undefined
|
|
|
|
try {
|
|
const parsed = yaml.load(frontmatterMatch[1]) as Record<string, unknown>
|
|
if (parsed && typeof parsed === "object" && "mcp" in parsed && parsed.mcp) {
|
|
return parsed.mcp as SkillMcpConfig
|
|
}
|
|
} catch {
|
|
return undefined
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
export async function loadMcpJsonFromDir(skillDir: string): Promise<SkillMcpConfig | undefined> {
|
|
const mcpJsonPath = join(skillDir, "mcp.json")
|
|
|
|
try {
|
|
const content = await fs.readFile(mcpJsonPath, "utf-8")
|
|
const parsed = JSON.parse(content) as Record<string, unknown>
|
|
|
|
if (parsed && typeof parsed === "object" && "mcpServers" in parsed && parsed.mcpServers) {
|
|
return parsed.mcpServers as SkillMcpConfig
|
|
}
|
|
|
|
if (parsed && typeof parsed === "object" && !("mcpServers" in parsed)) {
|
|
const hasCommandField = Object.values(parsed).some(
|
|
(value) => value && typeof value === "object" && "command" in (value as Record<string, unknown>)
|
|
)
|
|
if (hasCommandField) {
|
|
return parsed as SkillMcpConfig
|
|
}
|
|
}
|
|
} catch {
|
|
return undefined
|
|
}
|
|
|
|
return undefined
|
|
}
|