Guides

Plan files you can actually check off

Your agent writes a task list. Ticking a box should edit the file — not open an editor, and not live only in your head.

Updated September 4, 2026

Ask an agent to plan something before it starts and you get back a Markdown task list. It is the natural format: ordered, nested, human-readable, and something both of you can edit. It is also only one of the .md files an agent leaves behind, and the one most worth keeping open.

## Migration plan

- [ ] Audit current callers of `renderDocument`
- [ ] Add the new signature behind a flag
  - [ ] Unit tests for the flag path
  - [ ] Backfill the snapshot fixtures
- [ ] Migrate callers one package at a time
- [ ] Remove the flag

Then you start working through it, and the file stops being useful. You finish the audit. Now what? You either open the raw source in an editor and change three characters, or you keep the state in your head, or you tell the agent what you did and hope it updates the file. All three are worse than the plan deserves.

The file is the shared state

This is the part worth being deliberate about. When you work with an agent, the plan file is not a document about the work — it is the interface between you and the agent. It is the thing the agent reads at the start of the next session to find out where you left off. It is what you point at when you say “skip the third one, I did it by hand”.

Which means a checkbox that is only ticked in your head is a lie the agent will act on. And a checkbox you have to open an editor to tick is friction sitting directly in the loop you most want to be fast.

The useful behaviour is narrow and specific: click a checkbox in the rendered document, and the underlying .md file changes on disk. Nothing else about the file moves.

Task list syntax, briefly

Task lists are a GitHub Flavored Markdown extension, not part of original Markdown, which is why support varies so much between tools. The rule is a list item whose content starts with a bracket pair:

- [ ] not done
- [x] done

Three details catch people out:

  • The space inside the empty brackets is required. - [] is an ordinary list item containing empty brackets, not a checkbox.
  • The space after the brackets is required too. - [x]done will not parse as a task.
  • It must be a list item. A bracket pair in a paragraph is just text. Any of -, * or + works as the marker, and numbered lists work as well.

Nesting works by indentation, and nested tasks are independent — checking a parent does not check its children, and no renderer computes progress for you. If you want a count, the agent has to write one.

Why so few tools write the change back

Rendering a checkbox is easy. Making it clickable and having the click reach the file is where the work is, because the renderer has to hold on to a mapping it usually throws away.

Markdown rendering is lossy in the direction you need. A parser turns source text into a tree, and the tree knows the document structure but typically not which byte range of the original file each node came from. Toggling a checkbox means going backwards: from “the fourth checkbox in the rendered view” to “line 9, column 3 to 6 of the source”. Get that mapping wrong by one line and you tick the wrong item — or corrupt a list.

It has to survive the things real documents do. Mixed markers in one file. Task lists inside blockquotes. Items whose text wraps across lines. Indentation with tabs. And the file may have been rewritten by an agent between the moment it was rendered and the moment you clicked, which means a naive line-number cache is a corruption bug waiting to happen.

The safe approach is to re-read the file at the moment of the click, locate the item, rewrite only the two characters between the brackets, and leave every other byte — including line endings and trailing whitespace — exactly as it was. A task toggle should produce a one-character diff, not a reformatted document.

The workflow this unlocks

Once ticking a box is free, the plan file becomes something you actually use rather than something you read once:

  1. The agent writes the plan and starts work.
  2. You read it rendered, using the outline to see the shape of it, while the agent keeps writing — the document updates underneath you as it goes.
  3. You verify a step yourself and tick it. The file changes.
  4. The agent picks the file back up in the next session and sees exactly which steps are genuinely done, because the state was never anywhere but the file.

The important property is that no second system holds the truth. Not a checklist app, not the conversation history, not your memory. Just the .md file, which is also the thing that gets committed and code reviewed.

How nicemd does it

nicemd renders GitHub Flavored Markdown through cmark-gfm, and task lists in the reading view are clickable. Clicking one writes the change back to the file — a single character, in place, with the rest of the document untouched.

It works in the free reading mode, so you do not need to unlock editing to keep a plan up to date. And because nicemd reloads correctly when another tool rewrites the file, you and your agent can both be writing to the same plan without either of you clobbering the other's view of it.

For the wider workflow around agent-written documents, see reading the Markdown your coding agent writes.