| 1 | --- |
| 2 | name: a0-contribute-plugin |
| 3 | description: Guide for publishing an Agent Zero plugin to the community Plugin Index (a0-plugins repo). Covers GitHub repo setup, index.yaml creation, CI validation rules, and PR submission. Use when the user wants to share, publish, submit, or contribute a plugin to the Plugin Hub so other Agent Zero users can find and install it. |
| 4 | version: 1.0.0 |
| 5 | tags: ["plugins", "contribute", "publish", "plugin-hub", "community", "index", "PR"] |
| 6 | trigger_patterns: |
| 7 | - "contribute plugin" |
| 8 | - "publish plugin" |
| 9 | - "share plugin" |
| 10 | - "submit plugin" |
| 11 | - "contribute to plugin hub" |
| 12 | - "plugin index" |
| 13 | - "community plugin" |
| 14 | - "open source plugin" |
| 15 | --- |
| 16 | |
| 17 | # Agent Zero Plugin Contribution |
| 18 | |
| 19 | This skill guides publishing a plugin to the [Plugin Index](https://github.com/agent0ai/a0-plugins), making it discoverable and installable by all Agent Zero users. |
| 20 | |
| 21 | --- |
| 22 | |
| 23 | ## Prerequisites |
| 24 | |
| 25 | Before starting, verify: |
| 26 | |
| 27 | 1. Plugin exists and works locally in `/a0/usr/plugins/<name>/` |
| 28 | 2. Plugin has been reviewed - if not, offer to run `a0-review-plugin` first: |
| 29 | > "I recommend running a full review before contributing. Should I do that now?" |
| 30 | 3. User has a GitHub account and `git` / `gh` CLI available |
| 31 | |
| 32 | --- |
| 33 | |
| 34 | ## Step 0: Ask Automation Preference |
| 35 | |
| 36 | Before doing any git work, ask: |
| 37 | |
| 38 | > "Do you want me to handle the git operations (fork, branch, commit, PR) automatically, or would you prefer I give you the steps to run manually?" |
| 39 | |
| 40 | - **Automatic**: proceed using `gh` and `git` commands via the code execution tool |
| 41 | - **Manual**: provide exact commands at each step for the user to run |
| 42 | |
| 43 | --- |
| 44 | |
| 45 | ## Step 1: Prepare the Plugin GitHub Repository |
| 46 | |
| 47 | The plugin must live in its **own standalone GitHub repository** with plugin contents at the **repo root** (not inside a subfolder). |
| 48 | |
| 49 | ### Required repo structure |
| 50 | |
| 51 | ```text |
| 52 | your-plugin-repo/ <- GitHub repository root |
| 53 | ├── plugin.yaml <- runtime manifest (REQUIRED) |
| 54 | ├── README.md <- strongly recommended (shown in Plugin Hub detail view) |
| 55 | ├── LICENSE <- REQUIRED for Plugin Index submission (place at repo root) |
| 56 | ├── default_config.yaml <- optional |
| 57 | ├── api/ <- API handlers |
| 58 | ├── tools/ <- agent tools |
| 59 | ├── helpers/ <- shared Python logic |
| 60 | ├── prompts/ <- prompt templates |
| 61 | ├── agents/ <- agent profiles |
| 62 | ├── conf/ <- config files (e.g. model_providers.yaml) |
| 63 | ├── extensions/ <- lifecycle, UI, and implicit @extensible hooks |
| 64 | └── webui/ <- frontend pages, stores, components |
| 65 | ``` |
| 66 | |
| 67 | Inside `extensions/`, use `python/<point>/` for named lifecycle hooks, `python/_functions/<module>/<qualname>/<start|end>/` for implicit `@extensible` hooks, and `webui/<point>/` for UI breakpoints. Do not publish the retired flattened `python/<module>_<qualname>_<start|end>/` form. |
| 68 | |
| 69 | ### Runtime `plugin.yaml` requirements |
| 70 | |
| 71 | The remote `plugin.yaml` must include a **`name` field** - this is validated by CI and must exactly match the index folder name: |
| 72 | |
| 73 | ```yaml |
| 74 | name: my_plugin # REQUIRED - must match index folder name (^[a-z0-9_]+$) |
| 75 | title: My Plugin |
| 76 | description: What this plugin does. |
| 77 | version: 1.0.0 |
| 78 | settings_sections: [] |
| 79 | per_project_config: false |
| 80 | per_agent_config: false |
| 81 | always_enabled: false |
| 82 | ``` |
| 83 | |
| 84 | If the plugin was built locally, help the user create the GitHub repo and push it: |
| 85 | |
| 86 | ```bash |
| 87 | # Create repo (automatic mode - using gh CLI) |
| 88 | gh repo create <repo-name> --public --description "Agent Zero plugin: <title>" |
| 89 | git init |
| 90 | git add . |
| 91 | git commit -m "feat: initial plugin commit" |
| 92 | git remote add origin https://github.com/<user>/<repo-name>.git |
| 93 | git push -u origin main |
| 94 | ``` |
| 95 | |
| 96 | --- |
| 97 | |
| 98 | ## Step 2: Choose the Index Folder Name |
| 99 | |
| 100 | The folder name in the index must: |
| 101 | - Match the `name` field in your remote `plugin.yaml` **exactly** |
| 102 | - Follow `^[a-z0-9_]+$` (lowercase letters, numbers, underscores - **no hyphens**) |
| 103 | - Be unique in the index |
| 104 | - Not start with `_` (reserved for internal use) |
| 105 | |
| 106 | Verify uniqueness by fetching the current index: |
| 107 | ``` |
| 108 | https://github.com/agent0ai/a0-plugins/releases/download/generated-index/index.json |
| 109 | ``` |
| 110 | |
| 111 | Check that the intended name does not appear as a key in `plugins`. |
| 112 | |
| 113 | --- |
| 114 | |
| 115 | ## Step 3: Create the Index Submission |
| 116 | |
| 117 | ### Fork and set up |
| 118 | |
| 119 | ```bash |
| 120 | # Automatic mode |
| 121 | gh repo fork https://github.com/agent0ai/a0-plugins --clone --remote |
| 122 | cd a0-plugins |
| 123 | git checkout -b add-<plugin_name> |
| 124 | ``` |
| 125 | |
| 126 | ### Create the plugin folder |
| 127 | |
| 128 | ```bash |
| 129 | mkdir -p plugins/<plugin_name> |
| 130 | ``` |
| 131 | |
| 132 | ### Create `index.yaml` |
| 133 | |
| 134 | The index uses **`index.yaml`** (not `plugin.yaml`). These are different schemas: |
| 135 | |
| 136 | ```yaml |
| 137 | title: My Plugin |
| 138 | description: One-sentence description of what the plugin does for the user. |
| 139 | github: https://github.com/<user>/<repo-name> |
| 140 | tags: |
| 141 | - tools |
| 142 | - example |
| 143 | ``` |
| 144 | |
| 145 | Optional additional fields: |
| 146 | ```yaml |
| 147 | screenshots: |
| 148 | - https://raw.githubusercontent.com/<user>/<repo>/main/docs/screenshot1.png |
| 149 | - https://raw.githubusercontent.com/<user>/<repo>/main/docs/screenshot2.webp |
| 150 | ``` |
| 151 | |
| 152 | ### Recommended tags |
| 153 | |
| 154 | Use tags from https://github.com/agent0ai/a0-plugins/blob/main/TAGS.md (up to 5). |
| 155 | Common tags: `tools`, `automation`, `workflow`, `api`, `web`, `database`, `memory`, `integration`, `security`, `development`, `llm`, `agents` |
| 156 | |
| 157 | ### Optional thumbnail |
| 158 | |
| 159 | Add a square image named `thumbnail.png`, `thumbnail.jpg`, or `thumbnail.webp` (max 20 KB, must be square aspect ratio) to `plugins/<plugin_name>/`. |
| 160 | |
| 161 | --- |
| 162 | |
| 163 | ## Step 4: Pre-validate Before PR |
| 164 | |
| 165 | Run these checks locally before opening the PR (mirrors what CI will verify): |
| 166 | |
| 167 | | Check | Rule | |
| 168 | |---|---| |
| 169 | | `index.yaml` exists in `plugins/<name>/` | Required | |
| 170 | | Only `index.yaml` + optional thumbnail in the folder | No other files/subdirs | |
| 171 | | `title` length | Max 50 characters | |
| 172 | | `description` length | Max 500 characters | |
| 173 | | `index.yaml` total length | Max 2000 characters | |
| 174 | | `tags` count | Max 5 | |
| 175 | | `screenshots` count | Max 5, each URL must be reachable | |
| 176 | | `github` URL | Points to existing public repo | |
| 177 | | Remote `plugin.yaml` | Exists at repo root | |
| 178 | | Remote `plugin.yaml` `name` field | Matches index folder name exactly | |
| 179 | | Remote `LICENSE` | Exists at repo root (Plugin Index policy) | |
| 180 | | Folder name pattern | `^[a-z0-9_]+$`, no leading `_` | |
| 181 | | `github` URL uniqueness | Not already in the index for another plugin | |
| 182 | |
| 183 | Verify the remote `plugin.yaml` name match: |
| 184 | ```bash |
| 185 | curl -s https://raw.githubusercontent.com/<user>/<repo>/main/plugin.yaml | grep "^name:" |
| 186 | # Expected output: name: <plugin_name> |
| 187 | ``` |
| 188 | |
| 189 | --- |
| 190 | |
| 191 | ## Step 5: Commit and Open PR |
| 192 | |
| 193 | ```bash |
| 194 | # Add and commit |
| 195 | git add plugins/<plugin_name>/ |
| 196 | git commit -m "feat: add <plugin_name> plugin" |
| 197 | |
| 198 | # Push and open PR |
| 199 | git push origin add-<plugin_name> |
| 200 | gh pr create \ |
| 201 | --repo agent0ai/a0-plugins \ |
| 202 | --title "feat: add <plugin_name>" \ |
| 203 | --body "## Plugin: <title> |
| 204 | |
| 205 | <description> |
| 206 | |
| 207 | - GitHub: <github_url> |
| 208 | - Tags: <tags>" |
| 209 | ``` |
| 210 | |
| 211 | ### PR rules |
| 212 | |
| 213 | - One plugin per PR (adding exactly one new folder under `plugins/`) |
| 214 | - CI validates automatically on open/sync/reopen |
| 215 | - A human maintainer reviews after CI passes |
| 216 | - If PR has no activity for 7+ days after CI failure it may be auto-closed |
| 217 | |
| 218 | --- |
| 219 | |
| 220 | ## Two Schemas at a Glance |
| 221 | |
| 222 | | File | Location | Purpose | Key fields | |
| 223 | |---|---|---|---| |
| 224 | | `plugin.yaml` | Your plugin's GitHub repo root | Runtime manifest (drives Agent Zero behavior) | `name` (required!), `title`, `description`, `version`, `settings_sections`, `per_project_config`, `per_agent_config`, `always_enabled` | |
| 225 | | `index.yaml` | `a0-plugins/plugins/<name>/` | Index manifest (drives discoverability) | `title`, `description`, `github`, `tags`, `screenshots` | |
| 226 | |
| 227 | **Never mix these up.** They have different schemas and different purposes. |
| 228 | |
| 229 | --- |
| 230 | |
| 231 | ## References |
| 232 | |
| 233 | - Plugin architecture: `/a0/plugins/AGENTS.md` |
| 234 | - Developer lifecycle guide: `/a0/docs/developer/plugins.md` |
| 235 | - Plugin Index repo: https://github.com/agent0ai/a0-plugins |
| 236 | - Recommended tags: https://github.com/agent0ai/a0-plugins/blob/main/TAGS.md |
| 237 | - Review before contributing: read `/a0/skills/a0-review-plugin/SKILL.md` |
| 238 | - Build the plugin first: read `/a0/skills/a0-create-plugin/SKILL.md` |