Files
kanban/manifest.ts
T
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

65 lines
2.7 KiB
TypeScript

import type { PluginManifest } from '@@/plugins/manifest';
/**
* Kanban — a board over a folder of markdown files.
*
* ── What it was ──
*
* `/todos` in the platform: a board, an API and a tree reader, all pointed at
* `resolve(process.cwd(), 'todo')` — the platform's own todo folder, found by assuming the server's
* working directory. It worked, for exactly one project, on exactly one checkout.
*
* ── What changed in the extraction ──
*
* One thing, and everything else was carried across untouched: **the directory is a setting**. A
* project is a name and a path, there can be as many as you like, and the board asks which one you are
* looking at. The frontmatter reader that never rewrites a body, the ordering, the generated index —
* all of it came over as it was, and its tests came with it and still pass.
*
* ── It stores no items ──
*
* The files on disk are the truth. This plugin's only 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. That is the same
* property the markdown format was chosen for: readable, diffable and editable without Officer.
*
* ── What stayed in the platform, and why it is a seam rather than a loose end ──
*
* `scripts/todo-index.ts` and the platform's own `todo/` folder. That folder is the platform's own
* content — its deferred work, in its own repository, committed with its own code — and the CLI is how
* it is regenerated from a terminal with no Officer running. Moving either would have made the
* platform's own backlog depend on a plugin being installed.
*
* So the platform keeps its folder; this plugin points AT it as one project among however many.
*/
export const manifest: PluginManifest = {
publisher: 'officerdev',
version: '2026.08.29.02',
platform: '>=1.0.0',
label: 'Kanban',
summary: 'A board over folders of markdown todo files — as many projects as you point it at',
tags: ['Development'],
icon: 'SquareKanban',
color: '#8b5cf6',
// Nothing to declare. It reads and writes markdown with node's own fs; there is no binary on the
// path and no service to reach.
permissions: [
{
key: 'kanban',
label: 'Kanban',
description: 'Read and edit todo boards over folders you have added',
/*
Which FOLDERS exist on the machine is an owner's decision; moving a card is not.
Adding a project points this plugin at a directory and is therefore a statement about the
filesystem — the same class of decision as av-club's root location. Prefix-matched, so
`/projects/<id>` is covered by the same rule as `/projects`.
*/
ownerOnly: ['/projects'],
},
],
};