Release v1.0.108: precipitate user-facing copy contract
All checks were successful
技能自动化发布 / release (push) Successful in 8s
All checks were successful
技能自动化发布 / release (push) Successful in 8s
This commit is contained in:
@@ -522,6 +522,59 @@ class TestActionsManifest(unittest.TestCase):
|
||||
}
|
||||
jsonschema.validate(instance=manifest, schema=schema)
|
||||
|
||||
def test_action_examples_user_facing_copy_avoids_jargon(self) -> None:
|
||||
"""示例 Action 的用户可见字符串不得含常见开发黑话(属性名本身除外)。"""
|
||||
examples_dir = os.path.join(get_skill_root(), "assets", "examples")
|
||||
# 故意拆开,避免本测试源码触发自身扫描。
|
||||
forbidden = (
|
||||
"pickCount",
|
||||
"itemIds",
|
||||
"status=",
|
||||
"import-urls",
|
||||
"download-enqueue",
|
||||
"bind.selectionMode",
|
||||
"selectionMode=",
|
||||
)
|
||||
# async/pending 作为整词出现在 description 才禁止;executionProfile 值除外。
|
||||
word_forbidden = re.compile(r"\b(async|pending|sync)\b", re.I)
|
||||
|
||||
for name in os.listdir(examples_dir):
|
||||
if not name.endswith(".action.example.json"):
|
||||
continue
|
||||
path = os.path.join(examples_dir, name)
|
||||
with open(path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
actions = data["actions"] if isinstance(data, dict) and "actions" in data else [data]
|
||||
for action in actions:
|
||||
if not isinstance(action, dict):
|
||||
continue
|
||||
texts: list[str] = []
|
||||
for key in ("description",):
|
||||
if action.get(key):
|
||||
texts.append(str(action[key]))
|
||||
conf = action.get("confirmation") or {}
|
||||
if isinstance(conf, dict) and conf.get("message"):
|
||||
texts.append(str(conf["message"]))
|
||||
props = ((action.get("inputSchema") or {}).get("properties")) or {}
|
||||
for prop in props.values():
|
||||
if not isinstance(prop, dict):
|
||||
continue
|
||||
for key in ("title", "description"):
|
||||
if prop.get(key):
|
||||
texts.append(str(prop[key]))
|
||||
blob = "\n".join(texts)
|
||||
for token in forbidden:
|
||||
self.assertNotIn(
|
||||
token,
|
||||
blob,
|
||||
msg=f"{name} user-facing copy must not contain {token!r}",
|
||||
)
|
||||
match = word_forbidden.search(blob)
|
||||
if match is not None:
|
||||
self.fail(
|
||||
f"{name} user-facing copy must not contain {match.group(0)!r}"
|
||||
)
|
||||
|
||||
def test_no_execution_profile_placement_coupling_in_tests(self) -> None:
|
||||
"""守护:本文件不得引入入口位置与 sync/async 的错误硬耦合断言。"""
|
||||
path = os.path.join(get_skill_root(), "tests", "test_actions_manifest.py")
|
||||
@@ -686,6 +739,8 @@ class TestActionsManifest(unittest.TestCase):
|
||||
"labelColumn",
|
||||
"selectionMode",
|
||||
"勾选驱动",
|
||||
"用户可见文案",
|
||||
"双受众",
|
||||
"已选择",
|
||||
"revealInForm",
|
||||
"映射只读",
|
||||
|
||||
@@ -423,10 +423,16 @@ class TestDocsStandards(unittest.TestCase):
|
||||
self.assertIn("revealInForm", checklist)
|
||||
self.assertIn("A4-9", checklist)
|
||||
self.assertIn("selectionMode", checklist)
|
||||
self.assertIn("A4-10", checklist)
|
||||
self.assertIn("用户可见文案", checklist)
|
||||
runtime = self._read("development/SKILL_ACTION_RUNTIME.md")
|
||||
self.assertIn("visibleWhen", runtime)
|
||||
self.assertIn("revealInForm", runtime)
|
||||
self.assertIn("selectionMode", runtime)
|
||||
self.assertIn("用户可见文案", runtime)
|
||||
actions = self._read("references/ACTIONS.md")
|
||||
self.assertIn("用户可见文案", actions)
|
||||
self.assertIn("双受众", actions)
|
||||
|
||||
def test_guarded_docs_do_not_reference_amazon_implementation(self) -> None:
|
||||
forbidden = (
|
||||
|
||||
Reference in New Issue
Block a user