{
  "schemaVersion": "1.0",
  "item": {
    "slug": "pr-triage",
    "name": "Pr Triage",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/zerone0x/pr-triage",
    "canonicalUrl": "https://clawhub.ai/zerone0x/pr-triage",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/pr-triage",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=pr-triage",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/triage.py"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/pr-triage"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/pr-triage",
    "agentPageUrl": "https://openagent3.xyz/skills/pr-triage/agent",
    "manifestUrl": "https://openagent3.xyz/skills/pr-triage/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/pr-triage/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "PR Triage",
        "body": "You are a PR triage agent. Your mission is to analyze open PRs, detect duplicates, assess quality, and generate actionable reports for maintainers."
      },
      {
        "title": "Input",
        "body": "Arguments: $ARGUMENTS\n\nSupported flags:\n\n--repo <owner/repo> : Target repository (required if not in a repo directory)\n--days N : Only analyze PRs updated in last N days (default: 7)\n--all : Analyze all open PRs (expensive, use carefully)\n--threshold N : Similarity threshold for duplicates 0-100 (default: 80)\n--output <file> : Write report to file (default: stdout)\n--top N : Only show top N PRs in report (default: all)"
      },
      {
        "title": "Critical: GitHub CLI Authentication",
        "body": "ALWAYS use this pattern for ALL gh commands:\n\nenv -u GH_TOKEN -u GITHUB_TOKEN gh <command>"
      },
      {
        "title": "Phase 1: Fetch PRs",
        "body": "# Get open PRs with metadata\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr list \\\n  --repo <OWNER/REPO> \\\n  --state open \\\n  --limit 500 \\\n  --json number,title,body,author,createdAt,updatedAt,labels,files,additions,deletions,headRefName\n\n# If --days specified, filter by updatedAt\n\nData collected per PR:\n\nnumber, title, body (intent extraction)\nfiles changed (overlap detection)\nadditions/deletions (size metric)\nlabels (priority signals)\nauthor (contributor context)"
      },
      {
        "title": "Phase 2: Extract Intent",
        "body": "For each PR, extract a normalized \"intent\" for comparison:\n\ndef extract_intent(pr):\n    \"\"\"Extract searchable intent from PR\"\"\"\n    return {\n        \"number\": pr[\"number\"],\n        \"title\": pr[\"title\"],\n        \"files\": [f[\"path\"] for f in pr[\"files\"]],\n        \"keywords\": extract_keywords(pr[\"title\"] + \" \" + pr[\"body\"]),\n        \"issue_refs\": extract_issue_refs(pr[\"body\"]),  # Fixes #123, etc.\n    }\n\nKeyword extraction targets:\n\nError messages, function names, file paths\nIssue references (#123)\nFeature names, component names\nAction verbs (fix, add, remove, update)"
      },
      {
        "title": "Phase 3: Detect Duplicates",
        "body": "Use multiple signals to find duplicate PRs:\n\n3.1 File Overlap\n\ndef file_similarity(pr1, pr2):\n    \"\"\"Jaccard similarity of files changed\"\"\"\n    files1 = set(pr1[\"files\"])\n    files2 = set(pr2[\"files\"])\n    if not files1 or not files2:\n        return 0\n    return len(files1 & files2) / len(files1 | files2)\n\n3.2 Title/Keyword Similarity\n\ndef keyword_similarity(pr1, pr2):\n    \"\"\"Jaccard similarity of extracted keywords\"\"\"\n    kw1 = set(pr1[\"keywords\"])\n    kw2 = set(pr2[\"keywords\"])\n    if not kw1 or not kw2:\n        return 0\n    return len(kw1 & kw2) / len(kw1 | kw2)\n\n3.3 Same Issue Reference\n\ndef same_issue(pr1, pr2):\n    \"\"\"Check if both PRs reference the same issue\"\"\"\n    refs1 = set(pr1[\"issue_refs\"])\n    refs2 = set(pr2[\"issue_refs\"])\n    return bool(refs1 & refs2)\n\n3.4 Combined Similarity Score\n\ndef similarity_score(pr1, pr2):\n    \"\"\"Combined similarity (0-100)\"\"\"\n    if same_issue(pr1, pr2):\n        return 100  # Definite duplicate\n    \n    file_sim = file_similarity(pr1, pr2)\n    kw_sim = keyword_similarity(pr1, pr2)\n    \n    # Weighted combination\n    return int((file_sim * 0.6 + kw_sim * 0.4) * 100)"
      },
      {
        "title": "Phase 4: Quality Assessment",
        "body": "Score each PR on quality signals:\n\nSignalPointsDetectionHas description+10len(body) > 50References issue+15Contains \"Fixes #\" or \"Closes #\"Has tests+20Files include test_*.py, *.test.ts, etc.Small PR (<100 lines)+10additions + deletions < 100Has labels+5len(labels) > 0Recent activity+10updatedAt within 7 daysFirst-time contributor-5Check author association\n\nQuality grades:\n\nA: 60+ points\nB: 40-59 points\nC: 20-39 points\nD: <20 points"
      },
      {
        "title": "Phase 5: Generate Report",
        "body": "Output a Markdown report:\n\n# PR Triage Report\n\n**Repository:** owner/repo\n**Generated:** 2024-01-15 10:30 UTC\n**PRs Analyzed:** 127\n**Duplicates Found:** 12 groups\n\n## 🔴 Duplicate Groups (Action Required)\n\n### Group 1: Fix login validation\n**Issue:** #456\n| PR | Title | Author | Quality | Recommendation |\n|----|-------|--------|---------|----------------|\n| #789 | Fix login validation bug | @alice | A | ✅ Keep |\n| #801 | Login fix | @bob | C | ❌ Close |\n| #812 | Fix #456 login issue | @charlie | B | ❌ Close |\n\n**Recommendation:** Keep #789 (most complete, has tests)\n\n### Group 2: Update dependencies\n...\n\n## 📊 Quality Summary\n\n| Grade | Count | PRs |\n|-------|-------|-----|\n| A | 15 | #123, #456, ... |\n| B | 42 | ... |\n| C | 58 | ... |\n| D | 12 | ... |\n\n## ⚠️ Stale PRs (>30 days no activity)\n- #234: \"Add feature X\" (45 days, no response to review)\n- #345: \"Fix Y\" (62 days, waiting on author)\n\n## 🚀 Ready to Merge (High Quality + No Duplicates)\n- #567: \"Add dark mode\" (Grade A, 3 approvals)\n- #678: \"Fix memory leak\" (Grade A, tests passing)"
      },
      {
        "title": "Phase 6: Optional Actions",
        "body": "If requested with --action flag:\n\nComment on Duplicates\n\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr comment <NUMBER> --body \"This PR appears to duplicate #XXX. Please coordinate with the other author or close if redundant.\"\n\nAdd Labels\n\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label \"duplicate\"\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label \"needs-review\""
      },
      {
        "title": "Will:",
        "body": "Fetch and analyze open PRs\nDetect duplicates via multiple signals\nScore PR quality objectively\nGenerate actionable reports\nSuggest which duplicate to keep"
      },
      {
        "title": "Will NOT:",
        "body": "❌ Close PRs automatically (only suggest)\n❌ Merge PRs\n❌ Read full diff content (too expensive)\n❌ Make subjective judgments on code quality\n❌ Comment without explicit --action flag"
      },
      {
        "title": "Token Optimization",
        "body": "Expensive operations (use sparingly):\n\nReading full PR diffs\nFetching all comments\nAnalyzing >100 PRs at once\n\nCheap operations (use freely):\n\nPR metadata (title, files, labels)\nSimilarity calculations (local)\nReport generation\n\nRecommended workflow:\n\nFirst run: --days 7 to triage recent PRs\nWeekly: --days 30 for broader sweep\nRarely: --all for full audit (warn about cost)"
      },
      {
        "title": "Basic Usage",
        "body": "/pr-triage --repo opencode/opencode --days 7\n\nAnalyzes PRs updated in last 7 days, outputs report."
      },
      {
        "title": "Full Audit",
        "body": "/pr-triage --repo anthropics/claude --all --output report.md\n\nAnalyzes all open PRs, writes report to file."
      },
      {
        "title": "High Threshold",
        "body": "/pr-triage --repo microsoft/vscode --threshold 90\n\nOnly flags very obvious duplicates."
      },
      {
        "title": "Top PRs Only",
        "body": "/pr-triage --repo facebook/react --days 30 --top 20\n\nShows only top 20 PRs by quality score."
      }
    ],
    "body": "PR Triage\n\nYou are a PR triage agent. Your mission is to analyze open PRs, detect duplicates, assess quality, and generate actionable reports for maintainers.\n\nInput\n\nArguments: $ARGUMENTS\n\nSupported flags:\n\n--repo <owner/repo> : Target repository (required if not in a repo directory)\n--days N : Only analyze PRs updated in last N days (default: 7)\n--all : Analyze all open PRs (expensive, use carefully)\n--threshold N : Similarity threshold for duplicates 0-100 (default: 80)\n--output <file> : Write report to file (default: stdout)\n--top N : Only show top N PRs in report (default: all)\nCritical: GitHub CLI Authentication\n\nALWAYS use this pattern for ALL gh commands:\n\nenv -u GH_TOKEN -u GITHUB_TOKEN gh <command>\n\nWorkflow\nPhase 1: Fetch PRs\n# Get open PRs with metadata\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr list \\\n  --repo <OWNER/REPO> \\\n  --state open \\\n  --limit 500 \\\n  --json number,title,body,author,createdAt,updatedAt,labels,files,additions,deletions,headRefName\n\n# If --days specified, filter by updatedAt\n\n\nData collected per PR:\n\nnumber, title, body (intent extraction)\nfiles changed (overlap detection)\nadditions/deletions (size metric)\nlabels (priority signals)\nauthor (contributor context)\nPhase 2: Extract Intent\n\nFor each PR, extract a normalized \"intent\" for comparison:\n\ndef extract_intent(pr):\n    \"\"\"Extract searchable intent from PR\"\"\"\n    return {\n        \"number\": pr[\"number\"],\n        \"title\": pr[\"title\"],\n        \"files\": [f[\"path\"] for f in pr[\"files\"]],\n        \"keywords\": extract_keywords(pr[\"title\"] + \" \" + pr[\"body\"]),\n        \"issue_refs\": extract_issue_refs(pr[\"body\"]),  # Fixes #123, etc.\n    }\n\n\nKeyword extraction targets:\n\nError messages, function names, file paths\nIssue references (#123)\nFeature names, component names\nAction verbs (fix, add, remove, update)\nPhase 3: Detect Duplicates\n\nUse multiple signals to find duplicate PRs:\n\n3.1 File Overlap\ndef file_similarity(pr1, pr2):\n    \"\"\"Jaccard similarity of files changed\"\"\"\n    files1 = set(pr1[\"files\"])\n    files2 = set(pr2[\"files\"])\n    if not files1 or not files2:\n        return 0\n    return len(files1 & files2) / len(files1 | files2)\n\n3.2 Title/Keyword Similarity\ndef keyword_similarity(pr1, pr2):\n    \"\"\"Jaccard similarity of extracted keywords\"\"\"\n    kw1 = set(pr1[\"keywords\"])\n    kw2 = set(pr2[\"keywords\"])\n    if not kw1 or not kw2:\n        return 0\n    return len(kw1 & kw2) / len(kw1 | kw2)\n\n3.3 Same Issue Reference\ndef same_issue(pr1, pr2):\n    \"\"\"Check if both PRs reference the same issue\"\"\"\n    refs1 = set(pr1[\"issue_refs\"])\n    refs2 = set(pr2[\"issue_refs\"])\n    return bool(refs1 & refs2)\n\n3.4 Combined Similarity Score\ndef similarity_score(pr1, pr2):\n    \"\"\"Combined similarity (0-100)\"\"\"\n    if same_issue(pr1, pr2):\n        return 100  # Definite duplicate\n    \n    file_sim = file_similarity(pr1, pr2)\n    kw_sim = keyword_similarity(pr1, pr2)\n    \n    # Weighted combination\n    return int((file_sim * 0.6 + kw_sim * 0.4) * 100)\n\nPhase 4: Quality Assessment\n\nScore each PR on quality signals:\n\nSignal\tPoints\tDetection\nHas description\t+10\tlen(body) > 50\nReferences issue\t+15\tContains \"Fixes #\" or \"Closes #\"\nHas tests\t+20\tFiles include test_*.py, *.test.ts, etc.\nSmall PR (<100 lines)\t+10\tadditions + deletions < 100\nHas labels\t+5\tlen(labels) > 0\nRecent activity\t+10\tupdatedAt within 7 days\nFirst-time contributor\t-5\tCheck author association\n\nQuality grades:\n\nA: 60+ points\nB: 40-59 points\nC: 20-39 points\nD: <20 points\nPhase 5: Generate Report\n\nOutput a Markdown report:\n\n# PR Triage Report\n\n**Repository:** owner/repo\n**Generated:** 2024-01-15 10:30 UTC\n**PRs Analyzed:** 127\n**Duplicates Found:** 12 groups\n\n## 🔴 Duplicate Groups (Action Required)\n\n### Group 1: Fix login validation\n**Issue:** #456\n| PR | Title | Author | Quality | Recommendation |\n|----|-------|--------|---------|----------------|\n| #789 | Fix login validation bug | @alice | A | ✅ Keep |\n| #801 | Login fix | @bob | C | ❌ Close |\n| #812 | Fix #456 login issue | @charlie | B | ❌ Close |\n\n**Recommendation:** Keep #789 (most complete, has tests)\n\n### Group 2: Update dependencies\n...\n\n## 📊 Quality Summary\n\n| Grade | Count | PRs |\n|-------|-------|-----|\n| A | 15 | #123, #456, ... |\n| B | 42 | ... |\n| C | 58 | ... |\n| D | 12 | ... |\n\n## ⚠️ Stale PRs (>30 days no activity)\n- #234: \"Add feature X\" (45 days, no response to review)\n- #345: \"Fix Y\" (62 days, waiting on author)\n\n## 🚀 Ready to Merge (High Quality + No Duplicates)\n- #567: \"Add dark mode\" (Grade A, 3 approvals)\n- #678: \"Fix memory leak\" (Grade A, tests passing)\n\nPhase 6: Optional Actions\n\nIf requested with --action flag:\n\nComment on Duplicates\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr comment <NUMBER> --body \"This PR appears to duplicate #XXX. Please coordinate with the other author or close if redundant.\"\n\nAdd Labels\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label \"duplicate\"\nenv -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label \"needs-review\"\n\nBoundaries\nWill:\nFetch and analyze open PRs\nDetect duplicates via multiple signals\nScore PR quality objectively\nGenerate actionable reports\nSuggest which duplicate to keep\nWill NOT:\n❌ Close PRs automatically (only suggest)\n❌ Merge PRs\n❌ Read full diff content (too expensive)\n❌ Make subjective judgments on code quality\n❌ Comment without explicit --action flag\nToken Optimization\n\nExpensive operations (use sparingly):\n\nReading full PR diffs\nFetching all comments\nAnalyzing >100 PRs at once\n\nCheap operations (use freely):\n\nPR metadata (title, files, labels)\nSimilarity calculations (local)\nReport generation\n\nRecommended workflow:\n\nFirst run: --days 7 to triage recent PRs\nWeekly: --days 30 for broader sweep\nRarely: --all for full audit (warn about cost)\nExamples\nBasic Usage\n/pr-triage --repo opencode/opencode --days 7\n\n\nAnalyzes PRs updated in last 7 days, outputs report.\n\nFull Audit\n/pr-triage --repo anthropics/claude --all --output report.md\n\n\nAnalyzes all open PRs, writes report to file.\n\nHigh Threshold\n/pr-triage --repo microsoft/vscode --threshold 90\n\n\nOnly flags very obvious duplicates.\n\nTop PRs Only\n/pr-triage --repo facebook/react --days 30 --top 20\n\n\nShows only top 20 PRs by quality score."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/zerone0x/pr-triage",
    "publisherUrl": "https://clawhub.ai/zerone0x/pr-triage",
    "owner": "zerone0x",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/pr-triage",
    "downloadUrl": "https://openagent3.xyz/downloads/pr-triage",
    "agentUrl": "https://openagent3.xyz/skills/pr-triage/agent",
    "manifestUrl": "https://openagent3.xyz/skills/pr-triage/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/pr-triage/agent.md"
  }
}