From c79ba0d4017332cb15394c5d9f93d9761e17b88b Mon Sep 17 00:00:00 2001 From: PratikDhanave Date: Sun, 13 Sep 2026 18:30:48 +0530 Subject: [PATCH] Keep skill metadata keys that follow a blank line in the block The metadata block regex captured ((?:[ \t]+\S.*\n?)+), whose repetition terminates at the first line that is not indented-then-non-space. A blank line is legal and common inside a YAML mapping block, so any metadata key after a blank line was silently dropped - inconsistent with a real YAML parser and with the sibling block-scalar parsing, which tolerate blank lines. Allow blank lines within the captured block (they are ignored by the per-key extraction); a de-dented line still ends the block. --- agent/skills/fsskills/source.go | 2 +- agent/skills/fsskills/source_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/agent/skills/fsskills/source.go b/agent/skills/fsskills/source.go index 18a428d4..369df8b0 100644 --- a/agent/skills/fsskills/source.go +++ b/agent/skills/fsskills/source.go @@ -37,7 +37,7 @@ var ( var ( frontmatterRegex = regexp.MustCompile(`(?ms)\A^---\s*$(.+?)^---\s*$`) yamlKeyValueRegex = regexp.MustCompile(`(?m)^([\w-]+)\s*:\s*(?:["'](.+?)["']|(.+?))\s*$`) - yamlMetadataBlockRegex = regexp.MustCompile(`(?m)^metadata\s*:\s*$\n((?:[ \t]+\S.*\n?)+)`) + yamlMetadataBlockRegex = regexp.MustCompile(`(?m)^metadata\s*:\s*$\n((?:[ \t]+\S.*\n?|[ \t]*\n)+)`) yamlIndentedKeyValueRegex = regexp.MustCompile(`(?m)^\s+([\w-]+)\s*:\s*(?:["'](.+?)["']|(.+?))\s*$`) ) diff --git a/agent/skills/fsskills/source_test.go b/agent/skills/fsskills/source_test.go index a2a5763c..557024b4 100644 --- a/agent/skills/fsskills/source_test.go +++ b/agent/skills/fsskills/source_test.go @@ -706,3 +706,29 @@ func createSymlink(t *testing.T, linkPath, targetPath string) { t.Skipf("symlink creation unavailable: %v", err) } } + +func TestFileSource_MetadataWithBlankLine_KeepsAllKeys(t *testing.T) { + root := t.TempDir() + createSkillDirRaw(t, root, "gap-meta", strings.Join([]string{ + "---", + "name: gap-meta", + "description: d", + "metadata:", + " a: 1", + "", + " b: 2", + " c: 3", + "---", + "Body.", + }, "\n")) + + source := fsskills.NewSource(os.DirFS(root)) + loaded, err := source.Skills(t.Context()) + if err != nil { + t.Fatal(err) + } + m := loaded[0].Frontmatter.Metadata + if m["a"] != "1" || m["b"] != "2" || m["c"] != "3" { + t.Fatalf("metadata keys dropped after blank line: %#v", m) + } +}