AXe Skills HubSearch /

AXE plugins

A skill is a document the model reads. A **plugin is code that runs in the

agent's own process** — it registers tools, hooks and commands. That difference

decides everything below: a skill can be published as text and be complete, and

a plugin cannot, because the thing you need is the code at a specific revision.

So a plugin entry in this hub is a catalogue entry, not a payload: metadata

that names a repository and the exact commit that was reviewed. The hub answers

"which plugins exist, what do they touch, who owns them"; git serves the code.

What an entry looks like

One JSON file per plugin, plugins/<name>/axe-plugin.json:

{
  "name": "axe-skillshub",
  "description": "Search the AXE Skills Hub from inside a session, as a tool.",
  "repo": "https://github.com/memjar/axe-skills-hub",
  "sha": "0000000000000000000000000000000000000000",
  "tier": "official",
  "maintainer": "AXE",
  "license": "MIT",
  "capabilities": {
    "tools": ["skillshub_find", "skillshub_get"],
    "hooks": [],
    "env": ["SKILLSHUB_KEY"]
  },
  "requires_axe": ">=0.1",
  "platforms": [],
  "docs_url": "https://github.com/memjar/axe-skills-hub/blob/main/docs/axeskills-plugins.md",
  "subdir": "plugins/axe-skillshub"
}
FieldRequiredWhy it is required
nameyesThe key you install by. Bare slug, lowercase.
descriptionyesThe only field a chooser reads. An entry without one is undiscoverable, and an empty string passes every check that asks whether a description *exists* — so it is length-checked, not presence-checked.
repoyesWhere the code is.
shayesExactly 40 hex characters. A branch or tag is rejected.
tieryesofficial (we maintain it) or community.
maintaineryesWho to go to. Not the same as who ingested it.
licenseyesA plugin nobody may reuse is not a community resource.
capabilitiesyesDeclared tools, hooks and env. This is the blast radius, stated before install.
requires_axe, platforms, docs_url, subdirnoConstraints and pointers.

Why the SHA is not optional

A pin is the whole trust model. If an entry named a branch, the author could

change what every future install runs without anyone reviewing it — the

catalogue would be asserting a review it no longer covers. Pinning a commit

means updating what installs requires a new, reviewed change to the entry.

Two honest limits, stated rather than implied:

capabilities were looked at once, at that commit. It says nothing about any

other commit in the same repository.

are separate steps, and the second one is the consent.

Removed entries

plugins/axeskills-plugins-removed.json lists entries pulled from the

catalogue, each with a reason and a date. A publisher refuses to publish

anything on that list. This exists because a catalogue without a revocation

path can only ever grow, and the one time you need it is after a security

incident — when re-reviewing every entry by hand is exactly what you do not

have time for.

How it is stored

Plugins go in the registry as format="catalog" with metadata.kind="plugin"

and metadata.source="axe:plugin", under the axe tenant.

format carries a CHECK (format IN ('python','skillmd','catalog')) and

SQLite cannot alter a CHECK constraint, so a plugin format would mean

rebuilding a table of ~111k rows. It would also be the wrong shape: catalog

already means "metadata about a thing that lives elsewhere", which is precisely

what a plugin entry is. metadata.kind is what separates our plugin entries

from mirrored catalogue rows, and bySource in the exported manifest keeps

them in their own bucket.

Publishing

python3 axeskills-publish-plugin.py --url http://127.0.0.1:8741 plugins/axe-skillshub
python3 axeskills-publish-plugin.py --url http://127.0.0.1:8741 --dry-run plugins/axe-skillshub

Validation happens before the request, not after: a bad SHA, a missing

capability block or a removed entry fails locally with a reason naming the

field, so a malformed entry never becomes a row that has to be yanked.

What this deliberately does not copy

The upstream plugin system is a Python runtime — register(ctx), 26 lifecycle

hooks, provider plugins that swap memory or context engines, single-select

versus multi-select semantics. That surface belongs to an agent runtime, and

this repository is a registry: it stores and serves, it does not execute. The

piece worth taking is the catalogue discipline — SHA pins, declared

capabilities, a tier, a removed list, and review as an explicit step — because

that is what makes a third party's plugin safe enough to consider at all.

When there is an AXE agent runtime that loads plugins, the entry above already

tells it what to fetch and what the plugin will touch. Until then, an entry is

a reviewed pointer, and that is a useful thing on its own.