agentleFS
TJaenichenTJaenichen/claude-code-harness/skills/user/merged-prs/SKILL.md

merged-prs

Skill0 starsChanged 3 months agoMITView on GitHub

Summarize PRs merged across all Azure DevOps projects within a time window. Default 24 hours; accepts overrides like `48h` or `7d`. Use when the user asks "what got merged" / "PRs from the last X hours/days" / "what shipped recently".

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Don't fetch PR descriptions/diffs by default — title + author is enough for the overview.

    line 75
  2. Very specific:

    If the user is on a feature branch and only cares about one repo, this skill is overkill — point them at git log --since=...

    line 78

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Merged PRs Summary

Summarize completed (merged) pull requests across the user's Azure DevOps server within a time window.

Arguments

$ARGUMENTS — optional time window. Examples: 24h, 48h, 7d, 3d. Defaults to 24h when empty.

Parse it as <number><unit> where unit is h (hours) or d (days). Convert days to hours (1d = 24h).

Azure DevOps server

  • Base URL: https://devops.example.com
  • Auth: Windows Integrated (curl --negotiate -u :)
  • Projects: discover at runtime via /DefaultCollection/_apis/projects?api-version=7.0. e.g. MyProject (primary) and Sandbox.

Steps

  1. Parse the window. Determine the cutoff datetime as now - <window>. If $ARGUMENTS is empty or unparseable, fall back to 24 hours.
  2. List projects.
    curl -s -L --negotiate -u : "https://devops.example.com/DefaultCollection/_apis/projects?api-version=7.0"
    Extract project name values from the JSON value array.
  3. Fetch completed PRs per project. For each project name:
    curl -s -L --negotiate -u : "https://devops.example.com/DefaultCollection/<ProjectName>/_apis/git/pullrequests?searchCriteria.status=completed&api-version=7.0&\$top=200"
    The API returns most-recent-first. If the oldest PR returned is still newer than the cutoff, increase $top and re-fetch (some windows like 7d will need 500+).
  4. Filter by closedDate — keep PRs where closedDate >= cutoff. Note: closedDate is ISO-8601 with fractional seconds and a Z suffix; parse robustly.
  5. Group by repository (p['repository']['name']). Within each repo, list PRs as PR <id> | <author display name> | <title>.
  6. Render the summary in this shape:
    • Lead line: total PR count across all projects + the window.
    • Sections by repo, sorted by PR count descending. Use tiered headers (Heavy / Moderate / Light / Singletons) when the spread justifies it; otherwise just one flat list.
    • Within each repo entry, group multiple PRs by the same author when natural ("Jane Doe refactoring (X, Y, Z)") rather than listing each as a bare bullet.
    • Skip projects with zero PRs in window, but mention them briefly ("Sandbox had none") so the user knows they were checked.
    • End with a short Themes paragraph: cross-cutting patterns (e.g. "solution-structure cleanup dominates", "the BI team is mid-migration to a new scheduler"), or "No obvious cross-repo incident" if nothing stands out.

Python one-liner for filtering/grouping

The data is easier to handle in Python than jq on Windows. Pattern that works:

curl -s ... | python -c "
import sys, json
from datetime import datetime, timedelta, timezone
from collections import defaultdict
d = json.load(sys.stdin)
cutoff = datetime.now(timezone.utc) - timedelta(hours=<N>)
prs = [p for p in d['value']
       if datetime.fromisoformat(p['closedDate'].replace('Z','+00:00').split('.')[0]+'+00:00') >= cutoff]
by_repo = defaultdict(list)
for p in prs: by_repo[p['repository']['name']].append(p)
for repo, items in sorted(by_repo.items(), key=lambda x: -len(x[1])):
    print(f'=== {repo} ({len(items)}) ===')
    for p in items:
        print(f\"  PR {p['pullRequestId']} | {p['createdBy']['displayName']} | {p['title']}\")
"

Notes

  • Don't fetch PR descriptions/diffs by default — title + author is enough for the overview. Only drill into a specific PR if the user asks "tell me more about PR X".
  • The PR title is usually the merge commit subject (DevOps strips the Merged PR <id>: prefix on the web UI but the API title is clean).
  • Windows curl handles the URL escaping fine, but the $top query param must be escaped as \$top in bash to avoid shell expansion.
  • If the user is on a feature branch and only cares about one repo, this skill is overkill — point them at git log --since=... instead.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.