Cursor Hooks Integration
Today's release of Cursor 1.7 introduces a new lifecycle hooks feature, which makes it easy to use GitButler to automatically write smart commits and create new branches from your Cursor chats in the background.
Working with Cursor
One of the nice things about the GitHub Mafia is that there are helpful Hubbers everywhere.
After we made the Claude Code hooks integration, I reached out to some amazing ex-Hubbers at Anysphere to see if they could help us with a way to more easily see what Cursor was doing when it worked, so we could build some tools to help automate the version control of it's work.
At the time, they were working on writing temporary Git commits into a hidden ref as the agent worked as a sort of snapshotting system and we thought we could tie into that. However, after some issues turned up, they moved on to pursuing a hooks system instead.
Happily, they invited us to try out the new system as it was being built in the nightlies, so we got to give early feedback and hopefully help improve the API and documentation. This is how we're able to provide our hooks compatibility on the first day.
Why GitButler + Cursor?
There are a few challenges that I think we've all faced when using agentic coding systems, expecially around version control.
If you do setup some sort of Git subagent, MCP server or ruleset, you have to wait for it to run every time and you simply end up with one big stack of commits. So most developers just wait and do the committing by hand, which means you probably mix up work or lose context. Or best case, have to switch context when the agentic task is done.
It's much nicer (and much, much faster) to have this done automatically and have the commits aware of the agentic context prompt when crafting the commit message.
How do you use it?
Cursor hooks are read from a hooks.json
file, either in your project's .cursor
directory, or your user's global ~/.cursor
directory if you want the hooks to run for all your projects. (There is also an enterprise directory at /etc/cursor/hooks.json
but I assume that's rarely used?)
You need to install the GitButler CLI from either brew install gitbutler
or through your GitButler settings.
That gives you the but
command line tool, which is what you need to setup as your hooks. Your hooks file would then look like this:
{
"version": 1,
"hooks": {
"afterFileEdit": [
{
"command": "but cursor after-edit"
}
],
"stop": [
{
"command": "but cursor stop"
}
]
}
}
We make use of the afterFileEdit
hook to mark files that Cursor has modified and assign them to a branch, then commit and write a message on the stop
hook.
Now every new chat you do will automatically be put in a new branch and every time the task is completed, a new commit will be made based off your prompt. You can always easily squash down commits later, but now you have a nice starting point and a reminder of what your prompt history was.
The other nice thing is that creating a new chat automatically makes a new branch in parallel, meaning it's easier to have it start work on a new thing and easily split that out into an independent PR.
Check out our video intro or docs to learn more about how cool it is to use Cursor with GitButler in the background automatically handling everything.
Tell me more about Cursor hooks
I'm glad you asked!
We learned a lot about hooks while reviewing the functionality and developing the integration, so we wrote up a deep dive article if you're interested in how hooks work and what else you can currently do with them.
Try It Today
The Cursor hooks integration is available in the latest GitButler release's CLI. If you have questions or feedback, join us in our Discord community - we'd love to hear about your experience!