From f9da7957cf23ae8856ff39fb3abe01d254ba263f Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 5 Nov 2026 08:37:59 -0600 Subject: [PATCH] Add Claude listing icon matching Codex colors --- .claude-plugin/icon.png | Bin 0 -> 24536 bytes scripts/check_package.py | 9 +++++++-- scripts/test_check_package.py | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .claude-plugin/icon.png diff --git a/.claude-plugin/icon.png b/.claude-plugin/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9c35c6328fe97c198522e24cc0db92c5529987 GIT binary patch literal 24536 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 None: if relative not in PACKAGE_FILES: raise ValueError(f"unexpected package file: {relative}") found_files.add(relative) + if relative == ".claude-plugin/icon.png": + if not path.read_bytes().startswith(b"\x89PNG\r\n\x1a\n"): + raise ValueError("listing icon must be a PNG") + continue if CREDENTIAL_ASSIGNMENT.search(path.read_text(encoding="utf-8")): raise ValueError(f"possible credential assignment in package file: {relative}") else: @@ -104,8 +109,8 @@ def check_package() -> None: manifest_dir = ROOT / ".claude-plugin" if manifest_dir.is_symlink() or not manifest_dir.is_dir(): raise ValueError(".claude-plugin must be a directory") - if {path.name for path in manifest_dir.iterdir()} != {"plugin.json"}: - raise ValueError(".claude-plugin must contain only plugin.json") + if {path.name for path in manifest_dir.iterdir()} != {"plugin.json", "icon.png"}: + raise ValueError(".claude-plugin must contain only plugin.json and icon.png") skills_dir = ROOT / "skills" if skills_dir.is_symlink() or not skills_dir.is_dir(): diff --git a/scripts/test_check_package.py b/scripts/test_check_package.py index ceee56a..d992338 100644 --- a/scripts/test_check_package.py +++ b/scripts/test_check_package.py @@ -31,6 +31,14 @@ def check_staged_package(self) -> None: with patch.object(check_package, "ROOT", self.root): check_package.check_package() + def test_binary_listing_icon_is_accepted(self) -> None: + self.check_staged_package() + + def test_non_png_listing_icon_is_rejected(self) -> None: + (self.root / ".claude-plugin/icon.png").write_text("not a PNG") + with self.assertRaisesRegex(ValueError, "listing icon must be a PNG"): + self.check_staged_package() + def set_version(self, version: str) -> None: manifest_path = self.root / ".claude-plugin/plugin.json" manifest = json.loads(manifest_path.read_text(encoding="utf-8"))