Finish: checks, rebase and merge in one click

Every Shuriken chat works on its own branch. Finish runs your checks, rebases and squash-merges it, or opens a pull request with auto-merge.

FINISH beside a real screenshot of Shuriken with four chats on their own branches, under "Checks, rebase and merge in one click"
Contents

Running five agents at once is the fun part. The end of each one is not: commit what's left, catch up with main, fix the conflict, run the tests, fix the tests, merge, delete the branch, remove the worktree, close the chat. Five times.

We did that by hand for a while and kept forgetting a step, usually the "delete the branch" one. So we built a button for it. It's called Finish, and it lives in the header of every chat that works on its own branch.

What Finish does, step by step#

In Shuriken, every new chat (apart from the Main chat, more on that below) starts on its own branch in its own git worktree, so parallel agents never touch each other's files. When the work is done, you press Finish and it:

  1. waits for the turn to end, so it never merges half a thought;
  2. commits what's left, with the chat's title as the message (or its first message, when the title is too short to say much);
  3. catches up with your default branch by rebasing onto it;
  4. runs your checks;
  5. squash-merges the branch into your default branch, in your project folder;
  6. removes the branch and its worktree, and closes the chat.
Finish waits for the turn to end, commits what is left, rebases onto the default branch, runs the checks from shuriken.json, squash-merges, then removes the branch and worktree. A conflict during the rebase or a failing check goes back to the chat's own agent to fix, up to three times, before Finish stops and says why. ONE CLICK ON FINISH 1Wait for turn2Commit3Rebase4Run checks5Squash-merge6Clean upThe chat's agent fixes itconflict or red check · up to 3 triesconflictred check

The nice part is what happens when something goes wrong. A conflict during the rebase, or a check that fails, goes back to that chat's own agent as a message: it knows what it changed, so it's the right one to fix it. Finish then tries again. After three attempts it stops, tells you why in plain words, and leaves the branch in place, unmerged, for you to look at.

Two more safety rails we were glad to have:

  • One at a time per repository. If two chats edited the same file, they merge one after the other, and the second one resolves against the first.
  • No secrets. If the branch adds something that looks like a secret, Finish refuses and merges nothing.

Your checks live in shuriken.json#

Finish runs whatever you list under checks in shuriken.json, the project file Shuriken keeps at the root of your repository. One command or several:

json
{
  "checks": ["npm run typecheck", "npm test"]
}

Commit the file and every new branch starts with the same checks. When Finish gives up, it names the command that held it up: "The checks still fail: npm test".

Or: a pull request that merges itself#

Some projects want a pull request for every change, with CI as the judge. With a GitHub remote, Finish has a second option, via pull request:

  1. it pushes the branch;
  2. opens the pull request with auto-merge on;
  3. watches it, and closes the chat when GitHub merges it.

If the repository doesn't allow auto-merge, the pull request stays open and the chat tells you to merge it once its checks pass. A finish waiting on its pull request survives a restart of Shuriken.

It never closes a chat over unmerged work#

This was a rule from early on (it shipped in 0.12.0, on 3 October): a chat only closes once its work is in your default branch, or in a pull request on its way there. If you want the chat back without merging, there's Archive, which takes it out of the list and leaves its branch alone.

There's also Merge into main, keep chat, for when you want the work in now but plan to keep going in the same chat. And branches that got left behind show up under Stale branches, with a button to ask an agent to merge one or to delete it.

The Main chat: quick changes on your own branch#

Renaming a variable doesn't need a branch. Each project has one Main chat that works directly in your project folder, on your default branch, for the small stuff: a rename, a version bump, a quick question about the code. It has nothing to merge, so it has no Finish button.

The rule of thumb we use ourselves: everyday quick work goes to the Main chat. Anything you'd want to run in parallel, or anything risky, gets a new chat and a Finish at the end.

Works on other computers too#

If you started a chat on another computer, say a server that never sleeps, Finish does the same steps there, then sends the branch back to the computer the project lives on and merges it there.

For the bigger picture on running several agents side by side, read our guide to running Claude Code agents in parallel. Or skip the reading and try Shuriken: Finish is on every plan.

Frequently asked questions

Where do I tell Shuriken which checks to run?

In shuriken.json at the root of your project, under checks: one command or a list of them, such as your type check and your tests.

What happens when the checks fail?

Finish asks the chat's own agent to fix them and tries again, up to three times. If they still fail, it stops, says which command failed and leaves the branch in place, unmerged.

Does Finish squash my commits?

Yes. A local Finish squash-merges the chat's branch into your default branch, then removes the branch and its worktree.

Can Finish open a pull request instead of merging locally?

Yes, for a project with a GitHub remote. It pushes the branch and opens a pull request with auto-merge on, and the chat closes when GitHub merges it.

Free tools