name: Update marketplace index on: push: branches: [main] paths: - 'skills/**' - '.github/workflows/update-index.yml' workflow_dispatch: jobs: update-index: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Regenerate index.json run: | python3 << 'EOF' import os, json, re from datetime import datetime, timezone skills_dir = "skills" skills = [] for skill_name in sorted(os.listdir(skills_dir)): skill_md = os.path.join(skills_dir, skill_name, "SKILL.md") if not os.path.isfile(skill_md): continue with open(skill_md, "r", encoding="utf-8") as f: content = f.read() fm_match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL) description = "" if fm_match: fm = fm_match.group(1) dm = re.search(r"^description:[ \t]*(.*)$", fm, re.MULTILINE) if dm: first = dm.group(1).strip() if first[:1] in (">", "|"): # YAML block scalar: gather the following more-indented lines buf = [] for ln in fm[dm.end():].split("\n"): if ln.strip() == "": buf.append("") elif re.match(r"^[ \t]+\S", ln): buf.append(ln.strip()) else: break if first.startswith(">"): # folded: blank line = break, else join w/ space paras, cur = [], [] for b in buf: if b == "": if cur: paras.append(" ".join(cur)); cur = [] else: cur.append(b) if cur: paras.append(" ".join(cur)) description = " ".join(paras).strip() else: # literal description = " ".join(b for b in buf if b).strip() else: description = first.strip('"').strip("'") skills.append({ "name": skill_name, "description": description, "domain": "cybersecurity", "path": f"skills/{skill_name}" }) index = { "version": "1.1.0", "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), "repository": "https://github.com/mukul975/Anthropic-Cybersecurity-Skills", "domain": "cybersecurity", "total_skills": len(skills), "skills": skills } with open("index.json", "w", encoding="utf-8") as f: json.dump(index, f, separators=(',', ':')) print(f"Updated index.json: {len(skills)} skills") EOF - name: Sync skill count into README and marketplace run: | python3 << 'EOF' import os, re, json # Authoritative count: directories under skills/ that contain a SKILL.md # and are not .bak backups (matches index.json generation above). count = 0 for name in os.listdir("skills"): if name.endswith(".bak"): continue if os.path.isfile(os.path.join("skills", name, "SKILL.md")): count += 1 print(f"Authoritative skill count: {count}") # README.md — replace the skills badge and every " ... skills" phrase. with open("README.md", encoding="utf-8") as f: readme = f.read() readme = re.sub(r"(badge/skills-)\d+", rf"\g<1>{count}", readme) # "817 production-grade", "817 structured", "817 skills", "all 817 skills", # "Scans 817 skill", "contains **817 skills**", BibTeX "{817 structured" readme = re.sub(r"\b\d+(?=\s+production-grade cybersecurity skills)", str(count), readme) readme = re.sub(r"\b\d+(?=\s+structured cybersecurity skills)", str(count), readme) readme = re.sub(r"(all\s+)\d+(?=\s+skills)", rf"\g<1>{count}", readme) readme = re.sub(r"(Scans\s+)\d+(?=\s+skill\b)", rf"\g<1>{count}", readme) readme = re.sub(r"(contains\s+\*\*)\d+(?=\s+skills\*\*)", rf"\g<1>{count}", readme) readme = re.sub(r"(\{)\d+(?=\s+structured cybersecurity skills)", rf"\g<1>{count}", readme) with open("README.md", "w", encoding="utf-8") as f: f.write(readme) # marketplace.json + plugin.json — patch " cybersecurity skills" in descriptions. for path in (".claude-plugin/marketplace.json", ".claude-plugin/plugin.json"): with open(path, encoding="utf-8") as f: data = f.read() data = re.sub(r"\b\d+(?=\s+cybersecurity skills)", str(count), data) json.loads(data) # fail loudly if the regex broke JSON with open(path, "w", encoding="utf-8") as f: f.write(data) print("Synced skill count into README.md, marketplace.json, plugin.json") EOF - name: Commit updated index and skill count run: | git config user.name "mukul975" git config user.email "mukuljangra5@gmail.com" git add index.json README.md .claude-plugin/marketplace.json .claude-plugin/plugin.json git diff --staged --quiet || git commit -m "chore: auto-update index.json and skill count" git push