From 1a8cd4a3ee201b92332231dc44a2690b9c3bf9c5 Mon Sep 17 00:00:00 2001 From: Pine Date: Wed, 2 Sep 2026 14:50:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(market):=20=E6=8A=80=E8=83=BD=E5=8C=85?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E8=A7=A3=E6=9E=90=E2=80=94=E2=80=94=E4=BC=98?= =?UTF-8?q?=E5=85=88=E4=BB=8E=20SKILL.md=20frontmatter=20=E5=8F=96=20name?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=A0=B9=E7=9B=AE=E5=BD=95=20zip=20?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=8F=98=E6=88=90=20SKILL.md=20=E7=9A=84=20b?= =?UTF-8?q?ug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/market/routers.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/market/routers.py b/app/market/routers.py index 50ebf96..ceb1714 100644 --- a/app/market/routers.py +++ b/app/market/routers.py @@ -452,6 +452,7 @@ async def admin_upload_bundle( def _parse_skill_bundle(data: bytes) -> dict: """读取 zip 内 SKILL.md(frontmatter + content)→ bundle 结构。""" import zipfile + import re from io import BytesIO try: with zipfile.ZipFile(BytesIO(data)) as zf: @@ -465,7 +466,19 @@ def _parse_skill_bundle(data: bytes) -> dict: if n.startswith("__MACOSX") or n.endswith("/") or n.endswith((".DS_Store", "Thumbs.db")): continue files[n] = zf.read(n).decode("utf-8", errors="replace") - return {"name": skill_md.split("/SKILL.md")[0].strip("/"), "content": content, "files": files} + # 从 frontmatter 解析技能名称(优先),其次用 zip 内目录名,最后用文件名 + name = "" + fm_match = re.match(r"^---\s*\n(.*?)\n---", content, re.DOTALL) + if fm_match: + for line in fm_match.group(1).splitlines(): + if line.strip().startswith("name:"): + name = line.split(":", 1)[1].strip().strip('"').strip("'") + break + if not name: + # zip 路径形如 "my-skill/SKILL.md" → 取目录名 "my-skill";根目录 "SKILL.md" → 留空 + parts = skill_md.rsplit("/", 1) + name = parts[0] if len(parts) > 1 else "" + return {"name": name, "content": content, "files": files} except zipfile.BadZipFile: return {}