The Plugin API
The plugin API is small on purpose. A plugin is a prebuilt module plus a signed manifest that declares what it extends. This page sketches the surface — the full contract lives in the SDK.
Plugin tiers
Every plugin has a tier. The tier decides what it can reach.
Tier 1 — no code. A manifest only: content types and fields, categories, settings screens, admin forms, theme presets, and "call this URL on publish" hooks. Tovu's own code does the work, so it's safe to install from anyone. Example: a Recipes plugin that adds a Recipe collection.
Tier 2 — limited code. Plugin code that can only use what you grant it. Not built yet.
Tier 3 — full access. This is how code plugins work today. The plugin runs inside Tovu with full access to your machine and every site on it. Only install plugins you trust.
Set it with tier in the manifest: tier-1, tier-2, or tier-3. No tier means Tier 3.
A hook
Plugins subscribe to typed hooks. The v1 walking-skeleton ships one, so you can see the shape:
export default definePlugin({
id: "acme/word-count",
hooks: {
"content.entry.beforeSave": (entry) => {
entry.ext["acme/word-count"] = countWords(entry.bodyJson);
return entry;
},
},
});Extension fields, not schema changes
A plugin never owns your schema. It writes into a namespaced ext bag keyed by plugin id, so two plugins can never collide and uninstalling one never corrupts your tables.
definePlugin(...)— declare id, hooks, and requested capabilities.content.entry.beforeSave— the first typed hook; more land as the surface grows.ext.{pluginId}— where a plugin's data lives, namespaced and safe.
This is a preview of a thin slice; the API is not yet stable.