feat: skill 名字允许下划线分隔

放宽 skill 命名校验:除连字符外也接受下划线作为分隔符,首尾和连续
分隔符的限制扩展到 _ 与混合分隔(--、__、-_、_- 都拒绝)。前置
frontmatter 校验与存储层正则同步放宽。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xuhdandClaude Opus 4.7 committed 2026-05-14 10:41:37 +08:00
1 parent 434cf40b36
commit 230eec1baf
2 files changed
+7 -7

No files matched your search

@@ -12,7 +12,7 @@ from deerflow.skills.types import SKILL_MD_FILE, Skill, SkillCategory # noqa: F
logger = logging.getLogger(__name__)
_SKILL_NAME_PATTERN = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
_SKILL_NAME_PATTERN = re.compile(r"^[a-z0-9]+(?:[_-][a-z0-9]+)*$")
class SkillStorage(ABC):
@@ -36,7 +36,7 @@ class SkillStorage(ABC):
"""Validate and normalise a skill name; return the normalised form."""
normalized = name.strip()
if not _SKILL_NAME_PATTERN.fullmatch(normalized):
raise ValueError("Skill name must be hyphen-case using lowercase letters, digits, and hyphens only.")
raise ValueError("Skill name must use lowercase letters and digits separated by '-' or '_' only.")
if len(normalized) > 64:
raise ValueError("Skill name must be 64 characters or fewer.")
return normalized
@@ -65,11 +65,11 @@ def _validate_skill_frontmatter(skill_dir: Path) -> tuple[bool, str, str | None]
if not name:
return False, "Name cannot be empty", None
# Check naming convention (hyphen-case: lowercase with hyphens)
if not re.match(r"^[a-z0-9-]+$", name):
return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)", None
if name.startswith("-") or name.endswith("-") or "--" in name:
return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens", None
# Check naming convention (lowercase letters/digits separated by '-' or '_')
if not re.match(r"^[a-z0-9_-]+$", name):
return False, f"Name '{name}' should be lowercase letters, digits, hyphens or underscores only", None
if name[0] in "-_" or name[-1] in "-_" or re.search(r"[-_]{2,}", name):
return False, f"Name '{name}' cannot start/end with '-' or '_' or contain consecutive separators", None
if len(name) > 64:
return False, f"Name is too long ({len(name)} characters). Maximum is 64 characters.", None