# Todos and scratchpads from the CLI

The `solo todos` and `solo scratchpads` groups give scripts and terminal sessions project-scoped commands for common [todo](../todos/using-todos.md) and [scratchpad](../scratchpads/using-scratchpads.md) workflows. Both groups are project-scoped, so every command requires `--project-id`.

All commands accept `--json` for machine-readable output. Run `solo projects list` to find project IDs.

## Todos

```bash
solo todos list --project-id <id> [filters...] [--json]
solo todos get <id> --project-id <id> [--json]
solo todos create --project-id <id> --title <title> [--body <body> | --body-file <path|->] [--priority <priority>] [--tag <tag> ...] [--json]
solo todos update <id> --project-id <id> [--title <title>] [--body <body> | --body-file <path|->] [--priority <priority>] [--status <status>] [--tag <tag> ...] [--json]
solo todos delete <id> --project-id <id> [--force] [--json]
solo todos complete <id> --project-id <id> [--release-lock true|false] [--json]
solo todos incomplete <id> --project-id <id> [--release-lock true|false] [--json]
```

### Filtering the list

`todos list` supports the CLI filters below. `--status` accepts one status per command. `--is-blocked` tests whether a todo has unresolved blockers; the CLI does not expose the app's separate **Blocking** filter for active todos that block other work.

| Flag | Description |
|------|-------------|
| `--completed true\|false` | Filter by completion state. |
| `--status <status>` | Filter by status: `open`, `in_progress`, `backlog`, or `completed`. |
| `--is-blocked true\|false` | Filter by blocked state. |
| `--priority <priority>` | Filter by priority: `high`, `medium`, or `low`. |
| `--query <query>` | Filter by title, body, or comment text. |
| `--tag <tag>` | Filter by tag. May be repeated. |
| `--sort <sort>` | Sort by `priority`, `created-desc`, `created-asc`, `updated-desc`, `updated-asc`, `completed-desc`, or `completed-asc`. |
| `--offset <n>`, `--limit <n>` | Page through long lists. |

```bash
# Open, high-priority, unblocked work in project 2
solo todos list --project-id 2 --status open --priority high --is-blocked false

# Everything tagged "bug", newest first
solo todos list --project-id 2 --tag bug --sort created-desc
```

### Creating and updating

`--title` is required when creating. The priority defaults to `medium`. Tags set with `--tag` are normalized to lowercase; on `create` they are added, and on `update` they replace the todo's existing tags.

The body can come from three places:

- `--body <text>` for inline text.
- `--body-file <path>` to read from a file.
- `--body-file -` to read from stdin.

```bash
# Quick todo
solo todos create --project-id 2 --title "Fix flaky login test" --priority high --tag bug

# Longer body piped from stdin
git log --oneline -10 | solo todos create --project-id 2 \
  --title "Review recent commits" --body-file -

# Move a todo into progress and retag it
solo todos update 14 --project-id 2 --status in_progress --tag bug --tag urgent
```

### Completing

`complete` marks a todo done; `incomplete` moves a completed todo back to open. By default, both commands also release your actor's [coordination lock](../mcp-tools/todos.md) on the todo, which matters when agents and scripts share a todo list. Pass `--release-lock false` to keep the lock.

```bash
solo todos complete 14 --project-id 2 --release-lock true
```

`delete` removes a todo permanently. It's non-interactive; a `--force` flag is accepted for compatibility but not required.

## Scratchpads

```bash
solo scratchpads list --project-id <id> [--tag <tag>] [--query <query>] [--include-archived] [--offset <n>] [--limit <n>] [--json]
solo scratchpads read <id> --project-id <id> [--mode full|content|headings|section] [--section-heading <heading>] [--offset <n>] [--limit <n>] [--json]
solo scratchpads create --project-id <id> --name <name> (--content <text> | --content-file <path|->) [--tag <tag> ...] [--json]
solo scratchpads update <id> --project-id <id> --expected-revision <n> [--name <name>] [--content <text> | --content-file <path|->] [--tag <tag> ...] [--json]
solo scratchpads append <id> --project-id <id> (--content <text> | --content-file <path|->) --expected-revision <n> [--newline] [--json]
solo scratchpads rename <id> --project-id <id> --name <name> --expected-revision <n> [--json]
solo scratchpads archive <id> --project-id <id> [--json]
solo scratchpads unarchive <id> --project-id <id> [--json]
solo scratchpads delete <id> --project-id <id> --expected-revision <n> (--confirm | --force) [--json]
```

### Listing and reading

`list` shows active scratchpads by default; add `--include-archived` to see archived ones too. Filter with `--tag` (repeatable) and `--query`.

`read` supports four modes:

| Mode | Returns |
|------|---------|
| `full` | Metadata and content. |
| `content` | Metadata and content; currently the same projection as `full`. |
| `headings` | The scratchpad's Markdown headings, useful as a table of contents. |
| `section` | One section, selected with `--section-heading`. |

```bash
# Skim a long scratchpad's structure, then read one section
solo scratchpads read 5 --project-id 2 --mode headings
solo scratchpads read 5 --project-id 2 --mode section --section-heading "Open questions"

# Page through a long scratchpad 100 lines at a time
solo scratchpads read 5 --project-id 2 --offset 0 --limit 100
```

### Writing with revision checks

Scratchpads use [optimistic concurrency](../integrations/http-api.md) so multiple writers (you, scripts, agents) don't overwrite each other. Every write — `update`, `append`, `rename`, and `delete` — requires `--expected-revision <n>` matching the scratchpad's current revision, which you can get from `list` or `read` (in `--json` output). If the revision has moved on, the command fails instead of clobbering someone else's change; re-read and retry.

Content comes from `--content <text>`, `--content-file <path>`, or `--content-file -` for stdin. On `append`, add `--newline` to insert a newline before the appended text. Tags passed with `--tag` are normalized to lowercase; on `update` they replace existing tags.

```bash
# Create a scratchpad from a command's output
npm audit | solo scratchpads create --project-id 2 --name "audit-results" --content-file -

# Append a note (current revision is 3)
solo scratchpads append 5 --project-id 2 --expected-revision 3 \
  --newline --content "- [ ] follow up on the flaky test"
```

### Archiving and deleting

`archive` hides a scratchpad from the default list without losing it; `unarchive` brings it back. `delete` is permanent and requires `--expected-revision` plus `--confirm`:

```bash
solo scratchpads delete 5 --project-id 2 --expected-revision 4 --confirm
```

## Related pages

- [JSON output and scripting](./json-output-and-scripting.md) — envelopes, exit codes, and jq recipes
- [Todo agent tools](../todos/agent-tools.md) and [scratchpad agent tools](../scratchpads/agent-tools.md) — the MCP equivalents for agents

---

Are you a human? Read this doc on the web: https://soloterm.com/docs/cli/todos-and-scratchpads
