the UI half. a row per plugin that ships commanders, below the owner's own
categories and separated from them — because they are not the same kind of thing.
a category is the owner's filing and they may rename it; a plugin is where
something came from and they may not. mixed into one list, "av-club" reads as a
folder somebody made, and the first thing you do with a folder you made is rename
it.
offers sit ABOVE the grid rather than in it. a commander in the grid runs, has a
transcript and has cost money; an offer is a description on disk. drawn as the same
card with a badge, the two look interchangeable, and the first consequence is
somebody hunting for the transcript of a thing that has never run.
an offer STAYS after it is used. it is a template and there is no reason to have
only one — two folders watched for two formats is two commanders from one offer,
and hiding it would make the second look impossible.
the form is drawn from the template's own `inputs`. nothing in the component knows
what av-club wants: options become buttons, boolean becomes yes/no, everything else
is a field. the button names what is missing rather than marking it red.
TWO REAL BUGS FOUND BY WIRING IT UP, both in the list route:
`?category=plugin:av-club` reached `Number('plugin:av-club')` — NaN — and the query
compared `category_id = NaN`. that matches nothing and looks exactly like "this
plugin has no commanders", which is the worst way for a filter to fail. parsed
before the numeric branch now.
and the grid DROPS every row without a transcript. that was right when the only way
to get a row was to start a conversation; it is wrong now, because a commander from
a template arrives deliberately not running — so the thing somebody just created was
invisible, under a toast saying it worked. a row with a `plugin` and no session is
now projected from the row itself, with the zeroes that are true of it, and sorted
FIRST: it is the one that needs a decision. ordinary rows keep the old behaviour,
since a hand-made row with no transcript is a conversation that failed to start and
the design refuses to draw a tombstone for it.
four locale keys, all six languages, parity test green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043