Allow skill slugs without a platform suffix.
All checks were successful
技能自动化发布 / release (push) Successful in 9s
All checks were successful
技能自动化发布 / release (push) Successful in 9s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
||||
|
||||
SKILL_SLUG = "your-skill-slug"
|
||||
SKILL_VERSION = "1.0.111"
|
||||
SKILL_VERSION = "1.0.112"
|
||||
LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug"
|
||||
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
||||
|
||||
@@ -7,7 +7,7 @@ import re
|
||||
|
||||
_KEBAB_SLUG = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
|
||||
_MAX_SLUG_LENGTH = 48
|
||||
_MIN_SEGMENTS = 3
|
||||
_MIN_SEGMENTS = 2
|
||||
_MAX_SEGMENTS = 5
|
||||
_MAX_NOUN_SEGMENTS = 3
|
||||
|
||||
@@ -60,7 +60,9 @@ _BUILTIN_PLATFORMS = frozenset(
|
||||
"etax",
|
||||
}
|
||||
)
|
||||
_BUILTIN_SCOPES = frozenset({"all", "batch", "multi", "default"})
|
||||
_BUILTIN_SCOPES = frozenset({"all", "batch", "multi"})
|
||||
# 旧技能用 default 占位末段。不再当成合法 scope;校验只警告,避免同步后挡住已发布仓库。
|
||||
_DEPRECATED_PLATFORM_PLACEHOLDER = "default"
|
||||
|
||||
LEGACY_EXEMPT_SLUGS: frozenset[str] = frozenset(
|
||||
{
|
||||
@@ -117,11 +119,12 @@ def _match_platform_suffix(
|
||||
|
||||
def classify_slug_form(segments: list[str], *, slug: str = "") -> str:
|
||||
"""
|
||||
返回: 'legacy_exempt' | 'standard' | 'scope' | 'invalid'
|
||||
返回: 'legacy_exempt' | 'standard' | 'scope' | 'plain' | 'invalid'
|
||||
|
||||
- legacy_exempt: slug in LEGACY_EXEMPT_SLUGS
|
||||
- standard: 末段匹配 platforms, 首段 in verbs, 3<=len<=5
|
||||
- scope: 末段 in scopes, 首段 in verbs, 3<=len<=5
|
||||
- standard: 末段匹配 platforms,首段 in verbs,2<=len<=5,且动词后至少还有一段名词
|
||||
- scope: 末段 in scopes(all/batch/multi),首段 in verbs,至少 verb-noun-scope
|
||||
- plain: 动词 + 名词,无平台、无 scope
|
||||
- invalid: 其他
|
||||
"""
|
||||
if slug in LEGACY_EXEMPT_SLUGS:
|
||||
@@ -138,12 +141,14 @@ def classify_slug_form(segments: list[str], *, slug: str = "") -> str:
|
||||
return "invalid"
|
||||
|
||||
if segments[-1] in scopes:
|
||||
if len(segments) < 3:
|
||||
return "invalid"
|
||||
return "scope"
|
||||
|
||||
if _match_platform_suffix(segments, platforms) is not None:
|
||||
return "standard"
|
||||
|
||||
return "invalid"
|
||||
return "plain"
|
||||
|
||||
|
||||
def validate_slug_semantics(
|
||||
@@ -173,8 +178,8 @@ def validate_slug_semantics(
|
||||
|
||||
if segment_count < _MIN_SEGMENTS:
|
||||
msg = (
|
||||
f"slug 段数应为 {_MIN_SEGMENTS}~{_MAX_SEGMENTS}(verb-noun-platform),"
|
||||
f"当前为 {segment_count} 段:{slug!r};新技能禁止 2 段无平台形态(如 reconcile-finance)"
|
||||
f"slug 段数应为 {_MIN_SEGMENTS}~{_MAX_SEGMENTS}(动词-名词,平台可选),"
|
||||
f"当前为 {segment_count} 段:{slug!r}"
|
||||
)
|
||||
(errors if strict else warnings).append(msg)
|
||||
return errors, warnings
|
||||
@@ -197,9 +202,6 @@ def validate_slug_semantics(
|
||||
|
||||
form = classify_slug_form(segments, slug=slug)
|
||||
if form == "scope":
|
||||
if segments[-1] not in scopes:
|
||||
msg = f"slug 末段应为 scope 白名单中的词:{segments[-1]!r}(slug={slug!r})"
|
||||
(errors if strict else warnings).append(msg)
|
||||
noun_count = segment_count - 2
|
||||
elif form == "standard":
|
||||
platform_match = _match_platform_suffix(segments, platforms)
|
||||
@@ -210,13 +212,17 @@ def validate_slug_semantics(
|
||||
else:
|
||||
_platform_name, platform_part_count = platform_match
|
||||
noun_count = segment_count - 1 - platform_part_count
|
||||
elif form == "plain":
|
||||
noun_count = segment_count - 1
|
||||
if segments[-1] == _DEPRECATED_PLATFORM_PLACEHOLDER:
|
||||
warnings.append(
|
||||
"slug 末段 default 已不再作为平台占位;没有外部平台时直接省略。"
|
||||
f"已发布的技能不用改名:{slug!r}"
|
||||
)
|
||||
else:
|
||||
if segment_count >= _MIN_SEGMENTS:
|
||||
if segments[-1] not in scopes:
|
||||
platform_match = _match_platform_suffix(segments, platforms)
|
||||
if platform_match is None:
|
||||
msg = f"slug 末段应匹配平台或 scope 白名单:{slug!r}"
|
||||
(errors if strict else warnings).append(msg)
|
||||
if segments and segments[-1] in scopes and segment_count < 3:
|
||||
msg = f"scope 型 slug 至少为动词-名词-scope:{slug!r}"
|
||||
(errors if strict else warnings).append(msg)
|
||||
noun_count = 0
|
||||
|
||||
if noun_count > _MAX_NOUN_SEGMENTS:
|
||||
|
||||
Reference in New Issue
Block a user