Getting Started
From install to a fully populated workspace in about 10 minutes. Every command is copy-pasteable and shows the expected output.
Install
Requirements: Go 1.22+. No CGO. No external runtime dependencies.
go install github.com/mazen160/backlog/cmd/backlog@latest
Or download a pre-built binary from GitHub Releases:
curl -L https://github.com/mazen160/backlog/releases/latest/download/backlog_darwin_arm64.tar.gz | tar xz
sudo mv backlog /usr/local/bin/
curl -L https://github.com/mazen160/backlog/releases/latest/download/backlog_linux_amd64.tar.gz | tar xz
sudo mv backlog /usr/local/bin/
Confirm the install:
backlog version
backlog v1.0.0
Initialize a workspace
Create a directory for your project and run backlog init inside it:
mkdir my-project && cd my-project
backlog init
✓ workspace initialized at /Users/alice/my-project
Three files are created:
| File | Purpose |
|---|---|
backlog.db | SQLite database — all tasks, projects, plans, comments, labels |
backlog.json | Project manifest — used by backlog sync to reconcile |
backlog.config | Local workspace settings |
backlog.db and backlog.json to your repository so your team — and any AI agents working alongside you — share the same backlog.
To create a named workspace for use across directories, pass --profile:
backlog init --profile work # creates ~/.backlog/work/backlog.db
backlog init --path ~/projects/api # custom path
Create a project
A project groups tasks under a short alias — the identifier you type in every other command.
backlog project add "API Service" --alias api --repo-path /code/api
ID: 01KR4H1TMRW3QAZ7D274SYCRJ1
Alias: api
Name: API Service
Repo: /code/api
Created: 2026-05-08 12:29
backlog project add "Web Frontend" --alias web
backlog project list
ALIAS │ NAME │ REPO │ CREATED
───────┼──────────────┼───────────┼──────────────────
api │ API Service │ /code/api │ 2026-05-08 12:29
web │ Web Frontend │ │ 2026-05-08 12:29
Set a default project so you can omit -p from most commands:
backlog project set-default api
Create tasks
backlog task add --project api --title "Fix login timeout" --type bug --priority P2
ID: 01KR4H1ZYWGC3BQK01YBMM94P0
Project: api
Title: Fix login timeout
Type: bug
Status: todo
Priority: P2
Actor: human:alice
Created: 2026-05-08 12:29
The actor defaults to human:$USER. Pass --as to override:
backlog task add \
--project api \
--title "Reject unsigned JWTs in auth middleware" \
--type vulnerability \
--priority P1 \
--source "security-review-2026-Q1" \
--as human:alice
List open tasks:
backlog task list
ID │ P │ TYPE │ STATUS │ TITLE │ PROJECT │ LABELS │ ACTOR
──────────┼────┼───────────────┼────────┼─────────────────────────────────────┼─────────┼────────┼───────
01KR4H1Z │ P1 │ vulnerability │ todo │ Reject unsigned JWTs in auth middl… │ api │ │ alice
01KR4H1Z │ P2 │ bug │ todo │ Fix login timeout │ api │ │ alice
The ID column shows the first 8 characters of the ULID. You can use the prefix, the full ULID, or TASK-N interchangeably.
Move through the lifecycle
backlog task move TASK-1 --status doing
backlog task move TASK-1 --status done
All status transitions are valid in any direction:
todo → doing → done
↑___________|
Attach a plan
Plans are versioned markdown documents. Every edit creates an immutable new version — old versions are always readable.
backlog plan add \
--task TASK-1 \
--title "Fix unsigned JWT rejection" \
--content "## Steps
1. Extract JWT from Authorization header
2. Verify RS256 signature with JWKS endpoint
3. Return 401 on missing, malformed, or unsigned tokens
4. Add unit tests with forged tokens" \
--as ai:claude-code
A human reviews and revises:
PLAN_ID="01KR4H25J062ANP3ZN6Z6GFDCM"
backlog plan update "$PLAN_ID" \
--title "Fix unsigned JWT rejection (revised)" \
--content "## Steps
1. Extract JWT from Authorization header
2. Verify RS256 signature with JWKS endpoint
3. Return 401 on missing, malformed, or unsigned tokens
4. Add unit tests with forged tokens
5. Rotate the signing key — current key may be compromised" \
--change-note "added key rotation after security review" \
--as human:alice
View version history:
backlog plan history "$PLAN_ID"
VER │ TITLE │ ACTOR │ NOTE │ CREATED
─────┼──────────────────────────────────────┼────────────────┼──────────────────────────────────────────┼──────────────────
v1 │ Fix unsigned JWT rejection │ ai:claude-code │ │ 2026-05-08 12:29
v2 │ Fix unsigned JWT rejection (revised) │ human:alice │ added key rotation after security review │ 2026-05-08 12:29
Add comments
backlog comment add --task TASK-1 \
"JWKS endpoint is at /auth/.well-known/jwks.json — tested, returns correct keys."
backlog comment add --task TASK-1 \
"Got it. Should we cache the keys?" \
--as ai:claude-code
backlog comment add --task TASK-1 \
"Yes — 1hr TTL, re-fetch on key-ID miss." \
--as human:alice
backlog task show TASK-1 --with-plans --with-comments
--- Comments (3) ---
2026-05-08 12:30 [human:alice]: JWKS endpoint is at /auth/.well-known/jwks.json — tested.
2026-05-08 12:30 [ai:claude-code]: Got it. Should we cache the keys?
2026-05-08 12:30 [human:alice]: Yes — 1hr TTL, re-fetch on key-ID miss.
Organize with labels
backlog label create --project api "security" --color "#e03e3e"
backlog label create --project api "auth"
backlog label attach --task TASK-1 security
backlog label attach --task TASK-1 auth
backlog task list --label auth
Bulk import from a scanner
Create a findings file — suitable for output from security scanners, AI triage agents, or any structured source:
{
"version": 1,
"project": "api",
"items": [
{
"title": "SQL injection in /users search endpoint",
"type": "vulnerability",
"priority": "P1",
"source": "semgrep",
"external_ref": "SEMGREP-001",
"plans": [
{
"title": "Remediation",
"body": "Replace string interpolation with parameterized queries."
}
]
},
{
"title": "Hardcoded credentials in config sample",
"type": "vulnerability",
"priority": "P2",
"source": "semgrep",
"external_ref": "SEMGREP-002"
},
{
"title": "Outdated dependency: golang.org/x/net (CVE-2023-44487)",
"type": "vulnerability",
"priority": "P3",
"source": "dependency-scan"
}
]
}
# Dry run to preview
backlog import-findings findings.json --dry-run
[dry-run] imported 3 tasks · 1 plans · 0 errors
backlog import-findings findings.json --as ai:semgrep
Search and filter
# Full-text search (FTS5)
backlog task list --search "injection"
backlog task list --search "sql*" # prefix match
backlog task list --search "jwt OR csrf" # boolean OR
# Combine filters
backlog task list --project api --type vulnerability --priority P1
backlog task list --actor-kind ai # tasks created by AI agents
backlog task list --source semgrep # tasks from a specific tool
backlog task list --status doing # in-progress only
Export
backlog export --format json # machine-readable
backlog export --format csv --out tasks.csv # spreadsheets
backlog export --format md # paste into PRs / reports
Open the web UI
The embedded web UI runs entirely from the binary — no additional setup:
backlog web # opens http://localhost:8080 in browser
backlog web --port 3000 # custom port
backlog web --port 3000 --no-browser # don't auto-open
The web UI provides list, Kanban, and grid task views, versioned docs, memory entries, attachments, and an activity timeline. All API endpoints are also usable directly — see the API reference.
Connect an AI assistant
Start the MCP stdio server so an AI coding assistant can read and write your backlog directly — without CLI invocations:
backlog mcp serve --as ai:claude-code
BACKLOG_DB so the server always finds the right workspace — see the MCP guide.