cd /news/developer-tools/pinto-a-git-native-scrum-backlog-and… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-60977] src=dev.to β†— pub= topic=developer-tools verified=true sentiment=↑ positive

pinto: A Git-Native Scrum Backlog and Kanban Board for Your Terminal

A developer released pinto, a Git-native Scrum backlog and Kanban board that runs entirely in the terminal. The tool stores backlog items as plain Markdown files with TOML frontmatter, enabling teams to track changes with git diff, merge via pull requests, and work without a server or hosted database. pinto supports Scrum artifacts like Product Backlog Items, Sprints, and Kanban, and is built as a Rust binary available from crates.io.

read8 min views1 publishedJul 15, 2026

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.

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:

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.

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"
+++


Investigate, verify, and fix the current Windows CI failure while
keeping Windows as a supported target.


- [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:

git diff

.git log

and process data with tools such as grep

.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 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.

Consider a team building a login flow. The examples below use actual pinto output.

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

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.

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.

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:

--dry-run

executes the plan against an --json

reports every command as valid

, succeeded

, failed

, or skipped

, 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.

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.

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.

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.

── more in #developer-tools 4 stories Β· sorted by recency
── more on @pinto 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/pinto-a-git-native-s…] indexed:0 read:8min 2026-07-15 Β· β€”