Plugin Manifest
Every field of plugin-package-1.0, and the two manifest documents
There are two manifest documents and confusing them is a common first mistake.
plugin-package-1.0ismanifest.jsoninside the archive. It cannot carry the package content hash, because it is itself part of the bytes being hashed.plugin-manifest-1.0is the registration payload. It is the in-package manifest plus the content hash of the exact archive it describes, which is how the host binds a manifest to bytes.arvexa plugin upload --register-manifestbuilds it for you.
Fields of plugin-package-1.0:
contractVersion— must be exactlyplugin-package-1.0name— lowercase kebab/snake slug, at most 64 charactersversion—x.y.zminPlatformVersion—x.y.z, must not exceed the platform version1.0.0description— optional, at most 500 charactersscopes— at least one; the platform grants nothing by defaultroles— actor roles the plugin acts asaudiences— account audiences that may see and use ithooks— exact hook catalog ids, no wildcards and no prefixesextensionPoints—{ point, config }entriesruntime.entrypoints— map of entrypoint name to a path undersrc/webhooks—{ hook }entries, each also declared inhooks
Unknown fields are a warning, not an error: they are ignored by the platform rather than silently honored. The manifest itself is capped at 256,000 bytes.
Entrypoints. A key is either an exact hook catalog id — the runtime resolves a handler by the triggering hook — or a plain name matching [A-Za-z][A-Za-z0-9_]{0,63}. An unknown dotted key is rejected rather than loosely accepted, because hook ids are matched by exact catalog membership. The value must be a safe path under src/ with no traversal. At most 16 entrypoints.
Extension point config. Only the two declarative navigation points accept configuration, and only label and href. The href must be a same-origin absolute path starting with /; protocol-relative URLs, absolute URLs, backslashes, and control characters are all rejected. There is no way to inject HTML or script through a manifest — a navigation extension is a label and a path, by design.
Webhooks must also appear in hooks. Declaring a webhook for a hook you do not subscribe to is rejected, since there would be nothing to deliver.
Validate locally rather than by uploading. validatePluginPackageManifest in @arvexa/sdk collects every issue in one pass, which is what arvexa plugin validate prints. The host validator fails on the first problem — correct for a server, hostile as an authoring loop — so a clean local report is what saves you four upload cycles for four typos.