Task management for agentic engineering
A CLI that gives AI agents deterministic, token-efficient task tracking,
without the complexity of full project management tools.
Install · Quick Start · Commands · Output Formats · Why Tick?
Tick is a lightweight CLI for tracking tasks, dependencies, and status transitions inside your project. It stores everything in a plain JSONL file (human-readable, git-friendly) with a SQLite cache for fast queries. Run tick init, and you're set.
It's built to be used by AI agents as much as by humans. Output auto-switches between a token-efficient format for agents and clean tables for terminals, so the same commands work in both contexts.
Claude, Cursor, and other AI coding agents need a way to track tasks across sessions. The built-in approaches have problems:
- TodoWrite / in-context lists — lost between sessions, no persistence, no dependency tracking
- Markdown files — no structure, agents parse them inconsistently, output is verbose
- Beads / full PM tools — too much complexity for a coding session, heavy overhead
Tick sits in between: structured enough for agents to reason about reliably, simple enough that it doesn't get in the way.
| Tick | TodoWrite | Markdown | Beads | |
|---|---|---|---|---|
| Persists across sessions | Yes | No | Yes | Yes |
| Dependencies & blockers | Yes | No | No | Yes |
| Token-efficient output | TOON (30-60% savings) | N/A | No | No |
| Deterministic format | Yes | Varies | No | Yes |
| Complexity | Low | Minimal | Minimal | High |
| Setup | tick init |
None | None | Config |
macOS
brew install leeovery/tools/tickLinux
curl -fsSL https://raw.githubusercontent.com/leeovery/tick/main/scripts/install.sh | bashGo
go install github.com/leeovery/tick/cmd/tick@latesttick init # create .tick/ in your project
tick create "Build auth module" # create a task
tick create "Write tests" --priority 1 --blocked-by tick-a1b2
tick list # see all tasks
tick ready # tasks with no blockers
tick start tick-a1b2 # open → in_progress
tick done tick-a1b2 # in_progress → doneInitialize a new tick project in the current directory. Creates a .tick/ directory with an empty tasks.jsonl file.
tick initCreate a new task. Returns the full task detail on success.
tick create <title> [flags]| Flag | Type | Default | Description |
|---|---|---|---|
--priority |
0-4 |
2 |
0 critical, 1 high, 2 medium, 3 low, 4 backlog |
--description |
string | Task description (supports multi-line) | |
--parent |
ID | Make this a subtask of another task | |
--blocked-by |
IDs | Comma-separated list of tasks this depends on | |
--blocks |
IDs | Comma-separated list of tasks this blocks |
tick create "Build auth module"
tick create "Critical fix" --priority 0
tick create "Write tests" --blocked-by tick-a1b2,tick-c3d4
tick create "Login endpoint" --parent tick-a1b2List tasks with optional filters. Results are sorted by priority (ascending), then creation date.
tick list [flags]| Flag | Type | Default | Description |
|---|---|---|---|
--status |
string | Filter by status: open, in_progress, done, cancelled |
|
--priority |
0-4 |
Filter by priority level | |
--parent |
ID | Show descendants of a task | |
--ready |
bool | false |
Show only ready tasks (open, no unresolved blockers, no open children) |
--blocked |
bool | false |
Show only blocked tasks (open with unresolved blockers or open children) |
--ready and --blocked are mutually exclusive.
tick list # all tasks
tick list --status open # filter by status
tick list --priority 0 # only critical tasks
tick list --parent tick-a1b2 # descendants of a taskAlias for tick list --ready. Shows tasks that are open, have no unresolved blockers, and no open children.
tick readyAlias for tick list --blocked. Shows tasks that are open but waiting on dependencies or have open children.
tick blockedDisplay full detail for a single task, including blockers, children, and description.
tick show <task-id>Modify one or more fields on an existing task. At least one flag is required.
tick update <task-id> [flags]| Flag | Type | Description |
|---|---|---|
--title |
string | Set a new title |
--description |
string | Set or replace the description |
--priority |
0-4 |
Change priority level |
--parent |
ID | Set or change the parent task (pass empty string to clear) |
--blocks |
IDs | Comma-separated list of tasks this blocks |
tick update tick-a1b2 --title "Revised title" --priority 1
tick update tick-a1b2 --parent tick-c3d4Transition a task between statuses.
tick start <task-id> # open → in_progress
tick done <task-id> # in_progress → done
tick cancel <task-id> # any → cancelled
tick reopen <task-id> # done/cancelled → opendone and cancel set a closed timestamp. reopen clears it.
Manage task dependencies. Tick validates all dependency changes and prevents cycles, self-references, and children blocked by their own parent.
tick dep add <task-id> <blocked-by-id>
tick dep rm <task-id> <blocked-by-id>tick dep add tick-a1b2 tick-c3d4 # tick-a1b2 is now blocked by tick-c3d4
tick dep rm tick-a1b2 tick-c3d4 # remove that dependencyShow aggregate task counts grouped by status, workflow state (ready/blocked), and priority.
tick statsRun diagnostic checks against your task data. Read-only, never modifies data.
tick doctorChecks for: JSONL syntax errors, invalid IDs, duplicates, orphaned references, self-referential dependencies, dependency cycles, parent/child constraint violations, and cache staleness.
Force a full SQLite cache rebuild from the JSONL source file, bypassing the freshness check.
tick rebuildShow usage information. With no argument, lists all commands and global flags. With a command name, shows detailed help including flags.
tick help # list all commands
tick help create # detailed help for create
tick create --help # same as tick help create
tick -h # same as tick helpImport tasks from external tools.
tick migrate --from <provider> [flags]| Flag | Type | Default | Description |
|---|---|---|---|
--from |
string | required | Provider to import from (currently: beads) |
--dry-run |
bool | false |
Preview what would be imported without persisting |
--pending-only |
bool | false |
Only import tasks not yet migrated |
tick migrate --from beads
tick migrate --from beads --dry-run --pending-onlyTick auto-detects the context and picks the right format:
| Context | Default format | Override |
|---|---|---|
| Terminal (TTY) | --pretty |
--toon, --json |
| Pipe / agent | --toon |
--pretty, --json |
|
Agent / pipe (TOON) |
Terminal (Pretty) |
Designed for AI consumption. Schema is declared once in the header; rows are compact CSV-like lines. Uses 30-60% fewer tokens than equivalent JSON.
tasks[2]{id,title,status,priority}:
tick-a1b2,Setup auth,done,1
tick-c3d4,Login endpoint,open,1
task{id,title,status,priority,created,updated}:
tick-a1b2,Setup auth,in_progress,1,"2026-01-19T10:00:00Z","2026-01-19T14:30:00Z"
blocked_by[1]{id,title,status}:
tick-c3d4,Database migrations,done
children[0]{id,title,status}:
description:
Full task description here.
Can be multiple lines.
Clean aligned columns for terminals. No borders, no colors, no icons.
ID STATUS PRI TITLE
tick-a1b2 in_progress 1 Setup auth
tick-c3d4 open 1 Login endpoint
Standard 2-space indented JSON with snake_case keys.
[
{
"id": "tick-a1b2",
"title": "Setup auth",
"status": "in_progress",
"priority": 1
}
]Tick stores data in a .tick/ directory at your project root:
tasks.jsonl— append-only source of truth (one JSON object per line, human-editable, git-friendly).store— SQLite cache (auto-rebuilt when JSONL changes, do not commit)lock— file lock for safe concurrent access
Add to .gitignore:
.tick/.store
.tick/lock
--help, -h Show help (tick --help or tick <command> --help)
--quiet, -q Minimal output (IDs only where applicable)
--verbose, -v Debug logging to stderr
--toon Force TOON format
--pretty Force pretty format
--json Force JSON format
MIT