[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KK6G4MH9DB4G2PXTZVAC3M":3,"skill-same:01M6KK6G4MH9DB4G2PXTZVAC3M":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M6KK6G4MH9DB4G2PXTZVAC3M","gh-pr-analysis",null,"How to fetch and analyze pull request data from a GitHub repository for a given time period: counts, merge rates, average time-to-merge, and top contributors. Use this skill whenever the user wants PR metrics, pull request summaries, contributor leaderboards, or community pulse reports.","cxcscmu\u002FSkillLearnBench","cxcscmu","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F142838272?v=4","01M6KCQDFQWPDSN0MKZY96MSQP","01M6KCQDM7G70TKJ28NTSQC0RZ",93,"MIT","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fb4-skill-creator-claude-sonnet-4-6\u002Fgithub-repo-analytics\u002Fgh-pr-analysis\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"pr","gh pr analysis","gh","gh pr","analysis","how","pull","analyze","pull request","fetch","pulse","use","reports","community","time","how to","top","for","summaries","github","2026-11-10 10:12:30",false,"---\nname: gh-pr-analysis\ndescription: >\n  How to fetch and analyze pull request data from a GitHub repository for a\n  given time period: counts, merge rates, average time-to-merge, and top\n  contributors. Use this skill whenever the user wants PR metrics, pull request\n  summaries, contributor leaderboards, or community pulse reports.\n---\n\n# PR Analysis via GitHub REST API\n\n## Fetching PRs created in a date window\n\nUse the `\u002Frepos\u002F{owner}\u002F{repo}\u002Fpulls` endpoint with `state=all` and `since`:\n\n```python\nBASE = \"https:\u002F\u002Fapi.github.com\u002Frepos\u002Fcli\u002Fcli\"\n\ndef get_prs(start_iso, end_iso, token=None):\n    \"\"\"Fetch all PRs created between start_iso and end_iso (ISO 8601 strings).\"\"\"\n    headers = {\"Accept\": \"application\u002Fvnd.github+json\"}\n    if token:\n        headers[\"Authorization\"] = f\"token {token}\"\n\n    start_dt = datetime.fromisoformat(start_iso.replace(\"Z\", \"+00:00\"))\n    end_dt   = datetime.fromisoformat(end_iso.replace(\"Z\", \"+00:00\"))\n\n    results, page = [], 1\n    while True:\n        r = requests.get(f\"{BASE}\u002Fpulls\",\n                         headers=headers,\n                         params={\"state\": \"all\", \"sort\": \"created\",\n                                 \"direction\": \"desc\", \"per_page\": 100,\n                                 \"page\": page})\n        data = r.json()\n        if not data:\n            break\n        # Trim pages that are entirely before our window (sorted desc)\n        page_items = []\n        stop = False\n        for pr in data:\n            created = datetime.fromisoformat(pr[\"created_at\"].replace(\"Z\", \"+00:00\"))\n            if created > end_dt:\n                continue        # too recent\n            if created \u003C start_dt:\n                stop = True     # gone past our window, no need to paginate further\n                break\n            page_items.append(pr)\n        results.extend(page_items)\n        if stop or len(data) \u003C 100:\n            break\n        page += 1\n    return results\n```\n\n## Key calculations\n\n### Merged vs closed-not-merged\n\n```python\nmerged = [p for p in prs if p.get(\"merged_at\")]\n# \"closed\" means closed without merge (GitHub convention in this report)\nclosed_not_merged = [p for p in prs if p[\"state\"] == \"closed\" and not p.get(\"merged_at\")]\n```\n\n### Average time-to-merge (days, 1 decimal)\n\n```python\ndef ttm(pr):\n    c = datetime.fromisoformat(pr[\"created_at\"].replace(\"Z\", \"+00:00\"))\n    m = datetime.fromisoformat(pr[\"merged_at\"].replace(\"Z\", \"+00:00\"))\n    return (m - c).total_seconds() \u002F 86400\n\navg_merge_days = round(sum(ttm(p) for p in merged) \u002F len(merged), 1) if merged else 0.0\n```\n\n### Top contributor\n\n```python\nfrom collections import Counter\ntop_contributor = Counter(p[\"user\"][\"login\"] for p in prs).most_common(1)[0][0]\n```\n\n## Gotchas\n\n- `merged_at` is only present on the `\u002Fpulls` endpoint response, NOT on the\n  `\u002Fissues` endpoint. Always use `\u002Fpulls?state=all` for PR data.\n- GitHub sorts by `created` desc by default; bail out once `created_at \u003C start`\n  to avoid reading thousands of old PRs.\n- Bots (e.g. `dependabot[bot]`, `github-actions[bot]`) appear as contributors;\n  decide whether to include\u002Fexclude them based on context.\n","# PR Analysis via GitHub REST API\n\n## Fetching PRs created in a date window\n\nUse the `\u002Frepos\u002F{owner}\u002F{repo}\u002Fpulls` endpoint with `state=all` and `since`:\n\n```python\nBASE = \"https:\u002F\u002Fapi.github.com\u002Frepos\u002Fcli\u002Fcli\"\n\ndef get_prs(start_iso, end_iso, token=None):\n    \"\"\"Fetch all PRs created between start_iso and end_iso (ISO 8601 strings).\"\"\"\n    headers = {\"Accept\": \"application\u002Fvnd.github+json\"}\n    if token:\n        headers[\"Authorization\"] = f\"token {token}\"\n\n    start_dt = datetime.fromisoformat(start_iso.replace(\"Z\", \"+00:00\"))\n    end_dt   = datetime.fromisoformat(end_iso.replace(\"Z\", \"+00:00\"))\n\n    results, page = [], 1\n    while True:\n        r = requests.get(f\"{BASE}\u002Fpulls\",\n                         headers=headers,\n                         params={\"state\": \"all\", \"sort\": \"created\",\n                                 \"direction\": \"desc\", \"per_page\": 100,\n                                 \"page\": page})\n        data = r.json()\n        if not data:\n            break\n        # Trim pages that are entirely before our window (sorted desc)\n        page_items = []\n        stop = False\n        for pr in data:\n            created = datetime.fromisoformat(pr[\"created_at\"].replace(\"Z\", \"+00:00\"))\n            if created > end_dt:\n                continue        # too recent\n            if created \u003C start_dt:\n                stop = True     # gone past our window, no need to paginate further\n                break\n            page_items.append(pr)\n        results.extend(page_items)\n        if stop or len(data) \u003C 100:\n            break\n        page += 1\n    return results\n```\n\n## Key calculations\n\n### Merged vs closed-not-merged\n\n```python\nmerged = [p for p in prs if p.get(\"merged_at\")]\n# \"closed\" means closed without merge (GitHub convention in this report)\nclosed_not_merged = [p for p in prs if p[\"state\"] == \"closed\" and not p.get(\"merged_at\")]\n```\n\n### Average time-to-merge (days, 1 decimal)\n\n```python\ndef ttm(pr):\n    c = datetime.fromisoformat(pr[\"created_at\"].replace(\"Z\", \"+00:00\"))\n    m = datetime.fromisoformat(pr[\"merged_at\"].replace(\"Z\", \"+00:00\"))\n    return (m - c).total_seconds() \u002F 86400\n\navg_merge_days = round(sum(ttm(p) for p in merged) \u002F len(merged), 1) if merged else 0.0\n```\n\n### Top contributor\n\n```python\nfrom collections import Counter\ntop_contributor = Counter(p[\"user\"][\"login\"] for p in prs).most_common(1)[0][0]\n```\n\n## Gotchas\n\n- `merged_at` is only present on the `\u002Fpulls` endpoint response, NOT on the\n  `\u002Fissues` endpoint. Always use `\u002Fpulls?state=all` for PR data.\n- GitHub sorts by `created` desc by default; bail out once `created_at \u003C start`\n  to avoid reading thousands of old PRs.\n- Bots (e.g. `dependabot[bot]`, `github-actions[bot]`) appear as contributors;\n  decide whether to include\u002Fexclude them based on context.\n",{"name":5,"description":7},"main","726e1f79b96b0cb3d729d0e55a1c847e0b5353ae","skills\u002Fb4-skill-creator-claude-sonnet-4-6\u002Fgithub-repo-analytics\u002Fgh-pr-analysis",8,"https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench","https:\u002F\u002Fcxcscmu.github.io\u002FSkillLearnBench","https:\u002F\u002Fgithub.com\u002Fcxcscmu","2026-10-02 22:55:36",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add cxcscmu\u002FSkillLearnBench --skill gh-pr-analysis",{"tool":57,"command":58},"bunx","bunx skills add cxcscmu\u002FSkillLearnBench --skill gh-pr-analysis",{"tool":60,"command":61},"pnpm","pnpm dlx skills add cxcscmu\u002FSkillLearnBench --skill gh-pr-analysis","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fb4-skill-creator-claude-sonnet-4-6\u002Fgithub-repo-analytics\u002Fgh-pr-analysis\u002FSKILL.md",true,[],[66,84,108,126,146,158],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":77,"publishedAt":38},"01M6KM5KH175P5ABP5JMX2SBDQ","object_counter","Count occurrences of an object in the image using computer vision algorithm.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Fvideo-object-counting\u002Fobject_counter\u002FSKILL.md",[72],{"categoryNo":73,"categoryName":74,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[78,79,80,81,82,83],"object counter","object","vision","computer","Computer Vision","image",{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":93,"publishedAt":38},"01M6KM51TMVXG79MMPCS6Y8G86","travel-planning-workflow","Invoke this skill when performing travel planning. It defines a structured workflow for generating itineraries. Following this workflow is essential to ensure the final plan satisfies user requirements.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftravel-planning\u002Ftravel-planning-workflow\u002FSKILL.md",[90],{"categoryNo":91,"categoryName":92,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000023","Skill与智能体开发",[94,95,96,97,98,99,100,101,102,35,103,104,105,106,107],"workflow","planning","planning workflow","travel","travel planning","travel planning workflow","structured","performing","plan","user","it","requirements","essential","itineraries",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":38},"01M6KM4DY820XHS9YTSK5QP5HD","bundled-dataset-search-tool","invoke this skill when you need to perform database search for travel planning. This skill provides some useful pre-packaged tools to look up accommodations, attractions, cities, driving distance, flights, and restaurants from the bundled dataset.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftravel-planning\u002Fbundled-dataset-search-tool\u002FSKILL.md",[],[115,116,117,118,119,120,121,97,122,123,98,124,35,125,95],"search","tool","dataset","bundled dataset search tool","restaurants","Tools","up","look","flights","you","database",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":38},"01M6KM465BB9PQ0B548HQSVAWZ","glm-output","Output-processing guidance for GLM tasks. Especially useful after glm-basics and glm-calibration when you need verifier-matching metrics from output.nc and a final \u002Froot\u002Fmetrics.json.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-output\u002FSKILL.md",[],[133,134,135,35,136,137,138,139,140,141,142,143,124,144,145],"glm output","output","glm","tasks","metrics","json","basics","guidance","matching","verifier","processing","root","calibration",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":38},"01M6KM40KY3QWDW5W97S39R2BC","glm-calibration","Calibration guidance for GLM tasks. Often most effective after glm-basics has clarified the setup; glm-output is the companion skill for exact final metric computation.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-calibration\u002FSKILL.md",[152],{"categoryNo":91,"categoryName":92,"taxonomyType":75,"taxonomyTypeDesc":76},[154,145,135,134,140,139,136,155,156,35,157],"glm calibration","setup","companion","metric",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":38},"01M6KM3VHHVSGMGHJQB3PPT6YG","glm-basics","A good starting point for GLM calibration tasks. Use to inspect glm3.nml, confirm how GLM runs, and identify the relevant files before moving on to calibration and output evaluation.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-basics\u002FSKILL.md",[],[165,135,139,166,154,145,35,134,167,168,169,29,23,170,136],"glm basics","inspect","relevant","files","good","Evaluation"]