Distribution and versioning
Plugins stay ordinary git repos. The same herdr-plugin.toml that powers local development ships to the marketplace unchanged; the difference is only how herdr gets the code onto the machine.
Install vs link
plugin install | plugin link | |
|---|---|---|
| Source | GitHub shorthand owner/repo[/subdir] only | Any local directory |
| Mechanics | git clone into herdr-managed data, preview, [[build]], register | Registers your working tree in place |
| Build steps | Run (failure aborts install) | Never run; you build yourself |
| Checkout lifecycle | plugin uninstall removes it | plugin unlink leaves files alone |
| Global? | Yes: user-global across all sessions | Yes |
herdr plugin install peteretelej/herdr-plugins/hello-agent # marketplace path
herdr plugin link ./plugins/hello-agent # development path
Install shows a preview of the source and every command it will run; --yes skips it for trusted sources and --ref pins a revision. Both commands work while no herdr server is running. Installing over a locally linked plugin is refused; unlink first.
Gotcha: There is no
plugin update. Reinstall from GitHub to refresh a managed plugin, and bumpversionplus the CHANGELOG per release so users can see what changed. Same-id install replaces the checkout; config and state directories survive.
Same-id installs replace
Installed plugins are a map keyed by plugin_id (verified in _repos/herdrdev-herdr/src/app/api/plugins/mod.rs: plugins.insert(plugin.plugin_id, ...)). Two plugins with the same id cannot coexist on one machine; the newer install replaces the older registration. Uninstall removes by id (or by the install shorthand) and also clears the plugin’s agent-view source (plugin:<id>).
This is why the id-collision rule exists in practice: the marketplace tolerates duplicate ids across repos (its index records duplicates), but installing a colliding plugin silently takes over the slot.
Marketplace indexing
Listing is automatic and unreviewed:
- Make the repo public on GitHub.
- Add the
herdr-plugintopic. - Put one or more parseable
herdr-plugin.tomlmanifests on the default branch, at the root or in subdirectories.
The index refreshes about every 30 minutes and rescans a repo when its default-branch head changes. One repo card lists each valid manifest as a separately installable plugin. Forks, archived repos, and malformed manifests are excluded.
Census and collision checks run against the machine-readable index:
curl -s https://assets.herdr.dev/plugins/index.json | jq '.[] | .manifests[].id'
Run this before naming anything new (1,437 repos and 1,481 plugins as of 2026-10-02; all duplicate ids in the index are flat generic names, which is exactly why peteretelej.<name> prefixes are collision-free).
The min_herdr_version doctrine
min_herdr_version is a floor, not a target. The asymmetry:
- A
min_herdr_versionnewer than the running herdr is a hard failure: the plugin does not load, withplugin_requires_newer_herdrre-checked on every dispatch. - An unknown event name in the manifest is only an install-preview warning.
- Unknown manifest fields and new API methods surface as runtime errors you can catch, not load failures.
So the doctrine, recorded in production by herdr-automatic-rename’s manifest comments: keep the floor at the oldest herdr that supports what you already use, gate newer features at runtime, and declare newer event names freely. Raising the floor costs every user on an older herdr; a runtime capability check costs one if.
Hard-fail surfaces (avoid raising these): min_herdr_version itself, required manifest fields the old binary cannot parse. Warning surfaces (safe to use): unknown event names, unknown optional fields.
Prebuilt binaries: the later path
Nothing in the surveyed ecosystem mandates a distribution format beyond source plus [[build]], and herdr does not install missing toolchains: document required tools (cargo, bun) in your README because install previews show build commands but cannot satisfy them.
If install-time Rust compilation becomes a barrier for users, the candidate pattern is a bootstrap [[build]] step that downloads a prebuilt binary from GitHub Releases for the current platform (falling back to cargo build), with checksum verification. Treat this as unproven in the ecosystem for now: adopt it for the lab suite only after a real install-base complains about compile times, and keep the source-build fallback mandatory.