example leaves too; plugins/ is documentation now
Done with `tea` as admin: plugins/offscale made public, plugins/example created public, both verified anonymously over https — which is the check that matters, because fetch.ts clones with no credentials and a private plugin simply cannot be installed from the marketplace. plugins/example 8 files, cloned back and diffed identical plugins/offscale now public (was private, so was uninstallable) `.gitignore` is one line now — `/plugins/*/`. The trailing slash is the whole design: it ignores DIRECTORIES, so files at the top of plugins/ stay tracked. The documentation about plugins belongs to the platform; the plugins do not. All three are in the marketplace catalogue, which is what makes this reversible: before this, untracking offscale meant a fresh install could never get it back. Now the store is the way in for all three. CatalogueEntry gains `icon` (a lucide name) alongside `iconUrl`. Both new entries ship glyphs rather than artwork, and without it they drew the generic puzzle piece in the store and their real icon after install — which reads as the icon changing rather than the store not knowing it. EXTRACTING-A-PLUGIN.md pointed at four directories a fresh checkout no longer has. It now gives repository URLs, says up front that this directory holds documentation rather than plugins, and carries a table of where each one went. Checked first that no tracked source statically imports a plugin directory — none does, so a fresh clone still builds. tsgo clean, frontend builds, 787 pass / 7 fail (unchanged). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,14 +2,24 @@
|
||||
|
||||
The runbook, written the day offscale became the first one. Follow it for music, then for the rest.
|
||||
|
||||
**This directory holds documentation, not plugins.** Every plugin is its own repository as of
|
||||
2026-08-15, and arrives in `plugins/<name>/` by `git clone` when somebody installs it — so on a fresh
|
||||
checkout the four references below are URLs, and on a machine where they are installed they are also
|
||||
directories. Both are given.
|
||||
|
||||
**Read first, in this order:**
|
||||
|
||||
1. `plugins/offscale/PLUGIN.md` — every decision and why, including the three that reversed
|
||||
2. `plugins/example/` — the reference implementation, deliberately the smallest real plugin
|
||||
3. `plugins/offscale/` — the worked example, all four parts
|
||||
4. `plugins/music/PLUGIN.md` — the MESSY worked example: three pieces that stayed behind, and why each
|
||||
is a seam rather than a loose end. Read it if your feature has anything the platform also uses.
|
||||
5. `src/servers/plugins/` — the system itself: `manifest`, `discover`, `mount`, `install`, `ecosystem`, `schema`, `generate`
|
||||
1. [`plugins/offscale` → `PLUGIN.md`](https://gitea.officer.dev/plugins/offscale/src/branch/main/PLUGIN.md)
|
||||
— every decision and why, including the three that reversed
|
||||
2. [`plugins/example`](https://gitea.officer.dev/plugins/example) — the reference implementation,
|
||||
deliberately the smallest thing that is still a real plugin
|
||||
3. [`plugins/offscale`](https://gitea.officer.dev/plugins/offscale) — the worked example, all four parts
|
||||
4. [`plugins/music` → `PLUGIN.md`](https://gitea.officer.dev/plugins/music/src/branch/main/PLUGIN.md)
|
||||
— the MESSY worked example: three pieces that stayed behind, and why each is a seam rather than a
|
||||
loose end. Read it if your feature has anything the platform also uses.
|
||||
5. `src/servers/plugins/` — the system itself: `manifest`, `discover`, `mount`, `install`, `ecosystem`,
|
||||
`schema`, `generate`. This one IS in this repository: the platform owns the plugin system, and only
|
||||
the plugins left.
|
||||
|
||||
---
|
||||
|
||||
@@ -138,7 +148,8 @@ A normal refresh is enough; the shell is `no-store`. When the log's last line ap
|
||||
|
||||
## Music is done. What it changed about this runbook
|
||||
|
||||
Extracted 2026-08-15 and verified live through the whole table above. `plugins/music/PLUGIN.md` is the
|
||||
Extracted 2026-08-15 and verified live through the whole table above.
|
||||
[`plugins/music` → `PLUGIN.md`](https://gitea.officer.dev/plugins/music/src/branch/main/PLUGIN.md) is the
|
||||
record; the parts worth carrying forward are already folded into the rules and traps above.
|
||||
|
||||
The one thing that generalises: **map what the PLATFORM still needs from your feature before you plan the
|
||||
@@ -192,3 +203,21 @@ No decision has been made. What the tree says, for whoever picks it:
|
||||
still there for plugins that have left. Generalising the union to `` `${string}:server` `` is the fix.
|
||||
- **`hasPersonalWrites` reads `c.personal` only**, so a plugin declaring the same thing through
|
||||
`readOnlyWrites` reports `false`. Nothing renders it, so it is dead on the wire.
|
||||
|
||||
---
|
||||
|
||||
## Where the plugins went
|
||||
|
||||
| Plugin | Repository | In this repo? |
|
||||
| ---------- | ------------------------------------ | ------------- |
|
||||
| `example` | `gitea.officer.dev/plugins/example` | no |
|
||||
| `offscale` | `gitea.officer.dev/plugins/offscale` | no |
|
||||
| `music` | `gitea.officer.dev/plugins/music` | no |
|
||||
|
||||
All three are public and clone anonymously over https, which is what the marketplace requires — it
|
||||
clones with no credentials on purpose, so a private plugin cannot be installed from it at all.
|
||||
|
||||
`.gitignore` ignores `/plugins/*/` — directories only, so this file and anything beside it stay tracked.
|
||||
The rule exists because a cloned plugin carries its own `.git`, and a tracked one turns `git add -A` into
|
||||
a commit of a gitlink: a pointer to a commit this repository does not contain. That is not a mistake to
|
||||
be careful about, it is what installing a plugin does, so it is handled by rule.
|
||||
|
||||
Reference in New Issue
Block a user