{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://shopdb-flask/plugin-manifest.schema.json", "title": "shopdb-flask plugin manifest", "description": "Shape of a plugin's manifest.json (ADR-002, ADR-013). Known fields are typed; additionalProperties is permitted so existing manifests and future additive fields validate unchanged.", "type": "object", "additionalProperties": true, "required": ["name", "version", "description"], "properties": { "name": { "type": "string", "description": "Machine name. Must equal the plugin directory name. Lowercase, concatenated.", "pattern": "^[a-z][a-z0-9]*$" }, "version": { "type": "string", "description": "Plugin version (semver-ish string)." }, "description": { "type": "string", "description": "One-line human description." }, "display_name": { "type": "string", "description": "Human label for UIs. Falls back to a title-cased name." }, "author": { "type": "string" }, "dependencies": { "type": "array", "description": "Hard dependencies: plugin names that must be installed and enabled first. A name may carry an optional PEP440 range (e.g. 'employees>=1.1'); the runtime loader uses name-only semantics.", "items": { "type": "string" } }, "optional_dependencies": { "type": "array", "description": "Soft couplings: plugins that unlock extra behavior when present, but do not block install/enable. Loader-ignored; adopt/list only WARN when unmet.", "items": { "type": "string" } }, "tier": { "type": "string", "description": "core = mandatory, lifecycle refuses to uninstall/disable it; optional = catalog plugin (default).", "enum": ["core", "optional"] }, "core_version": { "type": "string", "description": "PEP440 specifier set the framework contract version must satisfy, e.g. '>=0.12.0,<1.0.0'." }, "api_prefix": { "type": "string", "description": "URL prefix for the plugin blueprint, e.g. '/api/printedparts'. Must be unique across enabled plugins." }, "default_enabled": { "type": "boolean", "description": "Whether install leaves the plugin enabled. Plugins that provision extra tables ship false so a site opts in." }, "provides": { "type": "object", "description": "Capabilities this plugin advertises (e.g. asset_type, a features list). Free-form object read by catalog/UI, not the loader." }, "settings": { "type": "object", "description": "Plugin-scoped default settings metadata." } } }