graft

Blog

Graft is open: keep your changes, keep getting updates

The problem

You changed an open-source tool. Maybe you fixed a bug upstream hasn't taken yet, or added the one option you needed. With an agent, that took an afternoon.

Then upstream ships a release. Now you either redo your change on the new version, or you stay where you are and miss the fixes. Most people stay. A few releases later the copy is far enough behind that catching up is its own project.

Graft is for that moment.

The prompt

Thariq (@trq212) posted that there should be a new way to distribute open source, where people modify it with agents and also

get upstream automatically merged in

He added that coding agents can already do this, they just won't do it automatically. That's the part Graft does.

What Graft does

Your changes are commits on top of an upstream release, each with the reason you made it in the commit message. When upstream ships a new release, Graft moves those commits onto it. A change that applies cleanly comes along as it is. A change upstream already made is dropped, and a drop needs evidence. A change that conflicts goes to an agent, along with your reason.

Then Graft runs your tests on the moved copy and on the release as shipped. If every change landed and your copy adds no failure the release doesn't have, Graft pushes a new branch, graft/<release>, and opens a pull request. It never pushes to your branch. You decide whether to take it.

Branches with merge commits are fine. Graft carries your own commits and leaves upstream's and the merges out.

The rule it never breaks

Graft never moves you onto a copy that fails your tests. If the tests fail on the moved copy, or one of your changes can't be accounted for, your copy stays where it was and the dashboard says why in one sentence.

A stay is annoying. A broken copy that looks fine is worse. So when it's unsure, Graft stays.

While getting ready I found a bug in the engine on my own benchmark: in some cases a change could be left out while the sync still moved. No user's sync ran into it. It's fixed, and Graft now checks before every move that each of your changes is on the moved copy. The write-up is on the changelog.

The numbers, including the stays

Before opening it up, I ran Graft on 12 real forks on GitHub, onto the next release and the newest, with agents and each project's own tests. 10 of 24 syncs moved by themselves: 7 of 12 onto the next release, 3 of 12 onto the newest. Wrong moves: 0.

The other 14 stayed. 5 because the agent wasn't sure enough of its fix, 4 because the fork's own changes already failed upstream's tests, 3 because the agent asked for a decision, and 2 because part of a change was already upstream.

That's under half moving on its own. I'd rather tell you that than round it up. Every one of those syncs, moved or stayed, is on /results, along with the counts for every sync Graft runs for users from here on.

The quickest way to watch one is my demo fork, craigm26/tqdm: tqdm with two small changes for CI logs, sitting on v4.66.1. Graft moves them onto v4.70.1 and the tests pass. The run took about a minute and a half.

What it costs

Free. At launch, the first 50 people to sign up get in right away. 10 syncs a month and up to 5 copies. Your copy moves automatically when nothing conflicts, and your first conflict is resolved free by Graft's agent. After that, you can save your own Anthropic API key and Graft's agent resolves conflicts on it.

Premium, $12 a month. Graft's agent, running on Anthropic's Managed Agents, sets up your tests and resolves conflicts for you. $6 of agent work is included each month, and there's no overage: if it runs out, conflicts wait until the 1st. Up to 40 syncs a month. Details are on the pricing page.

For agents

Most of these changes are going to be made by agents, so an agent should be able to use Graft without me or you in the loop. There's an MCP server at graftfork.com/mcp, an HTTP API under /api/v1, and a Claude Code plugin:

/plugin marketplace add craigm26/graft-claude-code
/plugin install graft@graft-claude-code

The plugin adds a skill. When Claude changes a dependency, a fork or a vendored package, it writes why into the commit message in the form Graft reads, and offers to track the repository. That reason is what Graft hands the agent at the next conflict, so writing it down when the change is made helps every later move. The plugin is public at github.com/craigm26/graft-claude-code, and the setup is in Agents and Claude Code.

What it doesn't do yet

  • Only git, only GitHub. No GitLab or Bitbucket yet, and no other version control systems.
  • No edited packages. If you changed a package in place, in node_modules or site-packages, with no repository behind it, Graft can't carry it yet. That's where a lot of agent-made changes live, and it's on the list.
  • Tests are found for Python and Node. Anything else needs a .graft.yml that says how to run them.
  • A merge with its own edits is refused. If a merge in your branch resolved a conflict by hand, Graft stays rather than guess.
  • One conflict at a time. A release with two conflicting changes takes two rounds.
  • The automatic rate. Under half of the benchmark syncs moved by themselves. Moving more without guessing is the main work ahead.

Try it

Paste any public fork at /try. No account. It runs a real sync on a short-lived machine, never pushes, and runs no agent. When you're ready to connect your own copy, your first sync, step by step walks through it.

If a sync stays when you think it should have moved, or anything else looks wrong, email support@graftfork.com. I read every one.

Craig