Skip to content

plugin-manifest schema

A real .spk business-application plugin's own spk-assembly/plugin.json contract (id/version/permissions/roles/dependencies).

Pull the full JSON Schema: erp schema pull plugin-manifest  ·  MCP: erp_get_schema {"name":"plugin-manifest"}

Top-level properties

PropertyTypeRequiredNotes
idstringyes
namestringyes
versionstringyes
typestring
vendorstring
licensestring
licenseTierstring
categorystring
erpVersionstring
minErpVersionstring
maxErpVersionstring
mainClassstring | nullFully-qualified PF4J plugin main class. Optional (null/absent) for a pure-JSON plugin that ships zero Java classes -- the platform loads it via the built-in JsonOnlyPlugin entry point.
schemaNamestringApp-owned Postgres schema this plugin's Entity-Engine tables route to — see feedback-entity-engine-tables-must-route-to-app-schema.
scopestringone of: global, tenant — Tenant-Safe Plugin & Extension Architecture spec §54. 'global' (default, every manifest that predates this field): a shared plugin installable by any tenant. 'tenant': a private single-tenant L5 extension — MUST also set tenantId, and if it carries Java code (mainClass, or type java-extension/code-plugin) it MUST declare runtimeModes: ['service'] — the shared runtime refuses to load it (ExtensionInstallValidator, spec §11/§28.10/§74).
tenantIdstringSpec §54 — the owning tenant of a scope:'tenant' plugin. Required iff scope=='tenant'; must match the tenant the plugin is installed into. Absent for a global plugin.
erpApiVersionstringSpec §25 — the ERP extension-API contract version this plugin targets (e.g. '5.0'), distinct from erpVersion/minErpVersion (platform build versions). Optional; informational in E1.
supportedApplicationsarraySpec §25 — applications this extension supports, e.g. ['HCM']. Optional; empty/absent means unconstrained.
dependenciesarray
optionalDependenciesarray
permissionsarrayLegacy flat permission-key catalogue; real installs read roles[].permissionKeys instead (PluginRoleInstaller) — commonly left empty on modules whose roles[] is populated.
ownerstring
editableboolean
extendableboolean
capabilitiesProvidedarray
capabilitiesRequiredarray
featureFlagsarray
configSchemaJsonobject | string | null
frontendBundleobjectOptional — dynamic frontend-plugin-loading (ai/patterns/code-plugin-sdk.md). Absent on every plugin.json that predates it.
rolesarray
runtimeModesarrayAdded 2026-09-03 (real gap — this field is genuinely load-bearing on every shipped plugin.json today, e.g. hcm-learning's own ["embedded"], but was entirely absent from this schema until now, so erp_get_schema/erp schema pull misrepresented the real manifest shape). Which Plugin Runtime modes this plugin can run under: 'embedded' (loaded in-process via PF4J, the only behavior every pre-existing manifest declares) and/or 'service' (its own standalone Spring Boot process, routed to over HTTP — see PluginManifest#runtimeModes' own Javadoc in engine-plugin-api). Defaults to ['embedded'] when absent. Declaring 'service' here does not itself switch anything — the actual mode is chosen per-plugin via Studio's Plugin Runtime toggle (erp_core.application.deployment_type).
serviceRuntimestring | nullone of: java, python, nodejs, null — Added 2026-09-14 (Polyglot Plugin Runtime initiative, PluginManifest#serviceRuntime's own Javadoc in engine-plugin-api). Which language a Service-mode plugin's own process is implemented in. Only meaningful when runtimeModes contains 'service' — an embedded-only plugin is always Java (nothing else can load into the JVM), and installing a manifest that sets this to 'python'/'nodejs' without declaring 'service' in runtimeModes fails install (PluginCodeLifecycle#validateServiceRuntime). null/absent defaults to 'java' — every manifest that predates this field keeps its exact current behavior. Real, proven implementations exist for all three values: hello-plugin-service (java), hello-plugin-service-python (python), hello-plugin-service-node (nodejs) — see 'Build a Service-mode plugin in Python or Node.js' for the SDK and full build/deploy path for each.
serviceFrameworkstring | nullone of: spring-boot, fastapi, express, null — Added 2026-09-14, same initiative as serviceRuntime — purely informational (shown as a read-only chip in Studio's Plugin Runtime panel; not validated against serviceRuntime today, so keep them consistent yourself: spring-boot pairs with java, fastapi with python, express with nodejs). null/absent defaults to 'spring-boot'.
serviceDeploymentobject | nullAdded 2026-09-03 (same real-gap fix as runtimeModes). Recommended deployment/runtime defaults for this plugin when run in 'service' mode (PluginManifest.PluginServiceDeploymentSpec in engine-plugin-api). null (the default for almost every manifest) means Studio seeds an empty config the admin fills in the first time they switch this plugin to Service mode. Only healthPath/timeoutMs/heartbeatIntervalSeconds actually drive runtime behavior today (health checks, proxy call timeout) — docker/kubernetes/cloud are real, persisted, Studio-editable data for a future Deployment Manager, not wired to any live provisioning API.

Named sub-definitions

resourceLimits