The catalog README's per-plugin `vX.Y.Z` labels were an UNGUARDED surface: check-versions validated each plugin's OWN README badge, never the catalog README's labels, so they drifted (config-audit shown v5.5.0 while pinned to v5.7.0; voyage v5.1.1 while pinned to v5.6.0) — the doc misstated what `claude plugin install` actually resolves. Close the class, same pattern as the ref surface: - check-versions.mjs: new ERROR rule "catalog README label == catalog ref" via pure extractCatalogLabel() (matches the /open/<name>) heading, takes the first `vX.Y.Z`, ignores a trailing lang/flag badge). No legitimate transient state lets label != ref, so ERROR (not WARN). +5 tests. - release-plugin.mjs: on --write, bump the README label atomically with the ref via pure reconcileReadmeLabel() and git add README.md on --commit, so future releases keep label and ref in lock-step. +4 tests. - README.md: reconcile the 2 stale labels (config-audit -> v5.7.0, voyage -> v5.6.0). Gate now 9 OK / 1 WARN / 0 ERROR. - CLAUDE.md: doctrine updated to document the new gate rule + atomic label bump. ms-ai-architect stays WARN by decision (1.16.0 is unreleased WIP, never tagged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cm2RxKbomdLqjiWGcwCCPi
2.8 KiB
2.8 KiB
ktg-plugin-marketplace (catalog)
Catalog repository for the ktg-plugin-marketplace. After the polyrepo migration this repo hosts only
the marketplace manifest and the catalog-level docs; every plugin and the shared design-system live in
their own Forgejo repositories under https://git.fromaitochitta.com/open/.
What lives here
.claude-plugin/marketplace.json— the marketplace manifest (plugin entries point at external repos)README.md— the landing/catalog pageCONVENTIONS.md— marketplace-wide conventions inherited by every plugin repoGOVERNANCE.md— governance + fork-and-own model.mailmap,.gitleaks.toml,.gitleaksignore— shared git-hygiene baselines
Catalog maintenance
- Marketplace conventions: see CONVENTIONS.md.
- Adding/updating a plugin entry: edit
.claude-plugin/marketplace.json(externalsource: "url"with a pinnedref) and re-state the plugin in README.md with its verified version. - Plugin source, issues, and releases live in each plugin's own repository — not here.
- Releasing a plugin (canonical path —
scripts/release-plugin.mjs): since the polyrepo split, a release is a TWO-repo act — tag the plugin repo AND bump the catalogref. Forgetting the second step strands users on the old version (the exact drift this helper exists to prevent). Runnode scripts/release-plugin.mjs <plugin> [--version X.Y.Z]— dry-run by default; it REFUSES unlessplugin.json== README badge == the target version AND thevX.Y.Ztag exists, then prints the planned bump. Apply with--write [--commit] [--push];--create-tagmints+pushes a missing plugin tag first. On--writeit bumps the catalogrefAND the catalog README's per-plugin`vX.Y.Z`label together (andgit adds both on--commit). Because it only moves both to a verified, tagged, consistent version,check-versions.mjsis green by construction. Never hand-edit arefor a README label for a release — use this. Pure planner + label reconciler covered byscripts/release-plugin.test.mjs. - Version-consistency gate: run
node scripts/check-versions.mjsbefore committing anyrefchange. For each plugin it checks (against the sibling repo) that the catalogrefresolves to a real git tag (ERROR if dangling — breaks install), thatplugin.jsonversion == README version-badge (ERROR), that the catalog README's per-plugin`vX.Y.Z`label == the catalogref(ERROR — the human-facing doc must not misstate the installed version), and that the catalogrefmatchesplugin.jsonversion (WARN — catalog lags or an unreleased bump). Exit 1 on any ERROR;--strictalso fails on WARN. Pure-function core covered byscripts/check-versions.test.mjs(node --test scripts/check-versions.test.mjs).