pinto lets teams manage Scrum backlogs as plain text.
Every backlog change can be inspected with git diff, carried across a branch, merged, and reviewed in a pull request—just like source code. The backlog follows the same lifecycle as the product it describes.
pinto is local-first: no server, account, or hosted database is required. It works with AI agents, but never depends on them. And unlike a generic CLI to-do list, its core model is Scrum: Product Backlog Items (PBIs), Sprints, Kanban, and the metrics teams use to inspect and adapt.
Why pinto exists
Jira, Asana, and Notion are capable products. But as more features accumulate, the process can start serving the tool instead of the other way around:
- Creating one ticket means navigating required fields and workflow settings.
- Running a Sprint begins with configuring permissions, automations, or dashboards.
- Even a small status change feels expensive when the tool is slow to open.
Scrum is meant to be a lightweight framework for rapid inspection and adaptation. When maintaining the board becomes work in its own right, the tooling has lost sight of that goal.
The name pinto comes from the Japanese word ピント “focus.” That is also the design intent: keep the team's attention on the Product Backlog, the Sprint, and the work flowing across the board.
pinto deliberately stays small. It starts quickly, keeps dependencies and vocabulary limited, stores durable data as readable files, and excludes project-suite features such as Gantt charts and CRM.
Your backlog belongs in the repository
Running pinto init creates a .pinto/ directory beside your code. Each PBI is a Markdown file with TOML frontmatter. Here is a real item from pinto's own backlog:
+++
id = "P-2"
title = "Investigate and fix Windows CI while retaining Windows support"
status = "done"
rank = "j"
labels = ["ci", "windows"]
created = "2026-07-15T06:24:58.731847Z"
updated = "2026-07-15T09:34:50.653786Z"
+++
# Summary
Investigate, verify, and fix the current Windows CI failure while
keeping Windows as a supported target.
# Acceptance Criteria
- [x] The root cause is documented.
- [x] The Windows build and tests pass on windows-latest.
Because the backlog is made of ordinary files, your existing engineering workflow applies to it:
- Review changes with
git diff. - Branch the backlog with the code that changes it.
- Discuss backlog updates in pull requests.
- Recover history with
git logand process data with tools such asgrep.
pinto can also link commits to PBIs (pinto link add / pinto link scan), keep a shared Definition of Done (pinto dod), and record dependencies (pinto dep). None of that requires a separate service.
“Git-native” does not mean Git is mandatory. The default file backend works without it. It means the data format can participate naturally in a Git workflow whenever the project does.
Install it
Install the native Rust binary from crates.io:
cargo install pinto-cli
Building from source requires Rust 1.89 or later; the commands are available in the repository README.
See the Scrum workflow in 90 seconds
Consider a team building a login flow. The examples below use actual pinto output.
Shape the backlog and plan a Sprint
Initialize the board and add a handful of PBIs:
pinto init
pinto add "Design the login form" --points 3 --label ui --label auth
pinto add "Implement the login API" --points 5 --label api --label auth
pinto add "Write onboarding docs" --points 2 --label docs
pinto add "Fix the session timeout bug" --points 1 --label bug --label auth
pinto add "Refactor the storage layer" --points 8 --label refactor
pinto list
T-1 todo Design the login form (3) [ui, auth]
T-2 todo Implement the login API (5) [api, auth]
T-3 todo Write onboarding docs (2) [docs]
T-4 todo Fix the session timeout bug (1) [bug, auth]
T-5 todo Refactor the storage layer (8) [refactor]
Each line keeps the essential context visible without opening a detail page. Rank controls Product Backlog order, so changing priority is as direct as pinto reorder T-4 --top.
Now pull the three highest-ranked items into a two-week Sprint:
pinto sprint new S-1 "Sprint 1" --goal "Ship the login flow" \
--start 2026-07-13 --end 2026-07-27
pinto sprint add S-1 --status todo --limit 3 # Add the top three ranked PBIs
pinto sprint start S-1
Created sprint S-1 Sprint 1
Assigned T-1 to sprint S-1
Assigned T-2 to sprint S-1
Assigned T-3 to sprint S-1
Started sprint S-1
Move the work
The move command takes the destination last, like Unix mv; mv is also an alias.
pinto move T-1 in-progress
pinto move T-2 in-progress
pinto move T-1 done
pinto board
todo (3)
T-3 Write onboarding docs
T-4 Fix the session timeout bug
T-5 Refactor the storage layer
in-progress (1)
T-2 Implement the login API
review (0)
(empty)
done (1)
T-1 Design the login form
Teams can define WIP limits in .pinto/config.toml. For a more interactive workflow, pinto kanban opens a terminal UI where you can move cards, edit them in $EDITOR, and manage dependencies and parent-child relationships.
Inspect and adapt
During the Sprint, pinto sprint burndown S-1 renders progress directly in the terminal:
S-1 Sprint 1 - burndown (points)
Period 2026-07-13 → 2026-07-27 · total 10
█ remaining ┆ ideal
2026-07-13 │███████████████████████████████████████████████████████████████┆│ 10
2026-07-15 │████████████████████████████████████████████░░░░░░░░░░░┆░░░░░░░░│ 7
2026-07-17 │████████████████████████████████████████████░░┆░░░░░░░░░░░░░░░░░│ 7
...
2026-07-27 │┆███████████████████████████████████████████░░░░░░░░░░░░░░░░░░░░│ 7
The same Scrum model can estimate capacity before the team commits to the Sprint:
pinto sprint capacity S-1 --daily-hours 8 --holidays 1 --deduction-factor 0.2
Once the remaining PBIs are done, close the Sprint and inspect velocity, cycle time, and lead time:
pinto move T-2 T-3 done
pinto sprint close S-1
pinto sprint velocity
pinto cycletime --sprint S-1
Closed sprint S-1
Velocity (last 5 sprints)
S-1 10 points completed: 3 unestimated: 0 incomplete: 0
Average: 10.0 points
Cycle/Lead time - 3 completed
cycle (start → done) n=3 mean 4s median 0s min 0s max 14s
lead (created → done) n=3 mean 36s median 41s min 26s max 41s
This board was created in under a minute, which is why the timing values are measured in seconds. A real project reveals the distribution across days and builds a useful velocity trend over successive Sprints.
The point is not the number of commands. It is that backlog refinement, Sprint execution, and inspection all happen without leaving the repository or the terminal.
Safe automation, with or without AI
Most read-only commands support --json. For writes, pinto provides pinto automate, a deliberately narrow boundary for agent-driven changes.
automate accepts a structured JSON plan made of argument arrays. Three properties make that boundary reviewable:
- Plans contain validated argv, not shell code. They are never passed to a shell, so there is no shell-injection path.
-
--dry-runexecutes the plan against an isolated copy of the board without modifying the real one. -
--jsonreports every command asvalid,succeeded,failed, orskipped, together with created and updated item IDs.
Imagine asking a coding agent:
Read the backlog and propose a pinto plan for a two-week Sprint starting next week. Show me a dry run before applying anything.
The agent first reads the current backlog:
pinto list --status todo --json
It then writes a plain, human-reviewable plan.json:
{
"commands": [
["sprint", "new", "S-2", "Sprint 2",
"--goal", "Harden auth", "--start", "2026-07-28", "--end", "2026-08-11"],
["sprint", "add", "S-2", "T-4"],
["sprint", "add", "S-2", "T-5"],
["sprint", "start", "S-2"]
]
}
Before applying it, the agent validates the plan:
pinto automate --plan plan.json --dry-run --json
{
"status": "dry_run",
"dry_run": true,
"commands": [
{
"index": 1,
"command": "sprint new",
"status": "valid",
"created_ids": [],
"updated_ids": [],
"error": null
},
{
"index": 2,
"command": "sprint add",
"status": "valid",
"created_ids": [],
"updated_ids": ["T-4"],
"error": null
},
{
"index": 3,
"command": "sprint add",
"status": "valid",
"created_ids": [],
"updated_ids": ["T-5"],
"error": null
},
{
"index": 4,
"command": "sprint start",
"status": "valid",
"created_ids": [],
"updated_ids": [],
"error": null
}
]
}
A human reviews plan.json or the dry-run result and removes --dry-run only when the proposal is sound. The agent's suggestion and its application to the board are separated by a reviewable artifact. That artifact can even travel with a pull request.
The same mechanism works for incident triage. An agent can turn a postmortem into a reviewable set of follow-up PBIs:
{
"commands": [
["add", "Add retry to the session refresh job",
"--points", "2", "--label", "bug", "--label", "auth"],
["add", "Alert on refresh failure rate",
"--points", "3", "--label", "ops",
"--body", "Threshold and runbook link are in the postmortem."],
["add", "Document the session lifecycle",
"--points", "1", "--label", "docs"]
]
}
Because add supports --body and --template, the plan can create useful PBIs without opening an editor. Long or multiline plans can be passed as files or through standard input (--plan -), while the team retains the same validation boundary.
Storage backends
Plain files are the default. Two other backends are available when a project needs different persistence:
pinto migrate --to git
The Git backend creates one commit per complete write operation. It uses a temporary index to isolate existing working-tree changes, so uncommitted code does not leak into a board commit. For agent-driven edits, that produces a precise, operation-by-operation audit trail.
An optional SQLite backend is available behind a Cargo feature flag for teams that prefer a single-file database.
How pinto differs from Backlog.md
If this sounds familiar, take a look at Backlog.md. It is an excellent Markdown-native project manager with a terminal board, a local web UI, search across tasks and project knowledge, and agent workflows through CLI instructions or MCP.
pinto learned from that approach but deliberately chose a narrower scope:
| Area | Backlog.md | pinto |
|---|---|---|
| Primary focus | Tasks, specs, docs, and decisions | Product Backlog, Sprints, and Kanban |
| Persistent data | Markdown files | Markdown with TOML frontmatter |
| Scrum reporting | Not the core model | Capacity, burndown, velocity, cycle/lead time |
| Interactive UI | Terminal board and local web UI | CLI and terminal TUI |
| Agent workflow | CLI instructions or optional MCP | Validated JSON plans with isolated dry-run |
| Runtime | TypeScript/Bun | Native Rust binary |
This is a difference in purpose, not a claim of superiority. Choose Backlog.md when you want a broad workspace for tasks, specifications, documents, decisions, and agents. Choose pinto when the job is to run Scrum with the smallest practical tool.
Final thoughts
pinto exists to keep the backlog close to the work: local, readable, reviewable, and governed by the same engineering habits as the code.
Clarity, Simplicity, and Humanity.
With or without AI.
If that is how you want to practice Scrum, give pinto a try. Issues and pull requests are welcome.
Top comments (0)