Adding a plugin
What to create, what to register, and what this site picks up on its own
A new plugin is a directory, a manifest, at least one skill, and one entry in the catalog. This site reads all of that from the repository at build time, so most of it needs no documentation work at all.
1. Create the plugin
mkdir -p <name>/skills/<skill><name>/plugin.json:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "<name>",
"description": "One sentence, in the voice of someone deciding whether to install it."
}2. Write the skill
<name>/skills/<skill>/SKILL.md. The frontmatter is the contract:
---
name: <skill>
description: >-
What it does, then the phrasings, situations and symptoms that should make
an agent reach for it, and what it is explicitly not for.
---
# …The description is a trigger, not a summary. It is what the model matches
against, so name the actual phrasings ("commit this", "faz um commit"), the
situations, and the boundaries. A vague description is a skill that never fires
or fires constantly.
Add invoke: only to narrow the policy. Absent means model and user, which
is what almost every skill should be:
invoke:
model: false # a deliberate action; the model must never auto-trigger it
user: truePut long material in references/ and executables in scripts/ rather than in
the skill body. See anatomy for the distinction between those
and a plugin-level resources/.
3. Register it
Add the entry to marketplace.json:
{
"name": "<name>",
"source": "./<name>",
"description": "The description a person reads in `uze list`.",
"keywords": ["…"]
}4. That is the documentation, mostly
This site's catalog is read from the repository at build time:
marketplace.json for the roster, each plugin.json for the manifest, each
SKILL.md's frontmatter for the capability and its invocation policy. A new
plugin appears in the landing page grid, in the catalog and in
the skill index with nothing written by hand.
What it does not generate is a page of its own. Add
web/content/docs/plugins/<name>.mdx:
---
title: <name>
description: One line, in the same voice as the others.
---
# <name>
Prose about the workflow, the part a reader needs that the frontmatter cannot say.
<PluginHeader name="<name>" />
## The skills
<PluginSkills name="<name>" />Then add "<name>" to web/content/docs/plugins/meta.json.
The components available in MDX all read the live catalog, so none of them take the facts as props:
| Component | Renders |
|---|---|
<PluginCards /> | the whole roster as cards |
<PluginHeader name="…" /> | skills, capability slots, keywords, install commands |
<PluginSkills name="…" /> | one section per skill, anchored by skill name |
<PluginResources name="…" /> | the plugin's resources/ tree, linked to source |
<SkillTable /> / <SkillTable plugin="…" /> | the skill table |
<InstallCommand command="…" label="…" /> | a copyable command line |
Before you split a plugin out
The current inventory does not need more separation than it has, and premature separation is easy to regret. Three splits are deliberately not made, and the reasoning is in the catalog. The bar is the same in both directions: a new plugin earns its own directory when its domain is genuinely different from every existing one, not when a skill feels like it deserves top billing.
Running this site
cd web
bun install
bun run devThe catalog reader resolves the repository as ../ from web/lib/, so the site
must be built from inside a checkout: a standalone copy of web/ has nothing
to catalog.
To compare colour palettes, append ?palette=<name> to any URL:
amber, periwinkle, terracotta or violet. The choice is remembered for
the visit; ?palette= with no value clears it. To change what the site ships
with, edit the one constant in web/lib/palette.ts.