Files
better-claude-config/scripts/build_icons.py
T
AJ Avezzano dd7557ea62
Build & Release / Build (Linux) (push) Failing after 2m56s
Build & Release / Build (macOS) (push) Successful in 4m24s
Build & Release / Build (Windows) (push) Has been cancelled
Build & Release / Publish Release (push) Has been cancelled
Add cross-platform packaging, icons, and Claude Code config discovery
- Auto-discovers Claude Code (~/.claude/settings.json) alongside Claude Desktop
- Generated icons/app.icns (macOS) and icons/app.ico (Windows) from rounded PNGs
- bcc.spec: PyInstaller spec for all platforms (.app on macOS, onefile on Windows/Linux)
- .github/workflows/release.yml: builds and publishes GitHub Release on version tags
- scripts/build_icons.py: regenerates icon files from source PNGs
- requirements-dev.txt: adds pyinstaller and pillow for building
- CLAUDE.md: initial repo guidance for Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:01:30 -04:00

94 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
Generate icons/app.ico (Windows) and icons/app.icns (macOS) from the
rounded PNG source files in icons/twin-gears/rounded/.
Run from the repo root:
python scripts/build_icons.py
Requirements:
pip install pillow # for .ico
iconutil # built into macOS; for .icns
"""
from __future__ import annotations
import os
import platform
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
ROOT = Path(__file__).parent.parent
SRC = ROOT / "icons" / "twin-gears" / "rounded"
OUT = ROOT / "icons"
def build_ico():
try:
from PIL import Image
except ImportError:
print("Pillow not installed — skipping .ico generation (pip install pillow)")
return
sizes = [16, 32, 48, 64, 128, 256]
imgs = []
for s in sizes:
p = SRC / f"icon-{s}.png"
if not p.exists():
print(f" Missing {p.name}, skipping")
continue
imgs.append(Image.open(p).convert("RGBA"))
if not imgs:
print(" No source PNGs found — cannot build .ico")
return
dest = OUT / "app.ico"
imgs[-1].save(dest, format="ICO", append_images=imgs[:-1])
print(f" Generated {dest.relative_to(ROOT)} ({dest.stat().st_size // 1024 + 1} KB)")
def build_icns():
if shutil.which("iconutil") is None:
print(" iconutil not found (macOS-only) — skipping .icns generation")
return
iconset = Path(tempfile.mkdtemp()) / "app.iconset"
iconset.mkdir()
mapping = {
"icon_16x16.png": "icon-16.png",
"icon_16x16@2x.png": "icon-32.png",
"icon_32x32.png": "icon-32.png",
"icon_32x32@2x.png": "icon-64.png",
"icon_128x128.png": "icon-128.png",
"icon_128x128@2x.png": "icon-256.png",
"icon_256x256.png": "icon-256.png",
"icon_256x256@2x.png": "icon-512.png",
"icon_512x512.png": "icon-512.png",
"icon_512x512@2x.png": "icon-1024.png",
}
for dst_name, src_name in mapping.items():
src = SRC / src_name
if src.exists():
shutil.copy2(src, iconset / dst_name)
else:
print(f" Missing {src_name}, skipping {dst_name}")
dest = OUT / "app.icns"
subprocess.run(
["iconutil", "-c", "icns", str(iconset), "-o", str(dest)],
check=True,
)
shutil.rmtree(iconset.parent)
print(f" Generated {dest.relative_to(ROOT)} ({dest.stat().st_size // 1024} KB)")
if __name__ == "__main__":
print("Building icons/app.ico ...")
build_ico()
print("Building icons/app.icns ...")
build_icns()
print("Done.")