pastilhasandClaude Opus 5 6968260f54 a mis-pointed project is a sentence, not a 500 reported as a permission problem
the owner pointed a project at the platform's repo root — an easy mistake, since
`todo/` sits inside one — and got "the todo board is owner-only, and this account
was refused". three things were wrong and only one of them was the path.

A THEME IS NOW A DIRECTORY WITH AN `_index.md`. readTree assumed every subdirectory
was one, which was safe when the only possible root was the platform's own todo
folder and is not safe now. against a repo root it read `src/_index.md`, threw
ENOENT, and the route 500'd. skipping non-themes is also just correct for a real
todo folder, which may hold a README beside its themes.

THE ERROR MESSAGE WAS A LIE IT INHERITED. "owner-only, and this account was
refused" was true of `/todos` in the platform, where the permission was
`kind: 'admin'`. here it is grantable and there is no such gate — so the sentence
survived the extraction describing a rule that no longer exists, and the first real
failure it met was reported as a permission problem. it shows the actual error now.
a wrong explanation is worse than none: it sent the owner to check their own
account when the answer was in the panel beside them.

AND AN EMPTY FOLDER SAYS SO. no themes at all is almost always this same mistake,
so it names it — a theme is a directory with an `_index.md`, and if you pointed at
a repository the folder you want is usually `todo/` inside it. an empty board
otherwise reads as "no work outstanding", which is the opposite of the truth.

verified: repo root now 200 with 0 themes and the explanation; the real folder
reads 38 themes and 139 items.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 07:13:29 +01:00

Kanban

A board over a folder of markdown todo files — as many projects as you point it at.

Items are <theme>/<slug>.md with frontmatter and hand-written prose. The files are the truth. This plugin stores no copy of them: its one table is a list of folders, so uninstalling it with "delete its data" ticked loses the list and never a line of anybody's work.

Adding a project

The path is the folder that holds the theme directories — usually todo/, not the repository root. It must be absolute and inside your home; symlinks are resolved before that is checked.

What it does to your files

  • Writes frontmatter only — status, priority, due, order. The body is yours and no route here can touch it.
  • Regenerates TODO.md beside the folder on every write.
  • Never deletes anything. Removing a project removes the row.

Where it came from

/todos in the Officer platform, which read resolve(process.cwd(), 'todo') — one board, found by assuming the server's working directory. The reader, the ordering and the frontmatter handling came across unchanged, with their tests. What changed is that the directory is a setting.

The platform kept its own todo/ folder and scripts/todo-index.ts: that folder is its own backlog, committed with its own code, and the CLI regenerates the index from a terminal with no Officer running. Making the platform's own backlog depend on a plugin being installed would have been the wrong trade.

That leaves two copies of the tree reader — this one, generalised over a root, and the platform's, which serves only that CLI. They will drift. The alternative was worse in both directions, and the honest fix on the day it matters is to delete the platform's CLI and let this own the format outright.

S
Description
A kanban board over a folder of markdown todo files, across as many projects as you point it at.
Readme
63 KiB
Languages
TypeScript 100%