mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-30 19:59:38 +02:00
[eric] skills: frontmatter parser reads YAML block scalars, so a |- description no longer renders literally (ENG-307)
This commit is contained in:
@@ -23,10 +23,24 @@ def parse_frontmatter(raw: str) -> tuple[dict, str]:
|
||||
fm_block = raw[3:end].strip()
|
||||
body = raw[end + 3:].strip()
|
||||
meta: dict = {}
|
||||
for line in fm_block.splitlines():
|
||||
m = re.match(r"^(\w[\w_-]*)\s*:\s*(.+)$", line)
|
||||
if m:
|
||||
meta[m.group(1).strip()] = m.group(2).strip().strip('"').strip("'")
|
||||
lines = fm_block.splitlines()
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
m = re.match(r"^(\w[\w_-]*)\s*:\s*(.*)$", lines[i])
|
||||
i += 1
|
||||
if not m:
|
||||
continue
|
||||
key, val = m.group(1).strip(), m.group(2).strip()
|
||||
if re.fullmatch(r"[|>][+-]?", val):
|
||||
# YAML block scalar: the text is the indented lines below; the bare indicator once shipped as a card's whole description (ENG-307).
|
||||
block: list[str] = []
|
||||
while i < len(lines) and (not lines[i].strip() or lines[i][0] in (" ", "\t")):
|
||||
block.append(lines[i].strip())
|
||||
i += 1
|
||||
joiner = "\n" if val[0] == "|" else " "
|
||||
meta[key] = joiner.join(b for b in block if b).strip()
|
||||
else:
|
||||
meta[key] = val.strip('"').strip("'")
|
||||
return meta, body
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import time
|
||||
import zipfile
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import HTTPException
|
||||
from backend.apps.skill_registry.skill_registry_github import parse_frontmatter
|
||||
from backend.config.Apps import SubApp
|
||||
from backend.apps.skills.models import Skill, SkillCreate, SkillLoadRequest, SkillUpdate, SkillUpload, SkillWorkspaceSeedRequest
|
||||
|
||||
@@ -339,18 +340,7 @@ async def load_skill(body: SkillLoadRequest):
|
||||
|
||||
def p_parse_skill_frontmatter(raw: str) -> dict:
|
||||
"""Extract YAML frontmatter fields from a SKILL.md file."""
|
||||
if not raw.startswith("---"):
|
||||
return {}
|
||||
end = raw.find("---", 3)
|
||||
if end == -1:
|
||||
return {}
|
||||
fm_block = raw[3:end].strip()
|
||||
meta: dict = {}
|
||||
for line in fm_block.splitlines():
|
||||
m = re.match(r"^(\w[\w_-]*)\s*:\s*(.+)$", line)
|
||||
if m:
|
||||
meta[m.group(1).strip()] = m.group(2).strip().strip('"').strip("'")
|
||||
return meta
|
||||
return parse_frontmatter(raw)[0]
|
||||
|
||||
|
||||
@skills.router.post("/workspace/seed")
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""A SKILL.md whose description uses a YAML block scalar rendered as the literal string "|-" on
|
||||
its marketplace card (ENG-307, seen live on /claude-api). The line-regex parser matched the
|
||||
indicator as the value and dropped the indented block below it. One parser now serves both the
|
||||
registry and the upload path, and it reads block scalars.
|
||||
"""
|
||||
from backend.apps.skill_registry.skill_registry_github import parse_frontmatter
|
||||
from backend.apps.skills.skills import p_parse_skill_frontmatter
|
||||
|
||||
|
||||
def test_literal_block_scalar_reads_the_indented_text():
|
||||
meta, body = parse_frontmatter("---\nname: claude-api\ndescription: |-\n Talk to the API\n with retries.\n---\nBody")
|
||||
assert meta["description"] == "Talk to the API\nwith retries."
|
||||
assert meta["name"] == "claude-api"
|
||||
assert body == "Body"
|
||||
|
||||
|
||||
def test_folded_scalar_joins_with_spaces():
|
||||
meta, _ = parse_frontmatter("---\ndescription: >-\n One line\n folded.\n---\n")
|
||||
assert meta["description"] == "One line folded."
|
||||
|
||||
|
||||
def test_plain_and_quoted_values_are_unchanged():
|
||||
meta, _ = parse_frontmatter('---\nname: "quoted"\nlicense: MIT\n---\n')
|
||||
assert meta == {"name": "quoted", "license": "MIT"}
|
||||
|
||||
|
||||
def test_empty_block_scalar_yields_empty_not_the_indicator():
|
||||
meta, _ = parse_frontmatter("---\ndescription: |-\nname: x\n---\n")
|
||||
assert meta["description"] == ""
|
||||
assert meta["name"] == "x"
|
||||
|
||||
|
||||
def test_upload_path_uses_the_same_parser():
|
||||
meta = p_parse_skill_frontmatter("---\ndescription: |-\n Uploaded skill.\n---\n")
|
||||
assert meta["description"] == "Uploaded skill."
|
||||
Reference in New Issue
Block a user