0025: Plugin distributions are named heinzel-<name>¶
Context and Problem Statement¶
ADR 0016 named plugins heinzel-plugin-*. ADR 0017
then named first-party plugins heinzel-<name> (heinzel-clock, heinzel-atlassian), so the repository had two
conventions: one for plugins in plugins/ and one for plugins scaffolded from template/. A plugin promoted from
its own repository into plugins/ would have to be renamed, which breaks every install URL and receipt that names
it. Which name does a plugin distribution get?
Decision Drivers¶
- One convention for every plugin, so promoting an external plugin into
plugins/changes nothing for its users. - Short names: distributions, repositories and
hz system plugin remove <distribution>are typed. - The name a user types (
hz system plugin add clock,hz clock ...) maps to the distribution without a lookup.
Considered Options¶
heinzel-<name>for every plugin, first-party or external (chosen)- Keep
heinzel-plugin-<name>for external plugins andheinzel-<name>for first-party ones: two conventions, and promotion renames the distribution. heinzel-plugin-<name>for every plugin: longer, and the first-party packages and extras (heinzel[atlassian]) would no longer match their distributions.
Decision Outcome¶
Chosen option: every plugin distribution is named heinzel-<name>, because one convention serves first-party and
external plugins alike and promotion becomes a move, not a rename.
- Distribution and repository:
heinzel-<name>, first-party or external. - Root package:
heinzel_<name>. - Entry point:
<name> = "heinzel_<name>"in theheinzel.modulesgroup;<name>is also the command group (hz <name> ...). hz system plugin add <name>resolves a first-party name toplugins/heinzel-<name>at the installed core version (ADR 0017); anything else is a uv spec (git URL, path, package name).- The copier template defaults to
heinzel-<name>/heinzel_<name>; the example plugin isheinzel-example. - This replaces the sentence "Plugins are
heinzel-plugin-*" of ADR 0016; the rest of ADR 0016 stands.
Consequences¶
- Good: one convention;
plugins/heinzel-<name>,heinzel_<name>,hz <name>and the extraheinzel[<name>]line up. - Bad: breaking for plugin authors who scaffolded with the old defaults. They rename the distribution and package, or keep the old name until their next major release; discovery reads the entry point group, not the name, so old plugins still load.
- Bad: external and first-party plugins share one namespace, so an external plugin can collide with a later first-party name.
Confirmation¶
tests/fixtures/heinzel-dummyandmake template-test(rendersheinzel-examplefrom the template) exercise the convention end to end.tests/unit/repository_test.py::test_first_party_plugins_match_the_plugins_directorykeeps first-party names equal toplugins/heinzel-<name>.- Review: the copier defaults in
copier.ymland the docs.
More Information¶
- ADR 0007 calls the example plugin
heinzel-plugin-example; it isheinzel-example(github.com/helmut-hoffer-von-ankershoffen/heinzel-example) from now on. Since 2026-10-24 it lives in heinzel-contrib, the repository of community plugins, asplugins/heinzel-example; its own repository is archived. - Decided by the maintainer on 2026-10-23.
- Open questions: who keeps a name when an external plugin collides with a later first-party one; whether the PyPI
keyword
heinzel-pluginin the template stays as the way to find plugins.