DEV Community

Siekwie
Siekwie

Posted on AI-assisted

I built a small kanban board that my coding agents update with curl

When I work with coding agents I usually have a few things going at once, and after a couple of sessions I no longer know what's finished, what's half done and what's waiting on me. I tried a TODO.md, but I never looked at it. Jira or Linear felt silly for a one-person project.

So I wrote KanbanEasy. It's a small desktop kanban board that I keep docked next to my editor. The part I actually wanted is that the agent can move its own cards.

KanbanEasy board with five columns of cards

The code is on GitHub under the MIT license: https://github.com/Siekwie/KanbanEasy

The agent side

While the app is open it serves a JSON API on 127.0.0.1:7420. I didn't want to set up an MCP server for this. Every agent I use can already run a shell command, so curl is enough:

# take the next free todo
curl -s -d assignee=claude localhost:7420/claim

# leave a comment on a card
curl -s -H 'X-Actor: claude' --data-urlencode body='Tests pass' localhost:7420/issues/KE-7/comments

# hand it back to me for review
curl -s -X PATCH -d status=review localhost:7420/issues/KE-7
Enter fullscreen mode Exit fullscreen mode

If you'd rather not type curl there is a small bash wrapper called kb, so the same things become kb claim claude or kb mv KE-7 review.

To tell an agent about the board, right-click the API line in the sidebar and pick "Copy agent instructions". That gives you a short text block to paste into CLAUDE.md or AGENTS.md.

Columns can have rules

This is the feature I use most. A column can say who gets the cards that land in it, and it can carry instructions for the agent. My Review column, for example, assigns cards to me. You can also do it the other way around: you write your decision in a comment, drop the card into a column that belongs to the agent, and the column's instructions tell it what to do next.

Every card keeps a log of who moved it or changed it, me or the agent. When the agent touches a card, it glows on the board for a moment. I added that as a gimmick and it turned out to be useful, because I notice progress without switching windows.

The human side

I wanted adding a card to cost almost nothing. Press N, type something like Fix flaky test #ci @agent !high and press Enter. The label, the assignee and the priority are read from the title, and the input stays open for the next card.

A card opened in the detail panel

When the window is narrow, the board turns into a stacked list, so it fits in a strip beside the editor. It only redraws when something changes, so it uses almost no CPU while it sits there.

The whole board is one readable JSON file in a KanbanEasy folder in your home directory. There are no accounts and nothing is sent anywhere. The app keeps a backup per weekday, and if you edit the file by hand it reloads.

Is an open local port a problem?

I asked myself the same thing. The server listens on localhost only. It also refuses any request that carries browser headers like Origin, or a Host that isn't local, so a website you have open can't reach it. Other programs running under your user can. That is on purpose, because that's how the agent gets in.

What it's built with

It's written in Lua on LÖVE, which is really a game framework. That sounds like an odd choice for a kanban board, but it starts instantly, and I genuinely think it is just an underrated piece of technology.

Try it

Builds for Windows, macOS and Linux are on the releases page. The macOS build isn't signed, so you have to right-click and choose Open the first time.

It's still young and I'm sure there are rough edges. If you run agents on your own projects, I'd like to know what you would want from a board like this, and whether the API makes sense to you.

Top comments (3)

Collapse
 
launchgatecheck profile image
Launch Gate •

The claim endpoint is a useful fit for multiple agents. I'd test it with one free card and two simultaneous claims, then a late status update from an agent whose assignment has changed. Exactly one claim should win, and the stale update shouldn't move a card that is now back with the human. Returning a card revision or claim token and requiring it on updates would make that boundary visible to the caller. Does /claim reserve the card atomically, and can a PATCH detect that ownership changed since the agent read it?

Collapse
 
siekwiedev profile image
Siekwie •

Thanks, this is a fair test. /claim is atomic because the server handles one request at a time on the main loop. Two simultaneous claims on one free card can't both win: the second finds nothing left in todo and gets a 404 (or the next free card). I only had a sequential test for it, though, not a truly concurrent one.

The stale update was a real gap. PATCH had no revision or ownership check, so an agent that was reassigned could still move the card. I like the revision idea, so I'm adding it now: /claim and GET return a rev, and PATCH accepts an optional If-Match and returns 409 on a mismatch. It stays optional so the plain curl flow still works. Thanks for the specifics.

Collapse
 
siekwiedev profile image
Siekwie •

Shipped an update already, check it out if you like: github.com/Siekwie/KanbanEasy/rele...