# Sloop
A job scheduler for coding agents.
Sloop runs each ticket in its own Git worktree, reviews the result, and merges
it when it passes.
- **Agent orchestration** — each ticket picks its agent, model, and effort:
design with a powerful model, send implementation and review to specialized
workers.
- **Agentic loops** — combine predefined flows, parallel agents, and scheduled
execution.
- **Runs while you sleep** — set running hours and wake up to finished work.
- **Repeatable** — tickets are Markdown files in your repo, easy to share and
re-run.
Under the hood it's a small Rust daemon that judges outcomes from commits and
tests.
**Install**
```sh
curl --proto '=https' --tlsv1.2 -LsSf \
Prebuilt binaries are also on the [releases page](https://github.com/hamish-mackie/sloop/releases).
**Initialize**
```sh
sloop init # Configure this repository
sloop daemon # Start the scheduler
```
**Write a ticket** (`my-ticket.md`)
```markdown
---
name: Add request logging
blocked_by: []
target: claude
model: sonnet
effort: medium
---
Log each HTTP request with its method, path, status, and duration.
```
**Post it**
```sh
sloop post my-ticket.md
sloop list # Ticket status, and why pending ones aren't running
sloop logs <run-id> # Follow a run's output
```
---
## Configuration
`sloop init` creates `.agents/sloop/config.yaml` with working targets for
Claude Code, Codex, and OpenCode. To change when work runs or which agent Sloop
uses, edit the generated config:
```yaml
version: 1
scheduler:
max_parallel_tasks: 2
running_hours:
start: "22:00"
end: "06:00"
agent:
default_target: claude
targets:
claude:
cmd: ["claude", "--print", "--model", "{model}", "--effort", "{effort}", "{prompt}"]
opencode:
cmd: ["opencode", "run", "--model", "{model}", "--variant", "{effort}", "{prompt}"]
codex:
cmd: ["codex", "exec", "--model", "{model}", "--config", 'model_reasoning_effort="{effort}"', "--sandbox", "workspace-write", "--ephemeral", "{prompt}"]
```
Running hours use local time and may cross midnight; omit them to run at any
time. Custom agent commands must include `{prompt}` exactly once; `{model}`
and `{effort}` come from the ticket. Keep secrets in environment variables.
## Flows
Flows define the steps a ticket must pass before its work is merged. `sloop init`
creates `.agents/sloop/flows/default.yaml`:
```yaml
stages:
- name: build
kind: build
- name: review
kind: exec
cmd: [opencode, run, "Read .agents/sloop/prompts/review.md and follow its instructions."]
- name: merge
kind: merge
```
The `build` stage runs the coding agent. Add `exec` stages for tests, reviews,
or any other command. Stages run in order and stop on failure; `merge` lands the
work after every earlier stage passes.
The filename is the flow name. Select one with `flow: <name>` in the ticket or
with `sloop post my-ticket.md --flow <name>`.
## Logs
Each run's full output is kept as `runs/<run-id>/output.ndjson` under Sloop's
state directory (on Linux, `~/.local/state/sloop/repositories/<repository>/`).
`sloop daemon` prints the exact log and socket paths on startup, and
`sloop logs <run-id>` is the normal way to read them.
## Tickets and projects
Tickets live under `.agents/sloop/tickets/` and projects under
`.agents/sloop/projects/` (both configurable). Every ticket belongs to one
project; `sloop init` creates a default for unassigned tickets. Projects group
and scope tickets, nothing more.
`blocked_by` lists the ticket IDs that must finish first; `[]` means none.
Posting rejects a missing `name`, an empty body, unknown blockers, and
dependency cycles, and assigns an ID and worktree branch (`sloop/<id>`) unless
you set your own. Reposting an edited file updates the ticket in place.
`sloop show <project>` lists recent notes and commits per ticket; add `--json`
for structured data.
## Design
Human-authored content lives in committed files. Runtime state lives in a
local SQLite database that only the daemon writes (bundled, nothing to
install). `sloop reindex` rebuilds whatever can be derived from committed
files and Git; runtime history such as notes may not survive it.
## License
Copyright 2026 Hamish Mackie. Licensed under the
[Apache License, Version 2.0](LICENSE).