MCPcopy Index your code
hub / github.com/scriptscat/scriptcat / parseSkillMd

Function parseSkillMd

src/pkg/utils/skill.ts:20–79  ·  view source on GitHub ↗
(content: string)

Source from the content-addressed store, hash-verified

18
19// 解析 SKILL.cat.md 内容:YAML frontmatter + markdown body
20export function parseSkillMd(content: string): { metadata: SkillMetadata; prompt: string } | null {
21 const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
22 if (!match) return null;
23
24 const [, frontmatter, body] = match;
25
26 let parsed: Record<string, unknown>;
27 try {
28 parsed = parseYaml(frontmatter);
29 } catch {
30 return null;
31 }
32
33 if (!parsed || typeof parsed !== "object") return null;
34
35 const name = typeof parsed.name === "string" ? parsed.name : "";
36 if (!name) return null;
37
38 const description = typeof parsed.description === "string" ? parsed.description : "";
39 const version = typeof parsed.version === "string" ? parsed.version : undefined;
40
41 // 解析 scripts 文件名列表(URL 安装时使用)
42 const scripts = Array.isArray(parsed.scripts)
43 ? parsed.scripts.filter((s): s is string => typeof s === "string")
44 : undefined;
45
46 // 解析 references 文件名列表(URL 安装时使用)
47 const references = Array.isArray(parsed.references)
48 ? parsed.references.filter((r): r is string => typeof r === "string")
49 : undefined;
50
51 // 解析 config 块
52 let config: Record<string, SkillConfigField> | undefined;
53 if (parsed.config && typeof parsed.config === "object" && !Array.isArray(parsed.config)) {
54 const rawConfig = parsed.config as Record<string, unknown>;
55 const entries = Object.entries(rawConfig);
56 if (entries.length > 0) {
57 config = {};
58 for (const [key, value] of entries) {
59 if (value && typeof value === "object" && !Array.isArray(value)) {
60 config[key] = normalizeConfigField(value as Record<string, unknown>);
61 }
62 }
63 // 如果解析后没有有效字段,置为 undefined
64 if (Object.keys(config).length === 0) config = undefined;
65 }
66 }
67
68 return {
69 metadata: {
70 name,
71 description,
72 ...(version ? { version } : {}),
73 ...(scripts?.length ? { scripts } : {}),
74 ...(references?.length ? { references } : {}),
75 ...(config ? { config } : {}),
76 },
77 prompt: body.trim(),

Callers 5

skill.test.tsFile · 0.90
installSkillMethod · 0.90
fetchSkillResourcesMethod · 0.90
checkSkillUpdateMethod · 0.90
getSkillInstallDataMethod · 0.90

Calls 3

normalizeConfigFieldFunction · 0.85
entriesMethod · 0.80
keysMethod · 0.80

Tested by

no test coverage detected