CLI for teams that ship with coding agents

Your backlog, worked by agents, delivered as merged PRs.

loop picks ideas, goals and tickets from markdown, GitHub issues or Jira, runs Claude Code or Cursor in a fresh worktree, opens a pull request, and keeps driving it through CI and review until it is merged and the ticket is closed.

$ loop list
#  ID              TITLE               STATUS              DEPENDS ON
1  backlog:auth    Add OAuth login     ready
2  gh:142          Rate limit the API  ready
3  backlog:search  Search across orgs  blocked by auth.md  auth.md

$ loop run auth.md
[backlog:auth] run 20260912-101500-backlog-auth created for "Add OAuth login"
[backlog:auth] creating worktree .loop/workdirs/auth-add-oauth-login on branch loop/auth-add-oauth-login
[backlog:auth] starting session session (claude)
[backlog:auth] session 6f1c0b2e ended after 12m4s; join with: cd .loop/workdirs/auth-add-oauth-login && claude --resume 6f1c0b2e
[backlog:auth] verify step: tests
[backlog:auth] pushing loop/auth-add-oauth-login
[backlog:auth] opened PR https://github.com/acme/my-service/pull/318
[backlog:auth] starting ci session (claude)
[backlog:auth] pushing ci round 1
[backlog:auth] CI green, marking PR ready for review
[backlog:auth] merging PR #318 (squash)
[backlog:auth] PR merged
[backlog:auth] removing workdir .loop/workdirs/auth-add-oauth-login
[backlog:auth] done

How it works

One iteration, start to finish

Every phase is persisted, so a crashed worker picks up where it stopped. Nothing is hidden: prompts, steps and scripts all live in your loop project and are referenced from loop.yaml.

Pick

Items are ordered by source, then oldest first. depends on: lines, frontmatter and Jira links block items until their dependencies are closed.

Checkout

A git worktree on loop/<id>-<title>. The item is claimed with a label, a comment or a frontmatter flag so no second loop grabs it.

Session

Your session template is rendered with the ticket (and its comments, if you want them) and the agent runs headlessly. Join any session with loop join.

Verify

Scripts or agent steps run in the workdir after the session and after every fix round. A failing check feeds its output back into a fix session before anything is pushed.

Pull request

A draft PR from a template, linked to the ticket. It is marked ready for review the first time CI is green.

Monitor & merge

Conflicts, red CI and review comments each start a bounded fix round. Merge by policy, behind optional human gates, then close the ticket and clean up.

Configuration

Everything in one file

A loop project is a folder with a loop.yaml, your backlog, prompt templates and hook scripts. Commit it next to your team's other tooling.

Sources, agent runner, models, limits, verify steps, PR settings and the merge policy are all declared here. State lives in a git-ignored .loop/ folder as readable YAML.

Configuration reference →

name: my-service
repo:
  url: git@github.com:acme/my-service.git
  base: main
sources:
  - name: backlog
    type: markdown          # backlog/*.md with frontmatter
    path: backlog
  - name: gh
    type: github            # issues labelled ready-for-agent
    labels: [ready-for-agent]
    claim_label: loop:in-progress
agent:
  runner: claude            # or cursor
  timeout: 45m
  allow: ["Bash(npm test:*)"]   # what a headless session may run
steps:
  setup:
    - script: hooks/setup.sh
  verify:
    - run: npm test
workflow:
  merge: when-green-and-approved
  gates: [before-merge]

Built for real repositories

What you get

Three backlog sources

Markdown files with frontmatter, GitHub issues filtered by label, and Jira via JQL. Mix them in one project; references resolve across sources. Comments from public repositories stay out of the prompt unless you opt in.

Dependencies that mean it

A ticket that says depends on: #12, PROJ-7 waits until both are closed. loop run --force when you know better.

Bounded fix rounds

Review feedback, failing checks (with the job log) and merge conflicts each get their own prompt template and a hard limit. Every review thread gets an answer and is resolved when done. Past it, the run parks with a note on the PR and runs your steps.blocked notification.

Merge policies and gates

manual, when-green, when-green-and-approved or GitHub auto-merge. Pause before the PR, before fixes or before the merge until loop approve, or a /loop approve comment on the PR.

Claude Code or Cursor

Sessions run through the official CLIs with your repository's own CLAUDE.md, AGENTS.md or Cursor rules, plus skills you link in. Permission rules from loop.yaml decide what a headless session may run, and loop's own tokens never reach the agent.

Forks and many projects

No push access? Branches go to your fork and the PR opens from there. One loop watch ~/loops/* drives every project you have.

Inspectable runs

Each run keeps its run.yaml, every prompt it sent, every agent transcript and the PR summary. loop status shows where things stand, loop logs -f follows a session live.

Quick start

Five minutes to the first PR

You need git, the claude or Cursor agent CLI, and a GitHub token. Jira needs an API token as well. loop doctor checks all of it before the first run.

Start with merge: manual: loop opens the PR, keeps it green and leaves the merge to you until you trust the workflow.

Workflow, gates and merge policies →

# grab a binary from github.com/christoph-jerolimov/loop/releases, or:
go install github.com/christoph-jerolimov/loop/cmd/loop@latest

mkdir my-service-loop && cd my-service-loop
loop init                 # loop.yaml, prompts/, backlog/, hooks/
$EDITOR loop.yaml         # repo.url and your sources
loop doctor               # tools, tokens, repo and sources
$EDITOR backlog/login.md  # write an idea

loop list                 # pick-up order and blockers
loop run login.md         # one item, end to end
loop watch --pick         # long-running worker

Point it at a backlog

Open source, a single Go binary for Linux, macOS and Windows, no service to run.