diff --git a/tests/tools/test_skills_hub.py b/tests/tools/test_skills_hub.py index 24d1e87affcc..40ccbeb7e85f 100644 --- a/tests/tools/test_skills_hub.py +++ b/tests/tools/test_skills_hub.py @@ -695,6 +695,27 @@ def test_bundle_content_hash_matches_installed_content_hash(self, tmp_path): assert bundle_content_hash(bundle) == content_hash(skill_dir) + def test_bundle_content_hash_accepts_bytes_content(self, tmp_path): + from tools.skills_guard import content_hash + + bundle = SkillBundle( + name="demo-skill", + files={ + "SKILL.md": b"# Demo Skill\n", + "references/checklist.md": "- [ ] security\n", + }, + source="github", + identifier="owner/repo/demo-skill", + trust_level="community", + ) + skill_dir = tmp_path / "demo-skill" + skill_dir.mkdir() + (skill_dir / "SKILL.md").write_bytes(b"# Demo Skill\n") + (skill_dir / "references").mkdir() + (skill_dir / "references" / "checklist.md").write_text("- [ ] security\n") + + assert bundle_content_hash(bundle) == content_hash(skill_dir) + def test_reports_update_when_remote_hash_differs(self): lock = MagicMock() lock.list_installed.return_value = [{ diff --git a/tools/skills_hub.py b/tools/skills_hub.py index 47aef8075b7c..d91414160a86 100644 --- a/tools/skills_hub.py +++ b/tools/skills_hub.py @@ -2630,7 +2630,11 @@ def bundle_content_hash(bundle: SkillBundle) -> str: """Compute a deterministic hash for an in-memory skill bundle.""" h = hashlib.sha256() for rel_path in sorted(bundle.files): - h.update(bundle.files[rel_path].encode("utf-8")) + content = bundle.files[rel_path] + if isinstance(content, bytes): + h.update(content) + else: + h.update(content.encode("utf-8")) return f"sha256:{h.hexdigest()[:16]}"