Files
hermes-agent/plugin-catalog
Steven Leggett 3a147d8037 Pin sugar entry to the v3.10.2 release merge on main
The plugin shipped in Sugar 3.10.2 and is now merged to main
(eade16940789bc1f927af090f8a3b475e537eddd). Structural validator and
the pinned-source clone + hermes plugins validate both re-verified
against the new pin.
2026-09-16 14:19:07 -07:00
..

Hermes Plugin Catalog

Curated, Nous-approved Hermes plugins. Each YAML file in this directory (except removed.yaml) is one catalog entry, discoverable via hermes plugins catalog / hermes plugins search and installable with hermes plugins install <name>.

Admission policy

Presence in this directory is the trust signal. The rules that keep it meaningful:

  1. Human-merged gate. Entries are added only via a PR to the hermes-agent repository, reviewed and merged by a maintainer. There is no self-serve registry, no automated ingestion.
  2. Exact SHA pins are mandatory. Every entry pins a full 40-character commit SHA. Branches, tags, and short SHAs are rejected by the loader. Installs clone the repository and check out exactly that commit.
  3. No self-updating code. A listed plugin must not fetch and replace its own files (in-app "check for updates", signed release downloaders, remote plugin.js loaders). The exact SHA pin is the trust model; a self-updater lets an installed copy move to a commit nobody reviewed. Updates reach users only through a SHA-bump PR here plus hermes plugins update <name>. Keep the updater in the standalone distribution if you want one; strip it from the catalog build.
  4. SHA bumps are new PRs. Updating an entry's pin is a new PR whose diff (old SHA → new SHA) is re-reviewed like any other change — reviewers are expected to look at the upstream commit range being adopted.
  5. Owner-or-major-contributor submissions, or a maintainer-curated sweep. An entry may be submitted by the plugin repository's owner or a major contributor to it; drive-by submissions of third-party repos are declined. Hermes maintainers may also add entries in batches from a reviewed sweep of community plugins (every pin validated and scanned at the pinned commit, self-updater and credential-store checks run, English-first UI). Authors of swept-in entries keep control: a PR from the owner adjusting or removing their entry is accepted on request, and SHA bumps stay owner-or-maintainer PRs under rule 4.
  6. Declared capabilities must match reality. The capabilities: block (tools, hooks, middleware, env vars) must match what the plugin actually registers at the pinned commit. Validation fails the entry otherwise — undeclared capability creep is treated as a security issue.

Entry schema

name: example-plugin        # [a-z0-9_-]{1,64}, the catalog key
repo: https://github.com/owner/repo   # https:// only
sha: <40-hex commit sha>    # mandatory exact pin
subdir: ""                  # optional path within the repo
description: One-line description.
maintainer: OwnerName
tier: official              # official | community (default community)
category: memory            # desktop | memory | platform | web | tools | voice | automation | models | general
                            # (default desktop) — the shelf the entry sits on at /docs/plugins
requires_hermes: ">=0.19"   # optional
docs_url: ""                # optional
version: "1.4.0"            # optional human label for the sha (quote it); shown as "1.4.0 @ abcd1234"
image: ""                   # optional https image on a GitHub host, 2:1 (e.g. 1200x600), e.g.
                            # https://raw.githubusercontent.com/owner/repo/<sha>/docs/banner.png
platforms: []               # optional, e.g. [linux, macos]; empty = all
capabilities:
  provides_tools: []
  provides_hooks: []
  provides_middleware: []
  requires_env: []

version and image are cosmetic: neither is parsed or used to pick what installs. The sha stays the release; bump version in the same PR that bumps sha so the label on the card matches the code. Images must live on raw.githubusercontent.com, github.com or *.githubusercontent.com so the Desktop catalog never fetches from third-party hosts; pin the raw URL to the entry's commit and the picture is as immutable as the code.

removed.yaml — the blocklist

When an entry is pulled from the catalog for security or policy reasons, it is recorded in removed.yaml with a reason and date. The installer refuses to install anything matching a removed entry's name or repo URL, so a malicious plugin cannot be re-installed from a stale identifier after removal. Removals, like additions, land via reviewed PRs.