# Getting Started
This guide takes you from nothing to a merged ticket.
## Install
```sh
curl --proto '=https' --tlsv1.2 -LsSf \
Prebuilt binaries are also on the
[releases page](https://github.com/hamish-mackie/sloop/releases).
You also need at least one coding agent CLI installed and authenticated —
Claude Code, Codex, or OpenCode work out of the box. The scaffolded
defaults dispatch to Claude Code; a one-line config change selects another.
## Initialize a repository
Run inside the Git repository you want agents to work on:
```sh
sloop init
```
This scaffolds committed configuration under `.agents/sloop/`:
- `config.yaml` — scheduler settings and agent commands
- `projects/default.md` — the default project for unassigned tickets
- `tickets/` — where your ticket files live
- `flows/default.yaml` — the default flow (build → review → merge)
- `prompts/review.md` — the prompt used by the default review stage
`init` never edits `.gitignore`; whether worktrees and tickets are committed
is your repository's policy.
Then start the daemon:
```sh
sloop daemon
```
This is idempotent — it connects to a running daemon or starts one, and
prints the daemon's log and socket paths. Every other operator command
ensures the daemon is running, so you rarely need to run it by hand.
After installing a new binary, ask the current daemon to drain and replace
itself with that binary:
```sh
./install
sloop daemon restart
```
The command returns immediately. Active runs finish through aftercare, queued
work waits without changing state, and dispatch resumes under the replacement.
## Write a ticket
A ticket is a Markdown file: YAML frontmatter for the metadata Sloop needs,
then a body that becomes the agent's assignment.
```markdown
---
name: Add request logging
blocked_by: []
---
Log each HTTP request with its method, path, status, and duration.
```
Three fields are required, and Sloop rejects a post that omits them rather
than guessing:
- `name` — a non-empty human-readable name.
- `blocked_by` — a YAML list of ticket IDs that must finish first. `[]`
explicitly means "no dependencies"; omitting the field is an error.
- A non-empty body after the frontmatter.
Everything else is optional. `target`, `model`, and `effort` select the
agent; omitted values fall back to the config's `default_target` and that
target's configured `model:` and `effort:`. The scaffolded config runs
`claude` with `opus` at `high` effort, so the ticket above works as-is;
the `codex` target defaults are filled in too, while `opencode` has
provider-qualified model names you set yourself. Sloop
stamps an `id` and a worktree branch derived from the filename
(`add-request-logging.md` → `sloop/add-request-logging`) for you unless you
set your own. That default requires the file stem to be a lowercase
`abc-def` slug; a ticket named otherwise must set `worktree:` explicitly.
## Post it
```sh
sloop post .agents/sloop/tickets/add-request-logging.md
```
Ticket files must live below the configured ticket directory
(`.agents/sloop/tickets/` by default). Posting validates the ticket, writes
the allocated ID back into the file, and queues one run. The daemon picks it
up at the next opportunity, creates an isolated worktree on the ticket's
branch, and spawns the agent there.
Editing the file and posting it again updates the ticket in place — same ID,
refreshed name, blockers, and worktree — without queuing a duplicate run.
## Watch it run
```sh
sloop list # every ticket's name, state, and scheduling reason
sloop status # what is running now, queue depth, next wake
sloop logs <run-id> # a run's captured output
sloop wait <run-id> # block until the run finishes; exit 0 only on merge
```
When the agent exits, Sloop evaluates its stage verdict, runs the bound flow's
`exec` stages in order, and performs its `merge` stage if they pass. A
configured test command runs immediately after the agent, before other flow
stages. The default agent verdict requires exit 0 and at least one observed
commit, so an unchanged run branch is retained for review rather than silently
merged.
## Everyday controls
```sh
sloop hold <ticket> # keep a ready ticket from being dispatched
sloop ready <ticket> # release it again
sloop retry <ticket> # return a failed ticket to ready, reset attempts
sloop pause # stop spawning new agents (in-flight ones finish)
sloop resume # start spawning again
sloop daemon restart # drain active runs, then use the installed binary
sloop cancel <run-id> # kill a run's whole process group, keep its worktree
sloop stop # shut the daemon down (refuses while runs are active)
```
## Where things live
Human-authored content — tickets, projects, flows, prompts, configuration —
lives in committed files under `.agents/sloop/`, so it travels with the
repository and is reviewable in a PR.
Machine state stays out of your repository. On Linux the state directory is
`~/.local/state/sloop/repositories/<repository>/`; on macOS it is under
`~/Library/Application Support/sloop/`. `sloop daemon` prints the exact
paths. Run worktrees are created under `.worktrees/` in the repository
(configurable).
## Next steps
- [Configuration](configuration.md) — running hours, parallelism, agent
targets, flows, and projects.
- [CLI reference](cli.md) — the full command surface.