Your markdown tickets as a kanban board, for any git repository
Tickets are agent-driven, so the agent moves the card. Read-only by choice.
npx scratchboard
npx scratchboard reads the markdown tickets already in your repo, maps them to lanes, and
opens a board in your browser. One self-contained HTML file in your temp directory. No config,
no dependencies, nothing written back to your repo.
There is no drag and drop and no write-back. Tickets are agent-driven, so the agent moves the card. This keeps your current flow safe.
npx scratchboard # the board
npx skills add darecstowell/scratchboard # the skill, for the setup that needs judgmentNode 18 or later.
One board, two themes. Both are the tickets in this repo, not a fixture.
Live demo: darecstowell.github.io/scratchboard
is this repo's own backlog, baked by this repo's own scratchboard on every push to main.
Run it in a repo with no config and it does three things.
- Finds your tickets. It checks
.scratch/,.tickets/,docs/issues/,issues/, andtasks/, then any other directory holding three or more markdown files it can read. YAML front matter and a plainKey: valueblock both need no setup. - Maps them to lanes. Folders first, so
todo/,in-progress/, anddone/become the lanes in that order. With no folders to go on it uses a status field. Any other metadata whose values repeat becomes a filter chip. - Bakes one HTML file and opens it. It lands in the OS temp directory, so nothing shows up
in
git status. That file travels too. Attach it to a pull request, or drop it in a chat.
Search, filters, and sort live in the URL hash, so a filtered board is a link you can send. Two
themes ship, latte and phosphor.
To keep the guess, the first run offers to save it and scratchboard init writes it any time.
Both write scratchboard.json at the repo root. Commit it and later runs skip detection.
--serve keeps the board open and reloads it when the files change. Leave it on a second
monitor while an agent works the tickets underneath you, and the cards move on their own.
npx scratchboard --serveEvery key is optional, and anything you leave out comes from detection. A lane is a match rather than a location, so a ticket never gets moved to join one.
{
"title": "Roadmap",
"tickets": ".scratch/**/issue.md",
"format": "yaml-frontmatter",
"idPattern": "^(\\d+)-",
"lanes": [
{ "name": "Todo", "match": { "path": ".scratch/todo/**" } },
{ "name": "In progress", "match": { "path": ".scratch/in-progress/**" } },
{ "name": "Done", "match": { "path": ".scratch/done/**" }, "collapsed": true }
],
"facets": [
{ "field": "priority", "icon": "alert", "colors": { "p0": "red", "p1": "amber", "p2": "cyan", "p3": "neutral" } },
{ "field": "labels" }
]
}A priority of p0 to p3, or of critical to low, is ranked and coloured with no config at
all, and so is a status. Naming colors or order yourself replaces the default. Detection
leaves a vocabulary it does not recognise alone rather than guessing at it.
Every key, every flag, the glob tokens, the lane and facet rules, the icon set, and what
detection does in full: docs/reference.md.
The CLI is the whole tool. The skill is for the part that needs judgment: looking at a repo full of tickets and deciding what the lanes should be.
npx skills add darecstowell/scratchboardIt has three jobs, and none of them is narrating a command you could have run yourself.
- Ask where the tickets live, and confirm the glob against real files.
- Read the detection report and correct the lane mapping. Tickets sitting in the trailing
Unmappedlane are the signal. - Write a parser when neither preset reads your format.
It writes only scratchboard.json and scratchboard.parser.mjs, it asks before each, and it
never touches a ticket. SKILL.md follows the agentskills.io format,
so Claude Code, Codex CLI, Cursor, Windsurf, Copilot, Amp, and Gemini CLI all read it.
Neither preset reads your format? A module of about 30 lines covers it, and nothing else in the config changes.
// scratchboard.parser.mjs
export function parse(path, text) {
return { id, title, body, fields };
}The only boundary is one line: the body has to be markdown, because the board renders it. The
metadata format is fully open, and fields is untyped, so your own severity or team field
works with no code change. See the
full contract, or let the skill write it.
Scratchboard is not a task manager. It does not create tickets, move them, or edit their front matter. It owns no directory and no file format. It reads the layout your repo already has and draws a board from it.
Backlog.md leads this category and it earns the lead: a
CLI that creates and edits tasks, a web UI with drag and drop, a terminal board, MCP for agents,
and a backlog/ folder it owns end to end. If you want a task manager that owns your files,
use Backlog.md. It will serve you better than this will.
Scratchboard is for the other case. Your tickets already exist, in a shape you picked, and you want a window onto them.
- No write-back, no drag and drop. Tickets are agent-driven, so the agent moves the card.
- One board per config. A second board means a second config file, on purpose.
- No single-file
TODO.mdformat. One ticket is one file. If you keep everything in one file, md-kanban handles that shape. - No hosted service, no accounts, no telemetry. The board is one HTML file in your temp directory. Nothing phones home.
- Zero dependencies, and that is a rule rather than a current state.
Two bundled fonts, and palettes derived from a third project. Each notice travels with the files it covers, including the base64 bytes inlined into a baked board.
| What | Licence | Notice |
|---|---|---|
| Spline Sans Mono | SIL Open Font License 1.1 | licenses/OFL-SplineSansMono.txt |
| Martian Mono | SIL Open Font License 1.1 | licenses/OFL-MartianMono.txt |
| Catppuccin | MIT | licenses/Catppuccin-MIT.txt |
| Octicons | MIT | licenses/MIT-Octicons.txt |
The latte and phosphor themes are original palettes derived from Catppuccin rather than
copies of it.
Scratchboard was the internal board on OffMain and turned out to be useful on its own. That repo's ticket tree is the corpus every change here is tested against.
MIT. See LICENSE.

