feat(worker): session skill registry (install/update/remove, pinned clone)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
namespace ClaudeDo.Worker.Skills;
|
||||
|
||||
internal static class SkillFrontmatter
|
||||
{
|
||||
public sealed record ParsedFrontmatter(string Name, string Description);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the YAML frontmatter block (between the first two "---" lines) of a SKILL.md
|
||||
/// file, extracting "name" (required) and "description" (optional). The description may
|
||||
/// be a folded scalar ("description: >"), whose indented continuation lines are joined
|
||||
/// with spaces into a single string.
|
||||
/// </summary>
|
||||
public static ParsedFrontmatter Parse(string skillMdPath)
|
||||
{
|
||||
var lines = File.ReadAllLines(skillMdPath);
|
||||
if (lines.Length == 0 || lines[0].Trim() != "---")
|
||||
throw new InvalidOperationException($"'{skillMdPath}' has no YAML frontmatter block.");
|
||||
|
||||
string? name = null;
|
||||
var description = "";
|
||||
|
||||
var i = 1;
|
||||
for (; i < lines.Length; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
if (line.Trim() == "---") break;
|
||||
|
||||
if (line.StartsWith("name:", StringComparison.Ordinal))
|
||||
{
|
||||
name = line["name:".Length..].Trim().Trim('"', '\'');
|
||||
}
|
||||
else if (line.StartsWith("description:", StringComparison.Ordinal))
|
||||
{
|
||||
var rest = line["description:".Length..].Trim();
|
||||
if (rest == ">" || rest == ">-" || rest == "|" || rest == "|-")
|
||||
{
|
||||
var folded = new List<string>();
|
||||
var j = i + 1;
|
||||
for (; j < lines.Length; j++)
|
||||
{
|
||||
var contLine = lines[j];
|
||||
if (contLine.Trim() == "---") break;
|
||||
if (contLine.Length == 0) continue;
|
||||
if (!char.IsWhiteSpace(contLine[0])) break;
|
||||
folded.Add(contLine.Trim());
|
||||
}
|
||||
description = string.Join(" ", folded);
|
||||
i = j - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
description = rest.Trim('"', '\'');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
throw new InvalidOperationException($"'{skillMdPath}' frontmatter is missing required 'name'.");
|
||||
|
||||
return new ParsedFrontmatter(name, description);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user