# Loops

A loop runs an agent or a command on a schedule. Set it once, and every night at 3 Claude picks a bug, fixes it on its own branch and opens a PR. You review it in the morning.

A loop runs in one of two places:

- **A project.** Each run gets its own Pane in a fresh worktree and branch, so you review the result like any other Pane.
- **A Session.** Each run sends the loop's prompt to that Session's agent. No new Pane, worktree or branch. Use it for a job that spans all your projects, like a morning standup summary.

Use a loop for a big job that should happen on a schedule: a nightly bug sweep, a weekly docs audit, a Monday dependency check. Loops run at most once an hour. If an agent only needs to wait a few minutes, for CI or a review, it should sleep with its own tools instead.

Loops are in Pane 2.4.204 and later.

## In the app

1. Click **Loops** near the top of the sidebar. The Loops page lists every loop across your projects.
2. Click **+ New**. A drawer opens.
3. Pick the project and what runs: Claude, Codex, Cursor or a command. Add the first message it gets.
4. Pick the schedule: **Hourly**, **Daily**, **Every weekday**, **Weekly** (choose the days), **Monthly** (choose the day), or **Custom cron**. Then pick the time. The drawer shows the schedule in words, like "Weekly on Mon, Wed, Fri at 9:00 AM", the next three runs and the cron it saves.
5. Click **Save**.

Select a loop to see its schedule, its next run, a strip of its last 10 runs and a table of those runs. **Edit** opens the same drawer.

Each run's branch is named after the loop and the run's date and time, like `loop-nightly-bug-sweep-20261024-0300`. A run's Pane shows a breadcrumb above its tabs (Loops › loop › run) that leads back to the loop, and a rail that switches between the loop's runs.

## From the CLI

Start Claude every day at 03:00:

```bash
runpane loops create --repo active --name nightly-bug-sweep \
  --cron "0 3 * * *" --agent claude \
  --prompt "Pick one bug from yesterday's issues, fix it, and open a PR." --yes
```

Run a command every Monday at 09:00:

```bash
runpane loops create --repo my-app --name dependency-check \
  --cron "0 9 * * 1" --tool-command "./scripts/nightly-report.sh" --yes
```

Check a schedule before you save it. `--dry-run` prints the schedule in words and the next run, and saves nothing:

```bash
runpane loops create --repo active --name docs-audit --cron "0 16 * * 5" \
  --agent codex --prompt-file audit.md --dry-run
```

Manage loops by id. `runpane loops list` shows it:

```bash
runpane loops list
runpane loops update --loop <id> --cron "0 4 * * *" --yes
runpane loops run --loop <id> --yes
runpane loops pause --loop <id> --yes
runpane loops resume --loop <id> --yes
runpane loops delete --loop <id> --yes
```

- `--repo` takes the same values as `panes create`: `active` (the repo selected in Pane), a repo id, a path or a saved name.
- `--agent` is `claude`, `codex` or `cursor`. `--tool-command` runs a command instead. Each replaces the other.
- `--prompt` is the text typed into the agent after it starts. `--prompt-file <path>` reads it from a file, and `-` reads stdin.
- `--worktree-name` sets the branch name template. It's `loop-<name>` by default.
- Commands that change a loop need `--yes` from a script or agent. In a terminal, they ask first.
- `update` changes only the values you pass.
- Add `--json` to any command for machine-readable output.

Your agents can manage loops too, with these commands or the `pane` MCP server's loop tools: `loops_list`, `loops_create`, `loops_update`, `loops_run`, `loops_pause`, `loops_resume` and `loops_delete`. See [MCP](/docs/mcp).

## Session loops

A Session loop sends its prompt to a [Session](/docs/sessions) instead of opening a Pane. In the app, choose **Runs in: Session**, then pick **New Session for this loop** or an existing Session. From the CLI, pass `--session` instead of `--repo`, with a Session id, its name, or `new`:

```bash
runpane loops create --session new --name morning-standup --cron "0 9 * * 1-5" \
  --agent claude --prompt "Summarize what changed across my projects since yesterday." --yes
```

- **Agents only.** A Session loop runs Claude, Codex or Cursor, and it needs a prompt.
- **Every message is unattended.** Saving the loop makes the Session's agent skip permission prompts, for every message the Session gets, not only loop runs.
- **Restart a running agent once.** An agent that's already running keeps the flags it started with. Until you exit it and start it again, runs wait and show **needs attention**. Pane never restarts it for you.
- **A busy agent queues the prompt.** If the agent is in the middle of a turn, the prompt goes in after it. If it's stopped at a prompt of its own, the run shows **needs attention**. Open the Session and fix it.
- **No run Panes.** The last 10 runs are listed, and there's nothing to archive.

## Rules

- **Schedule.** One five-field cron, in the time zone of the machine running Pane. `0 3 * * *` is "Daily at 3:00 AM".
- **At most once an hour.** Pane won't save a cron whose runs are less than 60 minutes apart.
- **Pane has to be running.** Runs start only while Pane runs on that machine. That can be your laptop or an always-on machine you reach with [Remote Pane](/remote).
- **Missed runs.** A run up to 15 minutes late still starts, for example after your computer wakes up. Later than that, it's recorded as skipped. Missed runs are never caught up.
- **Overlap.** A run starts even if the last one is still going.
- **Runs are unattended.** Claude, Codex and Cursor runs skip their permission prompts, so write the prompt like you'd brief someone working alone. A `--tool-command` runs as written.
- **Kept runs.** Pane keeps each loop's last 10 runs and archives older run Panes. A run Pane with uncommitted or unpushed work isn't archived. Its run stays in the list with a note, so a loop can show more than 10 runs.
- **Pause.** A paused loop starts no scheduled runs. Resuming picks up at the next scheduled time.
- **Run now.** `runpane loops run` starts a run right away, even while the loop is paused.
- **Delete.** Deleting a loop stops its schedule. Its run Panes stay, as normal Panes.
- **Folder trust.** Claude and Codex ask whether to trust a folder they haven't seen, and each project run is a new worktree. A run stopped there shows **needs attention**. Open the run and answer, or open the project folder in the agent once and trust it. Pane never answers a trust prompt for you.
- **Commands on Windows.** A `--tool-command` runs in Git Bash by default. Write it in bash, or call cmd with `//c`, like `cmd //c echo hi > loop.txt`.

## Run status

`runpane loops list --json` lists each loop's runs, newest first. A run's `status` is:

- `started`: its Pane was created, or a Session loop's prompt was sent. For a project loop, `sessionId` is the Pane's id, so you can check it with `runpane agents status --pane <sessionId>`. If `error` is set too, the run needs attention: the agent stopped at a prompt such as folder trust, never became ready, or Pane couldn't confirm the prompt arrived.
- `failed`: the Pane couldn't be created, or the Session couldn't be reached. `error` says why.
- `skipped`: the run came and went while Pane wasn't running or the computer was asleep.

## Related

- [Pane Loops](/scheduled-agents): what Loops look like, with real captures
- [Notify](/docs/notify): let a run ask you a question
- [Agent Loops](/docs/agent-loops): one agent managing other agents. A loop can start that agent every morning.
- [runpane CLI](/docs/runpane-cli)
