#!/usr/bin/env python3 import argparse import io import json import os import re import sys import urllib.error import urllib.request from datetime import datetime, timezone GITHUB_REPO = "sickn33/antigravity-awesome-skills" SYNC_COMMENT_RE = re.compile(r"") def configure_utf8_output() -> None: """Best-effort UTF-8 stdout/stderr on Windows without dropping diagnostics.""" if sys.platform != "win32": return for stream_name in ("stdout", "stderr"): stream = getattr(sys, stream_name) try: stream.reconfigure(encoding="utf-8", errors="backslashreplace") continue except Exception: pass buffer = getattr(stream, "buffer", None) if buffer is not None: setattr( sys, stream_name, io.TextIOWrapper(buffer, encoding="utf-8", errors="backslashreplace"), ) def find_repo_root(start_path: str) -> str: current = os.path.abspath(start_path) while True: if os.path.isfile(os.path.join(current, "package.json")) and os.path.isfile( os.path.join(current, "README.md") ): return current parent = os.path.dirname(current) if parent == current: raise FileNotFoundError("Could not locate repository root from script path.") current = parent def format_skill_count(total_skills: int) -> str: return f"{total_skills:,}+" def format_star_badge_count(stars: int) -> str: if stars >= 1000: rounded = int(round(stars / 1000.0)) return f"{rounded}%2C000%2B" return f"{stars}%2B" def format_star_milestone(stars: int) -> str: if stars >= 1000: rounded = int(round(stars / 1000.0)) return f"{rounded},000+" return f"{stars}+" def format_star_celebration(stars: int) -> str: if stars >= 1000: rounded = int(round(stars / 1000.0)) return f"{rounded}k" return str(stars) def fetch_star_count(repo: str) -> int | None: url = f"https://api.github.com/repos/{repo}" request = urllib.request.Request( url, headers={ "Accept": "application/vnd.github+json", "User-Agent": "antigravity-awesome-skills-readme-sync", }, ) try: with urllib.request.urlopen(request, timeout=10) as response: payload = json.load(response) except (urllib.error.URLError, TimeoutError, json.JSONDecodeError): return None stars = payload.get("stargazers_count") return int(stars) if isinstance(stars, int) else None def load_metadata(base_dir: str, repo: str = GITHUB_REPO) -> dict: readme_path = os.path.join(base_dir, "README.md") package_path = os.path.join(base_dir, "package.json") index_path = os.path.join(base_dir, "skills_index.json") with open(index_path, "r", encoding="utf-8") as file: skills = json.load(file) with open(package_path, "r", encoding="utf-8") as file: package = json.load(file) with open(readme_path, "r", encoding="utf-8") as file: current_readme = file.read() current_star_match = re.search(r"โญ%20([\d%2C\+]+)%20Stars", current_readme) current_stars = None if current_star_match: compact = current_star_match.group(1).replace("%2C", "").replace("%2B", "") compact = compact.rstrip("+") if compact.isdigit(): current_stars = int(compact) live_stars = fetch_star_count(repo) total_stars = live_stars if live_stars is not None else current_stars or 0 return { "repo": repo, "version": str(package.get("version", "0.0.0")), "total_skills": len(skills), "total_skills_label": format_skill_count(len(skills)), "stars": total_stars, "star_badge_count": format_star_badge_count(total_stars), "star_milestone": format_star_milestone(total_stars), "star_celebration": format_star_celebration(total_stars), "updated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat(), "used_live_star_count": live_stars is not None, } def apply_metadata(content: str, metadata: dict) -> str: total_skills = metadata["total_skills"] total_skills_label = metadata["total_skills_label"] version = metadata["version"] star_badge_count = metadata["star_badge_count"] star_milestone = metadata["star_milestone"] star_celebration = metadata["star_celebration"] sync_comment = ( f"" ) content = re.sub( r"^# ๐ŸŒŒ Antigravity Awesome Skills: .*?$", ( f"# ๐ŸŒŒ Antigravity Awesome Skills: {total_skills_label} " "Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More" ), content, count=1, flags=re.MULTILINE, ) content = re.sub( r"^> \*\*The Ultimate Collection of .*?\*\*$", ( f"> **The Ultimate Collection of {total_skills_label} Universal Agentic " "Skills for AI Coding Assistants โ€” Claude Code, Gemini CLI, Codex CLI, " "Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**" ), content, count=1, flags=re.MULTILINE, ) content = re.sub( r"https://img\.shields\.io/badge/โญ%20[\d%2C\+]+%20Stars-gold\?style=for-the-badge", f"https://img.shields.io/badge/โญ%20{star_badge_count}%20Stars-gold?style=for-the-badge", content, count=1, ) content = re.sub( r"^\*\*Antigravity Awesome Skills\*\* is a curated, battle-tested library of \*\*.*?\*\* designed", ( f"**Antigravity Awesome Skills** is a curated, battle-tested library of " f"**{total_skills_label} high-performance agentic skills** designed" ), content, count=1, flags=re.MULTILINE, ) content = re.sub( r"\[๐Ÿ“š Browse \d[\d,]*\+ Skills\]\(#browse-[^)]+\)", f"[๐Ÿ“š Browse {total_skills_label} Skills](#browse-{total_skills}-skills)", content, count=1, ) content = re.sub( r"\*\*Welcome to the V[\d.]+ .*? Stars Celebration Release!\*\*", f"**Welcome to the V{version} {star_celebration} Stars Celebration Release!**", content, count=1, ) content = re.sub( r"> \*\*๐ŸŒŸ .*? GitHub Stars Milestone!\*\*", f"> **๐ŸŒŸ {star_milestone} GitHub Stars Milestone!**", content, count=1, ) content = re.sub( r"\*\*Antigravity Awesome Skills\*\* \(Release [\d.]+\) is a massive upgrade to your AI's capabilities, now featuring \*\*.*?\*\* skills", ( f"**Antigravity Awesome Skills** (Release {version}) is a massive upgrade " f"to your AI's capabilities, now featuring **{total_skills_label} skills**" ), content, count=1, ) content = re.sub( r"## Browse \d[\d,]*\+ Skills", f"## Browse {total_skills_label} Skills", content, count=1, ) content = re.sub( r"\n?", "", content, count=1, ) return f"{sync_comment}\n{content.lstrip()}" def update_readme(dry_run: bool = False) -> dict: base_dir = find_repo_root(os.path.dirname(__file__)) readme_path = os.path.join(base_dir, "README.md") metadata = load_metadata(base_dir) print(f"๐Ÿ“– Reading README from: {readme_path}") print(f"๐Ÿ”ข Total skills found: {metadata['total_skills']}") print(f"๐Ÿท๏ธ Version found: {metadata['version']}") if metadata["used_live_star_count"]: print(f"โญ Live GitHub stars found: {metadata['stars']}") else: print(f"โญ Using existing README star count: {metadata['stars']}") with open(readme_path, "r", encoding="utf-8") as file: content = file.read() updated_content = apply_metadata(content, metadata) if dry_run: print("๐Ÿงช Dry run enabled; README.md not written.") return metadata with open(readme_path, "w", encoding="utf-8", newline="\n") as file: file.write(updated_content) print("โœ… README.md updated successfully.") return metadata def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Sync generated metadata into README.md.") parser.add_argument("--dry-run", action="store_true", help="Compute metadata without writing files.") return parser.parse_args() if __name__ == "__main__": configure_utf8_output() args = parse_args() update_readme(dry_run=args.dry_run)