cd /news/developer-tools/a-todo-txt-shared-by-a-human-and-ai-… · home topics developer-tools article
[ARTICLE · art-64045] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

A todo.txt shared by a human and AI agents: why plain text beat a SaaS board for my workflow

A developer replaced a SaaS task board with a plain-text todo.txt file that both they and their AI coding agents read and write. The file uses a simple format with priority, dates, project tags, and context tags, and is managed via a small CLI and cron job. The setup eliminates API dependencies and provides a shared surface for human-plus-agent workflows.

read7 min views1 publishedJul 17, 2026

If you have tried to give an AI coding agent access to your task board, you have probably hit the wall I did: the board lives behind an API, and the agent lives in your repo. Here is the low-tech surface I use instead, where both of us read and write the same file.

I maintain a fleet of small OSS projects. The cross-cutting "what do I do next" list used to live in my head, then in a SaaS board, then nowhere useful. What finally stuck is embarrassingly low-tech: a single todo.txt

in todo.txt format, plus a few dozen lines of dependency-free shell and Python around it.

The twist is that I'm not the only one reading and writing that file. My AI coding agents read it, grep it, and append to it too. Same file, same format, no API in between. This post is about why a plain-text board turned out to be the right shared surface for a human-plus-agents workflow, and what the moving pieces actually are.

What you'll learn:

todo.txt

is a better shared surface for human-plus-agent work than a hosted boardThere are only three things, and the file is the important one.

todo.txt

— the source of truth Every open task is one line. Priority in parentheses, a creation date, the description, a +project

tag, an @context

tag, and an optional due:

in ISO format:

(A) 2026-01-10 add CSV export to the reports page +myapp @dev due:2026-01-15
(B) 2026-01-09 write onboarding docs +docs-site @writing
2026-01-08 investigate flaky auth test +myapp @dev due:2026-01-20

That's the whole schema. (A)

(C)

is priority (A first), +project

names the repo, @context

is the kind of work (@dev

, @review

, @ops

, @writing

, ...), and due:YYYY-MM-DD

is the deadline. Because dates are ISO, plain string comparison sorts them correctly — the sort itself needs no date parsing at all (relative dates like due:+3d

are resolved to an absolute ISO date once, at write time).

Completed tasks don't clutter the board. A done

command moves the line, prefixed with x

and a completion date, into a separate done.txt

archive.

A tiny CLI (todo.sh

— pure bash over coreutils; the gantt and issue views shell out to a small dependency-free Python script) is the front door:

todo.sh                 # today: overdue + due-today + priority-A
todo.sh week            # deadlines within 7 days
todo.sh all             # everything, sorted by priority then due date
todo.sh ls +myapp       # filter by project or any substring
todo.sh add "(A) add CSV export +myapp @dev due:+3d"
todo.sh done "CSV export"

Two conveniences that pull their weight: add

accepts relative due datesdue:today

, due:tomorrow

, due:+3d

, due:+2w

, due:fri

— and rewrites them to an absolute ISO date before saving, so the stored file stays unambiguous. And add

stamps the creation date for you. The query and display path is mostly grep

, awk

, and sort

over one text file.

A single crontab line runs a rollup

command once a night (22:00, in my case):

0 22 * * * /path/to/todo.sh rollup >> rollup.log 2>&1

rollup

reads the board and writes a dated Markdown digest — daily/2026-01-12.md

— with counts (open / overdue / due-today / this-week) and each bucket listed out. It's idempotent: run it again and it just regenerates the same day's file, so if the machine was asleep at 22:00 I can regenerate the current day by hand (or my agent does it at the start of a session). No state, no database — the digest is a pure function of todo.txt

.

The rollup also appends an ASCII Gantt chart. A separate gantt

command renders the board's start:

due:

ranges two ways: ASCII in the terminal, and a Mermaid diagram written to gantt.md

that renders on GitHub, in Obsidian, or on mermaid.live. The Gantt is a view, never a second copy of the data — tasks without a due:

simply don't appear.

For "leave it open and add/complete on the spot," there's a full-screen curses TUI (todo-tui.py

). It imports nothing but the Python standard library — curses

, os

, re

, sys

, unicodedata

, datetime

. No pip install, ever.

It shows todo.txt

live and, crucially, watches the file's mtime: if todo.sh

, cron, an agent, or a phone app rewrites the file, the TUI reloads automatically. a

adds, d

/Enter

completes, e

edits a line in place, /

filters, and Tab

cycles between the list, the Gantt view, and an issues view. I keep it pinned in a dedicated tmux

pane.

Because it's the same todo.txt

underneath, nothing about the TUI is privileged. It's just one more editor of the file.

Here's the part that made this click for a human-plus-AI setup.

An AI coding agent already has three verbs that work perfectly on a text file: Read, Edit, and Grep. A todo.txt

needs no adapter, no MCP server, no OAuth dance, no rate limit. The agent opens the file the same way it opens any source file in the repo, and it understands the format after seeing it once because the format is self-evident — it's just lines.

Compare that to a SaaS board. To let an agent touch a hosted kanban you need an integration, credentials, and a network round-trip — and interactive-auth integrations are exactly the thing that tends to be missing in headless contexts: a cron job, a scheduled agent, a CI run. A plain file in the repo is always reachable, from every one of those contexts, with zero setup.

Plain text buys you three more things for free:

git log

on one file.+myapp

?" is grep +myapp todo.txt

, for me and for the agent identically.The format being boring is the feature. There's no layer where the human's mental model and the agent's mental model can drift apart, because there's no layer at all — just the file.

The day-to-day loop is the payoff. In the middle of a coding session I say something like "add a task to ship the CSV export by Friday," and the agent runs:

todo.sh add "(A) ship CSV export +myapp @dev due:fri"

The relative due:fri

becomes a concrete date, the line lands in todo.txt

, and the TUI in my other pane redraws a second later because its mtime watch fired. When the work is done, "mark the CSV export done" becomes todo.sh done "CSV export"

and the line moves to the archive. Nothing I say has to be structured; the agent knows the schema and fills it in.

There's no lock and no coordination protocol, and yet the human, the CLI, the cron job, and the TUI never fight, because there's exactly one writer pattern — append a line, or filter-and-rewrite — over one small file, and the TUI treats the file as the truth rather than caching its own copy. "Just say it and it's on the board" isn't a feature anyone built; it falls out of everyone sharing the same plain-text file.

When your collaborators are AI agents, the interface you share with them matters more than the features of any one tool. A hosted board optimizes for a human clicking a UI. A todo.txt

optimizes for anything that can read a file — you, your shell, a cron line, a phone app, and an LLM agent — participating on equal footing with no integration in between.

Pick the substrate your agents can already touch. For a task list, that substrate is a plain-text file, and the whole rest of the system is a few dozen lines of dependency-free glue.

This is part of a series on human-AI collaboration patterns. Two companion pieces — one on the collaboration "shape" I use with coding agents, and one on a "don't decide too early / keep options live" discipline — are still in the drafts and will link here once published.

The board conventions and the CLI/TUI behavior described here are taken from the actual tooling (a README.md

spec, a small bash CLI, and a dependency-free curses TUI). All task examples in this post are fictional; the real board's contents are omitted.

── I run a suite of self-hosted business tools in production. I take on consulting for legacy modernization and shared-hosting constraints. Contact: github.com/hideyukiMORI

── more in #developer-tools 4 stories · sorted by recency
── more on @todo.txt 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/a-todo-txt-shared-by…] indexed:0 read:7min 2026-07-17 ·