---
title: "Publish a plugin or theme"
description: "A public GitHub repository and one request. No review queue, no account."
canonical: "https://smabar.com/docs/publish/"
lang: en
---

# Publish a plugin or theme

> A public GitHub repository and one request. No review queue, no account.

Canonical HTML version: https://smabar.com/docs/publish/ · Language: en · Publisher: smabar (https://smabar.com)

---

Anyone can list a plugin or theme in the Community Store. The store reads public GitHub repositories, checks the form of what it finds, and lists it right away.

## What the repository needs

- A plugin: `smabar.json` at the root for a single plugin, or `plugins/<id>/smabar.json` for several. The `id` in the manifest is the store id; ids are first come, first served, and plugins and themes are separate namespaces.
- A theme: `themes/<name>.json`.
- A `LICENSE` file at the root. Without one the repository is rejected.
- A `README.md` next to the manifest. The store shows it on the plugin's page.
- No symlinks and no git submodules anywhere in a plugin folder, and at most two hundred folders below it.

If your agent built the plugin, ask it to prepare the repository; it knows the manifest format and can write the README.

## Versions

The `version` in the manifest is the update unit: bump it and push, and every installation is offered the new version. A release tag named `v<version>` (single plugin) or `<id>-v<version>` (collections and themes) pins the listed version to that tag; without releases the store lists the default branch. A tag whose version differs from the file is rejected, never silently corrected.

## Submitting

One request checks the plugins and themes in your repository:

```sh
curl -X POST https://store.smabar.com/submit \
  -H 'content-type: application/json' \
  -d '{"url":"https://github.com/<owner>/<repo>"}'
```

The answer names every plugin and theme it found with `accepted` or `rejected` and, for a rejection, the rule that failed. Each repository may publish **20 new plugins and themes combined per rolling 24 hours**. Updates to listed entries do not use this allowance. Excess entries are rejected for now; once the repository is listed, its hourly crawl retries them as slots become available, even without another commit. Deleting entries or renaming the repository does not reset the allowance.

Ten submission attempts per hour and address are allowed. By default, an address may also submit at most **five new repositories from three different GitHub accounts within 24 hours**; IPv6 addresses share their /64 network's allowance. Repeating the same repository does not consume another source slot. A 429 response includes a retry time. The operator can block entire repositories or GitHub accounts, including future entries; blocked sources receive a 403 response.

## What the store does not do

It does not review code, does not run it, does not sign it and never hosts it. Clients download from GitHub, verify the content against the signed catalog, and show every requirement before install. Popularity is not a security signal, and the store does not pretend otherwise. If a version turns out to be harmful, it is blocked, which disables it on every machine but deletes nothing.
