DEV Community

Cover image for My coding agents don't need a project management tool. They need markdown files.
Anojan Stelarani Thirukeetheeswaranathan
Anojan Stelarani Thirukeetheeswaranathan

Posted on AI-assisted

My coding agents don't need a project management tool. They need markdown files.

My coding agents used to read their tasks from a hosted tracker. They never needed one. They needed a folder of markdown files, and I needed a small board to look at them.

This is how I worked that out, and the tool that came from it: board.md, a local board for the markdown task files already in your repo.

Where I started: a hosted tracker, an MCP server, and a limit

I was about to pay for a database when the only reader of the data was an agent that reads text.

I run several projects with coding agents. The tasks lived in Notion, on the free plan, and the agents pulled task details through its MCP server. It worked. But with a few projects I was close to the free plan's limit, and the next step would have cost me about $40 a month. It would have gone the same way with Jira, Monday or ClickUp: the limit and the price differ, the problem doesn't.

Before paying, I looked at what the agents actually did with a task. They read the title, the notes and a few fields. Then they changed a status. That was all.

What an agent needs from a task tracker

An agent needs a file it can read and edit. One markdown file per task, in the repo, with the fields in YAML frontmatter and the notes below:

---
id: DEMO-4
title: "Projects CRUD"
status: todo
phase: P2
module: projects
priority: P0
size: M
branch:
pr:
---

# DEMO-4 Projects CRUD

Soft delete. Names unique per account, ignoring case.
Enter fullscreen mode Exit fullscreen mode

That format beats a hosted tracker for an agent in four ways:

  • No API. The task is in the same checkout as the code. There is no token, no network call and no rate limit.
  • It ships with the work. The pull request that builds the task also sets its status, so the board on main always shows what is merged.
  • It gets reviewed. A changed status is a line in a diff, like everything else.
  • History is free. git log on the file is the task's history.

One of my projects already worked this way, with 88 task files. The agents were happy. I was the problem.

What I needed: a board

I needed to see 88 files as columns and drag a card from one to the next. Nothing more.

My first plan was something bigger, with a database behind it. I didn't need any of that: the files were already the database. The markdown kanban tools I looked at each wanted their own file layout, and I didn't want to convert files my agents already understood.

So board.md reads the files you have. npx boardmd init looks at them and works out a config: the id format, the statuses, which fields become badges or filters. npx boardmd serve shows the board on localhost.

[image: Demo: a card dragged from Todo to In progress changes one line in its file; boardmd new creates a task and its card appears on the board]

Status you don't have to maintain

"In progress" and "in review" are not written in any file. The board reads them from git each time it loads.

  • A local branch named for a task, like task/demo-4-projects-crud, shows that task as in progress.
  • An open pull request shows it as in review, labelled draft, approved or changes requested.
  • A merged pull request whose file still says todo gets a badge, so you can see the file is behind.

This matters most with agents. My agent creates a branch, does the work and opens a pull request. The card moves across the board by itself, and nobody edits a status until the pull request sets it to done.

The one-line diff

When I drag a card, exactly one line of one file changes:

-status: todo
+status: in-progress
Enter fullscreen mode Exit fullscreen mode

This is the rule the tool is built around. The files belong to the agents and to code review. A board that re-serialises the YAML reorders keys, changes quotes and turns a status change into a noisy diff that conflicts with the next branch.

So a drop does very little, on purpose:

  1. The page sends the new status with a hash of the file as it last saw it.
  2. If the file changed on disk since then, nothing is written and the card reloads.
  3. Only the value on the status: line is replaced. The key, spacing, quotes, any comment and the line ending stay as they were.
  4. The file is written to a temporary file and renamed over the original.

A file with no status: line is refused, not given one. The board never commits or pushes; a banner lists the files you changed so you can.

Agents are users too

An agent gets the same guarantees as the board, through four commands.

Command What it guarantees
boardmd list --json Every open task with its fields, its file and its live state from git.
boardmd new "<title>" --set phase=P2 The next id, the right folder and file name, and frontmatter in the same order as the other files.
boardmd set DEMO-4 status=done pr=41 Only those lines change. It warns if git shows the task in progress or in review.
boardmd check Every file is validated: ids, file names, folders, required fields, allowed values.

Before these existed, creating a task meant the agent guessed the next id, the folder and which fields to fill. Now a wrong guess gets an answer it can act on:

$ npx boardmd new "Half a task" --set priority=P9
Can't create the task: priority must be one of: P0, P1, P2; set phase (P1, P2),
module, size (S, M, L) with --set <field>=<value>.
Enter fullscreen mode Exit fullscreen mode

An agent also can't use a tool it doesn't know is there. So boardmd init offers to add a short section to CLAUDE.md or AGENTS.md, and a Claude Code skill. Both point at boardmd guide, which prints this repo's own rules from the config: where tasks live, the next id, the allowed values for each field and how branches are named.

For Claude Code there is also a plugin. /plugin marketplace add anojanst/board.md, then /plugin install boardmd@board-md, adds /boardmd:setup to set a repo up and /boardmd:board to open its board.

Try it

Three commands, from the root of a repo that has task files:

npm install --save-dev board.md
npx boardmd init
npx boardmd serve --open
Enter fullscreen mode Exit fullscreen mode

init shows what it found and asks before writing anything. With no task files yet, it offers to create a tasks/ folder with an example. You need Node 20 or later. git and the GitHub CLI are optional: without them the board works, just without branch and pull request state.

It is free and open source (MIT): npm, GitHub.

What it doesn't do

board.md is deliberately small, and these are the edges:

  • One person, one machine. It serves on localhost. There are no accounts and no hosting.
  • GitHub only for pull requests. That state comes from the GitHub CLI. Branch state works with any git repo.
  • The board edits status only. Other fields change through boardmd set, or in your editor.
  • It never runs git for you. No commits, no branches, no pushes.

If a team needs comments, assignments and reports, a hosted tracker earns its price. If your agents already keep tasks in markdown, point board.md at them and tell me what breaks.

Top comments (1)

Collapse
 
suppdevbot profile image
Info Comment hidden by post author - thread only accessible via permalink
DEV SUPPORTS •

You need to verify your account.

Enter fullscreen mode Exit fullscreen mode

tr.ee/dev-to

Some comments have been hidden by the post's author - find out more