---
name: pigeon
description: Use Pigeon to coordinate project-local tasks across coding agents and people.
---

# Pigeon

Pigeon is a small local task queue CLI backed by SQLite. Use it when coordinating work inside a project without introducing a hosted service.

## First Step

Run `pigeon status` before adding, claiming, or updating tasks. It shows the active SQLite database path and task counts. If multiple agents should share a queue, they must use the same project root or the same `PIGEON_DB` value. Use `PIGEON_WORKTREE_LOCAL=1` only when you intentionally want a separate queue per worktree.

```sh
pigeon status
pigeon whoami
```

If `pigeon whoami` shows a remote URL, normal board commands are being sent to that Pigeon server instead of a local SQLite file.

## Install

For one-off use, run the published package with Bun:

```sh
bunx --bun task-pigeon@latest status
```

For repeated local use:

```sh
bun add --global task-pigeon
pigeon status
```

Do not try to run Pigeon directly from a Git URL with `bunx`; use the npm package.

## Agent Workflow

Use this loop for ordinary task coordination:

```sh
pigeon status
pigeon list --output normal
pigeon claim --by codex
pigeon update 12 --note "Investigating"
pigeon wait --by codex
pigeon done 12
```

Use `pigeon config --by <name>` to set a local default actor when you are repeatedly running commands in the same session or project. This is a name tag, not sign-in. Environment override also works: `PIGEON_BY=codex pigeon status`.

By default, `pigeon list` and `pigeon watch` show active tasks: `pending`, `claimed`, and `blocked`. Use `--all` only when done tasks matter too. Use CSV status filters like `--status pending,blocked`, or `--status active` as shorthand for `pending,claimed,blocked`.

Use `pigeon monitor --by <agent>` for a long-running terminal screen with status, tasks, and unread messages together. The monitor shows a visible control bar, and detail mode backs out with `Esc`, `Backspace`, or left arrow.

Use `pigeon monitor --by <agent> --mentions-only` when the message board is noisy and you only want messages addressed to that agent.

Use the `pigeon-babysit` skill when you want a task or PR to stay actively monitored between turns instead of letting the work go quiet. Babysit flows must start with `pigeon status` and `pigeon whoami`, and they must stay on one shared queue or one explicit remote URL for the whole run. If `whoami` shows a worktree-local queue, stop unless that isolation was intentional.

Use `pigeon wait --by <agent>` when you are idle, blocked, or waiting for another counterpart. Add `--mentions-only` when you only want messages addressed to that agent to wake the session. After it returns, run `pigeon status --by <agent>`, `pigeon list --output normal`, and `pigeon message list --by <agent> --unread` before deciding what to do next.

```sh
pigeon wait --by codex
pigeon wait --by codex --mentions-only
pigeon wait --by codex --timeout 300000
```

Use focused monitor flags when one section matters more than the whole board:

```sh
pigeon monitor --by codex --compact
pigeon monitor --by codex --hide-status --hide-tasks
pigeon monitor --by codex --hide-messages
```

When adding tasks, include a URL, note, priority, and labels whenever useful context exists:

```sh
pigeon add "Fix failing publish" --url https://github.com/andrew-bierman/pigeon/issues/3 --note "trusted publishing failure" --priority high --labels release,npm
```

Claim a specific task when the work is already identified:

```sh
pigeon claim 12 --by codex
```

Release a wrong claim back to `pending`:

```sh
pigeon release 12
```

Block instead of completing when work is waiting on outside context. Include the dependency with `--blocked-by` when it is known:

```sh
pigeon block 12 --note "waiting on credentials" --blocked-by npm
```

Pigeon validates task input. Provided URLs must be valid URLs, priorities must be `low`, `normal`, `high`, or `urgent`, labels are normalized as comma-separated values, and blocked tasks require a non-empty note.

## Messages

Use messages for coordination context that should not become a task, especially when multiple agents are active in the same repo.

```sh
pigeon message add "@claude Codex is checking release automation" --by codex
pigeon message add "Please check the package metadata" --by codex --to claude
pigeon message list --mentioned claude
pigeon message list --by claude --unread
pigeon message ack 1 --by claude
pigeon message resolve 1
```

Mentions can come from `@name` in the body or comma-separated names passed to `--to`.

Read state is per agent name. A message acknowledged by Codex remains unread for Claude until Claude acknowledges it too. Use `pigeon message resolve <id>` when the message no longer belongs on anyone's live board. Resolved messages are hidden from normal message lists and monitors; use `pigeon message list --all` to inspect resolved history.

If you post a message for a specific counterpart, you usually own cleanup. Check that counterpart's read state with `pigeon message list --by <agent>`. Once the counterpart has acknowledged or acted on the message, resolve it so monitors stay focused.

Use `pigeon status --by codex` to include Codex's unread message count.

## Private Remote

Use private remote mode when another computer needs the same queue. One machine owns the SQLite file and runs the Elysia server; other machines send fixed Pigeon commands over HTTP through the Eden Treaty client. Do not expose this on the public internet.

Server:

```sh
PIGEON_TOKEN=secret pigeon serve --host 100.x.y.z --port 8787 --db /data/pigeon/project.db
```

Client:

```sh
pigeon config --remote-url http://100.x.y.z:8787 --remote-token secret
pigeon whoami
pigeon status
pigeon list --output normal
```

For temporary sessions, prefer environment variables:

```sh
PIGEON_URL=http://100.x.y.z:8787 PIGEON_TOKEN=secret pigeon monitor --by codex
```

Use `pigeon remote` for examples. Clear remote config with `pigeon config --clear-remote-url --clear-remote-token`.

Projects can configure extra required fields. Run `pigeon requirements` to see available keys. If `claim.by` is required, always pass `--by` when claiming:

```sh
pigeon requirements
pigeon config --show
pigeon claim --by codex
```

## Tables And Output

Default `list` and `watch` output includes task URLs. Use `--columns` when you need notes or lifecycle timestamps too.

```sh
pigeon columns
pigeon list --columns id,status,priority,title,url,labels,blockedBy,note,claimedBy,updatedAt
pigeon watch --columns id,status,priority,title,url,labels,blockedBy,note,claimedBy,updatedAt
```

Use normal stacked output when URLs or notes should stay easy to read.

```sh
pigeon list --output normal
pigeon watch --output normal
```

Use `--output table` when a compact grid is more useful than readable full links.

Set project defaults:

```sh
pigeon config --by codex
pigeon config --columns id,status,priority,title,url,labels,note,claimedBy,updatedAt --output normal
```

Set user defaults:

```sh
pigeon config --user --by codex
pigeon config --user --columns id,status,priority,title,url,labels,note,claimedBy,updatedAt --output normal
```

Config precedence is:

```text
defaults < user config < project config < PIGEON_BY/PIGEON_URL/PIGEON_TOKEN/PIGEON_COLUMNS/PIGEON_OUTPUT/PIGEON_REQUIRE < CLI flags
```

Valid columns are `id`, `status`, `priority`, `title`, `url`, `claimedBy`, `blockedBy`, `labels`, `note`, `createdAt`, `updatedAt`, `claimedAt`, `blockedAt`, and `doneAt`.

Valid output modes are `auto`, `table`, and `normal`.

## Rules Of Thumb

- Prefer `claim` before doing work so other agents can see ownership.
- Prefer resolving your own messages after the intended counterpart has acknowledged or acted.
- Prefer `wait --by <agent>` instead of repeatedly checking when blocked or idle.
- Prefer `release` over manual database edits when you claimed the wrong task.
- Prefer `block --note` when external context is needed.
- Prefer `done` only when the task is actually complete.
- Keep project queues project-local unless a shared `PIGEON_DB` path is intentional.
