Agent skill

Auto Merge

by aeonfun in aeonfun/aeon

Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts

MITAuto-check passed

Install Auto Merge

skills CLI
$ npx skills add aeonfun/aeon --skill auto-merge -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install aeonfun/aeon auto-merge --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/auto-merge .claude/skills/auto-merge && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
auto-merge
GitHub stars
767
Token cost
~2.6k tokens
SKILL.md length
1,155 words
Files
1
Skills in repo
82
Repo updated
First seen
Licence
MIT

At a glance

Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts

  • Works in 8 steps: Bootstrap state — per-PR retry counter… → List open PRs for each watched repo with… → Handle UNKNOWN state — GitHub computes… → …
  • SKILL.md covers Safety policy, Steps, Network note and Constraints, plus 1 more section
  • Calls gh and jq; needs GITHUB_TOKEN

What it does

Auto Merge is an agent skill from aeonfun/aeon. Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: The most autonomous AI agent framework: runs unattended on GitHub Actions, self-healing skills, drives Claude Code, Grok, Codex & more. No approval loops. Configure once, forget… The licence is MIT.

Example prompts

  • “/auto-merge”

Requirements

  • A credential in GITHUB_TOKEN

Workflow steps

8 steps, taken from the first numbered list in SKILL.md.

  1. Bootstrap state — per-PR retry counter lives in memory/topics/auto-merge-state.json
  2. List open PRs for each watched repo with the full field set
  3. Handle UNKNOWN state — GitHub computes mergeStateStatus lazily. If a PR returns UNKNOWN, sleep 3 seconds and re-query once
  4. Apply the safety policy to each PR. Record a verdict for every PR: either MERGE or SKIP:. Reasons must name the failing gate — e.g…
  5. Merge qualifying PRs, up to MAX_AUTO_MERGE (default 3)
  6. Send a notification only when at least one real (non-dry-run) merge succeeded or at least one PR has hit the retry cap (5b below). No…
  7. Persist state — write the updated memory/topics/auto-merge-state.json. Update last_run to current timestamp. Validate with jq empty; on…
  8. Log to memory/logs/${today}.md under an ### auto-merge heading

What it can do on your machine

Read from SKILL.md and the folder at commit c0cb7c4. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • gh
    • jq

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use gh, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • GITHUB_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Auto Merge loads about 2.6k tokens when it runs. Until then it costs about 25 tokens; SKILL.md has 1,155 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~25
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from aeonfun/aeon at commit c0cb7c4, republished under its MIT licence (© aeonfun). 1,155 words, ~2,573 tokens.

Download SKILL.mdSave it as .claude/skills/auto-merge/SKILL.md (or your agent's skills folder).
name
auto-merge
description
Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts
metadata.title
Auto Merge
metadata.category
core
metadata.tags
dev, meta
<!-- autoresearch: variation C — safety-hardened (author allowlist, size cap, UNKNOWN retry, fork block, dry-run mode) so an autonomous agent with merge credentials cannot accidentally ship a hostile or oversized PR -->

${var} — Repo (owner/repo) to target. If empty, uses every repo in memory/watched-repos.md. Env: AUTO_MERGE_DRY_RUN=1 logs intent without merging. MAX_AUTO_MERGE=N caps merges per run (default 3).

Merge open PRs that are fully green and pass an explicit safety policy. The policy exists because this skill runs autonomously with write access — a bug in the gate is a bug that ships to main.

Read memory/MEMORY.md and memory/watched-repos.md for repos to target. Read the last 2 days of memory/logs/ to avoid re-logging PRs already merged.

Safety policy

A PR merges only when every one of the following holds:

  • Author allowlist: author.login is one of dependabot[bot], renovate[bot], github-actions[bot], OR appears under a ## Trusted Authors section in memory/watched-repos.md. No allowlist → only the three bot logins are eligible.
  • Size cap: additions + deletions ≤ 500. Override by applying the label auto-merge-large on the PR.
  • Base branch: baseRefName is main or master. Refuse any other target.
  • Not a fork: isCrossRepository == false (fork CI can be tampered with).
  • Not draft: isDraft == false.
  • Not already queued: autoMergeRequest == null (avoid fighting GitHub's native auto-merge if a human enabled it) and the PR is not already in a merge queue (mergeQueueEntry == null, checked in step 2b).
  • No opt-out label: none of {do-not-merge, wip, hold, needs-review, blocked} present.
  • Mergeable state: mergeStateStatus == "CLEAN" (this is stricter than mergeable == "MERGEABLE" — CLEAN additionally requires branch-protection gates to be satisfied).
  • Reviews: reviewDecision != "CHANGES_REQUESTED".
  • Checks: every entry in statusCheckRollup has conclusion in {SUCCESS, NEUTRAL, SKIPPED}. Any FAILURE, TIMED_OUT, CANCELLED, PENDING, or null conclusion disqualifies the PR.
  • Retry cap: this PR has been attempted fewer than 3 times. A PR that has hit MERGE_FAIL three times across runs is paused — repeated failure on a CLEAN-looking PR usually means something subtle (a required check that didn't surface, branch-protection drift, token scope drift). Surface it and stop looping.

Steps

  1. Bootstrap state — per-PR retry counter lives in memory/topics/auto-merge-state.json:

    bash
    mkdir -p memory/topics
    [ -f memory/topics/auto-merge-state.json ] || echo '{"prs":{},"last_run":null}' > memory/topics/auto-merge-state.json

    Schema:

    json
    {
      "last_run": "2026-05-23T08:00:00Z",
      "prs": {
        "owner/repo#123": {
          "first_seen": "2026-05-21T10:00:00Z",
          "last_attempt": "2026-05-23T08:00:00Z",
          "attempts": 2,
          "last_outcome": "merge_failed",
          "last_error": "Pull Request is in unstable state"
        }
      }
    }

    PR keys are <owner>/<repo>#<number> so state survives multi-repo runs. Cap to 50 most-recent entries (LRU by last_attempt). Validate with jq empty after write; restore from .bak on failure.

  2. List open PRs for each watched repo with the full field set:

    bash
    gh pr list -R owner/repo --state open --json number,title,author,isDraft,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,autoMergeRequest,isCrossRepository,labels,additions,deletions,baseRefName
  3. Handle UNKNOWN state — GitHub computes mergeStateStatus lazily. If a PR returns UNKNOWN, sleep 3 seconds and re-query once:

    bash
    sleep 3 && gh pr view NUMBER -R owner/repo --json mergeStateStatus,mergeable,statusCheckRollup

    If still UNKNOWN after the retry, skip the PR with reason UNKNOWN-persistent and let the next run retry.

    2b. Skip PRs already in a merge queue. A PR this skill queued on an earlier run is still open, so it would be merged again, bump attempts, and hit the retry cap while it waits. gh pr list does not expose the queue, so ask GraphQL per PR:

    bash
    gh api graphql -f query='query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){mergeQueueEntry{state}}}}' \
      -f o=owner -f r=repo -F n=NUMBER --jq '.data.repository.pullRequest.mergeQueueEntry.state // ""'

    A non-empty state (e.g. QUEUED, AWAITING_CHECKS, MERGEABLE) skips the PR as SKIP:already-queued:<state>. A failed lookup skips it as SKIP:merge-queue-unknown. Neither counts as an attempt: do not touch its attempts, and leave its state entry as is.

  4. Apply the safety policy to each PR. Record a verdict for every PR: either MERGE or SKIP:<specific-reason>. Reasons must name the failing gate — e.g. SKIP:author-not-allowlisted:contributor123, SKIP:size-cap:823-lines, SKIP:mergeStateStatus=BEHIND, SKIP:label:do-not-merge, SKIP:check-failed:lint, SKIP:retry-cap:3-attempts. Vague reasons like SKIP:not-ready are not acceptable.

  5. Merge qualifying PRs, up to MAX_AUTO_MERGE (default 3):

    • If AUTO_MERGE_DRY_RUN=1, log DRY_RUN:would-merge #N and continue — do NOT invoke merge.
    • Otherwise:
      bash
      gh pr merge NUMBER -R owner/repo --squash --delete-branch
      A zero exit is not proof of a merge: on a repo with a merge queue, gh pr merge exits 0 after only adding the PR to the queue. Confirm with GitHub before counting or reporting it:
      bash
      gh pr view NUMBER -R owner/repo --json state,mergeCommit --jq '[.state, (.mergeCommit.oid // "")] | @tsv'
      Only MERGED with a commit SHA is a merge: report that SHA, never one inferred from the command output. OPEN means it was queued: log QUEUED #N, record last_outcome: queued, and report it as queued, not merged. Any other result, or a failed lookup, is logged as MERGE_UNCONFIRMED #N and reported as such. Both count toward MAX_AUTO_MERGE: a merge was attempted and GitHub accepted the command, so the cap still bounds how much this run can send to main. Increment state.prs["<owner>/<repo>#<N>"].attempts on every attempt regardless of outcome. Set first_seen if absent. Reset to 0 (delete the entry) for PRs that no longer appear in the open list (already merged or closed since the last run). If the merge fails (non-zero exit), capture stderr and log MERGE_FAIL #N: <stderr>. Record last_outcome: merge_failed and last_error: <stderr ≤200 chars> on the state entry. A failed merge does NOT count toward the per-run MAX_AUTO_MERGE cap — continue to the next qualifying PR. A PR whose attempts has reached 3 is filtered out in step 3 with SKIP:retry-cap:3-attempts; surface it in step 5b instead of retrying.
  6. Send a notification only when at least one real (non-dry-run) merge succeeded or at least one PR has hit the retry cap (5b below). No merges and no cap hits → no notification, just a log entry.

    5a. At least one merge succeeded:

    *Auto Merge — ${today}*
    Merged N PR(s) on owner/repo:
    - #123: PR title (+45/-12, by @author) — squash merged abc1234   (the mergeCommit SHA GitHub returned)
    Queue cleared. Self-improve cycle unblocked.

    5b. Retry cap reached on ≥1 PR (AUTO_MERGE_RETRY_CAP) — include in the same message if both fire, otherwise stand-alone:

    *Auto Merge — retry cap*
    Hit retry cap (3 attempts) on:
    - owner/repo#40 — last error: "Pull Request is in unstable state"
    Stopping auto-merge attempts on this PR. Investigate manually.

    Dedup: suppress re-notify if the exact same set of cap-hit PR keys already notified within the last 24h (grep memory/logs/ for prior AUTO_MERGE_RETRY_CAP entries).

  7. Persist state — write the updated memory/topics/auto-merge-state.json. Update last_run to current timestamp. Validate with jq empty; on failure restore from a .bak written before this run.

  8. Log to memory/logs/${today}.md under an ### auto-merge heading:

    • Mode: live | dry-run
    • Repo(s): list
    • Merged: #N title @author +A-D SHA per line, confirmed MERGED by GitHub
    • Queued: #N per line (merge queue accepted it; not merged yet)
    • Skipped: #N SKIP:<reason> per line
    • Retry-capped: owner/repo#N — <last_error> per line (empty if none)
    • Totals: merged=X queued=Q qualified=Y considered=Z retry_capped=R
    • If zero qualified, include a verdict breakdown: AUTO_MERGE_SKIP: 0/Z qualifying (behind=B blocked=L failing=F draft=D already-queued=U author-blocked=A size-blocked=S retry-capped=R)
Show full SKILL.md (203 more words)Show less

Network note

gh authenticates via the workflow's GITHUB_TOKEN — no curl needed. If gh pr merge fails with Resource not accessible by integration, the workflow token lacks merge permission on that repo; log once and notify at most once per 7 days (check memory/logs/ for prior notification) to avoid alert spam.

Constraints

  • Never merge a PR whose author is not allowlisted, even if every other gate is green.
  • Never bypass the size cap without the explicit auto-merge-large label (set by a human, not a bot).
  • Never auto-retry a MERGE_FAIL within the same run — if the first merge attempt fails, log and move on.
  • After 3 failed attempts across runs, stop retrying that PR. Surface it once via the retry-cap notification and let the operator investigate.
  • Do not modify PR state other than merging (no comments, no label edits, no branch updates).

Running this as an agent-shipping loop

To close the loop on PRs the agent itself opens (from feature, external-feature, self-improve, etc.), add the agent's GitHub identity under a ## Trusted Authors section in memory/watched-repos.md:

markdown
## Trusted Authors
- aeon-bot
- claude-code[bot]

Once allowlisted, agent PRs flow through the same safety policy as bot PRs and get auto-merged on green CI. The retry cap protects against runaway behavior on a stuck PR.

© aeonfun, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/auto-merge of aeonfun/aeon.

Open the folder on GitHubat commit c0cb7c4

Compare with similar skills

Auto Merge next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Auto Merge compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Auto Merge this skillaeonfun/aeon767—~2.6kAutomated safety check: PassMIT
Merging PRsPostHog/posthog40k—~4.1kAutomated safety check: PassCustom licence
Merge Dependabot PRsonyx-dot-app/onyx32k1 repos~2.2kAutomated safety check: PassMIT
Mergeremotion-dev/remotion63k—~508Automated safety check: PassCustom licence
Authorized PR Merge Workflowdiegosouzapw/OmniRoute74k—~1.3kAutomated safety check: PassMIT
Mergewithastro/astro63k—~153Automated safety check: PassCustom licence

Similar skills

  • Merging PRs

    PostHog/posthog

    Official

    Merge a PR into master through the Trunk merge queue and babysit it until it lands.

    40k GitHub stars~4.1k tokensUpdated today
    Auto-check passed
  • Merge Dependabot PRs

    onyx-dot-app/onyx

    Triages and lands a batch of open Dependabot PRs in the Onyx repo, where main is gated exclusively by GitHub's merge queue: approves and enqueues green PRs, closes superseded duplicates, fixes…

    32k GitHub starsUsed in 1 repo~2.2k tokens
    DevelopmentAuto-check passed
  • Merge

    remotion-dev/remotion

    Official

    Wait for a Remotion pull request to become mergeable, handle merge conflicts, distinguish genuine CI failures from flakes, rerun flaky checks through the flake skill, and merge the PR.

    63k GitHub stars~508 tokensUpdated today
    DevelopmentAuto-check passed
  • Authorized PR Merge Workflow

    diegosouzapw/OmniRoute

    Works through analyzed pull request plans, repairs approved fixes while keeping contributor credit, validates candidates and merges only owner-authorized groups.

    74k GitHub stars~1.3k tokensUpdated today
    DevelopmentAuto-check passed
  • Merge

    withastro/astro

    Official

    Handle main-to-next merge tasks including conflict resolution, changeset cleanup, and CI fix-ups.

    63k GitHub stars~153 tokensUpdated today
    Auto-check passed
  • Merge Up

    symfony/symfony

    Cascade-merge maintained Symfony branches from oldest to newest (e.g.

    31k GitHub stars~4k tokensUpdated today
    DevelopmentAuto-check passed

More from aeonfun/aeon

All 82 skills in this repo
  • Browses open tasks on the TaskMarket agent-worker market and, with explicit operator approval, creates tasks, tracks submissions and submits finished work.

    767 GitHub stars~1.4k tokensUpdated yesterday
    Auto-check passed
  • Sets up and manages an Aeon agent instance that runs skills on a schedule through GitHub Actions: starting, rescheduling, debugging, editing skills and mining chat history.

    767 GitHub stars~9k tokensUpdated yesterday
    Auto-check: warnings
  • Reads a Base Account's address, portfolio and transaction history through the Base MCP server, and stays strictly read-only in unattended Aeon runs, reporting only changes.

    767 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Audits every page of a site each day from its sitemap, scores on-page and technical SEO, checks duplicates across pages and reports what changed since the last run.

    767 GitHub stars~5.1k tokensUpdated yesterday
    Auto-check passed
  • Action Converter

    aeonfun/aeon

    5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates

    767 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Aeon Config Doctor

    aeonfun/aeon

    Static linter for an Aeon instance's configuration that catches silent failures such as unquoted schedules, duplicate keys, unconfigured skills and broken MCP references.

    767 GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed

Questions about Auto Merge

What does Auto Merge do?

Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts. Auto Merge is an agent skill from aeonfun/aeon.

How do I install Auto Merge in Claude Code?

Run `npx skills add aeonfun/aeon --skill auto-merge -a claude-code`. Or copy the skill folder (skills/auto-merge in aeonfun/aeon) into .claude/skills/auto-merge in your project. Claude Code loads it when a task matches its description.

How do I install Auto Merge in Codex?

Run `npx skills add aeonfun/aeon --skill auto-merge -a codex`. Or copy the skill folder (skills/auto-merge in aeonfun/aeon) into .agents/skills/auto-merge in your project. Codex loads it when a task matches its description.

Can I use Auto Merge in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add aeonfun/aeon --skill auto-merge -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/auto-merge, .gemini/skills/auto-merge, .github/skills/auto-merge and .opencode/skills/auto-merge in your project.

What does Auto Merge need to run?

Going by SKILL.md and its folder, Auto Merge needs the command-line tools its instructions call (gh and jq) and credentials named GITHUB_TOKEN. Our summary lists: A credential in GITHUB_TOKEN.

Does Auto Merge access the network?

SKILL.md contains no URLs. Its commands use gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Auto Merge safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Auto Merge use?

Auto Merge is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Auto Merge use?

About 2.6k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Auto Merge?

Skills that share tags, products or a category with Auto Merge: Merging PRs (PostHog/posthog, 40k stars), Merge Dependabot PRs (onyx-dot-app/onyx, 32k stars), Merge (remotion-dev/remotion, 63k stars) and Authorized PR Merge Workflow (diegosouzapw/OmniRoute, 74k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Auto Merge?

aeonfun (a GitHub organization) maintains it in aeonfun/aeon, which has 767 GitHub stars. The repository holds 82 skills in this directory. The repository was last updated on October 8, 2026.

Source: aeonfun/aeon on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.