Adding a plugin
Each plugin lives in its own repository, which holds its code, reference documentation and issues. purisev/agent-plugins holds the two catalogs, the installer and this site.
- Give the plugin repository a
.claude-plugin/plugin.jsonwith anameand aversion, and check it withclaude plugin validate <checkout>/.claude-plugin/plugin.json. For Codex it also needs a.codex-plugin/plugin.json. - Add an entry with the same
nameto both catalogs:.claude-plugin/marketplace.json— agithubsource;.agents/plugins/marketplace.json— aurlsource for the same repository, and apolicy. Codex has nogithubsource type and lists nothing from the first file.
- A plugin that needs another plugin from this catalog lists it under
dependenciesin its.claude-plugin/plugin.json. A bare name resolves inside this marketplace, so Claude Code installs it automatically. - Add the plugin to
ALL_PLUGINSindocs/install.shand to$AllPluginsand the-PluginValidateSetindocs/install.ps1, and give it a section indocs/plugins.md. - Run the checks and open a pull request.
Do not give a plugin repository a marketplace.json of its own. The same plugin reachable through two
marketplaces can be enabled twice, and its hooks then run twice.
Claude Code tells plugin versions apart by version in plugin.json, so raise it with every release.
Hooks shared by both hosts use ${CLAUDE_PLUGIN_ROOT} in their commands: Claude Code expands only that
token, and Codex provides it next to its own ${PLUGIN_ROOT}.
Checks
node --test
claude plugin validate .
codex plugin marketplace add . && codex plugin list
mdbook build
node --test needs no network. It guards both catalogs and that they agree, and runs both installers
against stand-ins for claude, codex, git and node, so nothing is installed. The install.ps1
cases are skipped where pwsh is missing.
The marketplace name purisev is part of every installed plugin’s id and of users’ settings. Renaming
it would orphan those installs.