Extension Manifest Reference
The ExtensionManifest is the root descriptor for every MetaOne extension. It declares runtime type, capabilities, UI components, database requirements, permissions, and configuration schema.
Full Manifest Structure
public record ExtensionManifest(
String id, // Extension ID, e.g. "crm-extension"
String version, // Semantic version, e.g. "1.0.0"
String requiresPlatform, // Min platform version, e.g. ">=1.0.0"
String requiresSdk, // Min SDK version, e.g. ">=1.0.0"
RuntimeType runtimeType, // IN_PROCESS or EXTERNAL_SERVICE
UiManifest uiManifest,
DatabaseManifest databaseManifest,
CapabilityManifest capabilityManifest,
EntityManifest entityManifest,
List<String> permissions,
String serviceBaseUrl, // Required for EXTERNAL_SERVICE
ConfigManifest configManifest
)Runtime Types
| Type | Description |
|---|---|
IN_PROCESS | Plugin JAR loaded by PF4J into the host JVM. Capabilities invoked via reflection. |
EXTERNAL_SERVICE | Remote HTTP service. Set serviceBaseUrl to the service's base URL. |
CapabilityManifest
Declares which capabilities the extension provides and which events it publishes/consumes.
public record CapabilityManifest(
List<CapabilityProvide> provides, // Capabilities this extension exposes
List<String> consumesEvents, // Event keys this extension subscribes to
List<String> publishesEvents // Event keys this extension may publish
)
record CapabilityProvide(String key, String scope)Example:
new CapabilityManifest(
List.of(
new CapabilityProvide("crm.product.search", "workspace"),
new CapabilityProvide("crm.deal.create", "workspace")
),
List.of("chat.message.received"), // consumes
List.of("crm.deal.closed") // publishes
)UiManifest
Declares UI components contributed to the frontend shell.
public record UiManifest(
List<NavItemDef> navItems, // Sidebar nav items
List<RouteDef> routes, // SPA routes
List<WidgetDef> widgets, // Embeddable widgets
String assetsBaseUrl // Base URL for JS/CSS assets
)NavItemDef
record NavItemDef(String label, String icon, String route, int order)| Field | Description |
|---|---|
label | Display text |
icon | Icon name (framework-specific) |
route | Frontend route path (e.g. /crm) |
order | Sort order in nav |
RouteDef
record RouteDef(String path, String componentUrl)| Field | Description |
|---|---|
path | Frontend route path (e.g. /crm) |
componentUrl | URL to the remote JS component |
WidgetDef
record WidgetDef(String mountPoint, String componentUrl, int order)| Field | Description |
|---|---|
mountPoint | Named slot in the shell (e.g. dashboard.sidebar) |
componentUrl | URL to the remote widget component |
order | Order when multiple widgets share a mount point |
DatabaseManifest
Tells the platform which packages to scan for @Entity classes in the extension's workspace database.
public record DatabaseManifest(List<String> entityPackages)Example:
new DatabaseManifest(List.of("vn.metaone.crm.entity"))ConfigManifest
Declares configurable settings for this extension. These are surfaced in the admin UI and managed per workspace.
public record ConfigManifest(List<ConfigFieldDef> fields)
record ConfigFieldDef(
String key,
String label,
String description,
FieldType type, // STRING, SECRET, URL, INTEGER, BOOLEAN
boolean required,
String defaultValue
)Field Types:
| Type | Description |
|---|---|
STRING | Plain text |
SECRET | Encrypted at rest, masked in API responses |
URL | Validated URL string |
INTEGER | Numeric value |
BOOLEAN | true/false toggle |
Example:
new ConfigManifest(List.of(
new ConfigFieldDef("apiUrl", "API URL", "Base URL for the CRM API", URL, true, ""),
new ConfigFieldDef("apiKey", "API Key", "CRM API secret key", SECRET, true, ""),
new ConfigFieldDef("pageSize", "Page Size", "Default results per page", INTEGER,false, "20")
))EntityManifest
Exposes public data entities from the extension for cross-extension queries.
public record EntityManifest(List<PublicEntity> entities)
record PublicEntity(String name, List<EntityAction> actions, List<String> scopes)
enum EntityAction { CREATE, READ, UPDATE, DELETE, LIST }Permissions
The permissions list declares what platform resources the extension needs access to. These are checked during install and granted via ext_permission_grant.
List.of(
"crm.product.read",
"crm.product.write",
"crm.deal.read",
"crm.deal.write"
)Complete Example
new ExtensionManifest(
"crm-extension",
"1.0.0",
">=1.0.0",
">=1.0.0",
RuntimeType.IN_PROCESS,
new UiManifest(
List.of(new NavItemDef("CRM", "briefcase", "/crm", 10)),
List.of(new RouteDef("/crm", "http://localhost:5173/crm/main.js")),
List.of(),
"http://localhost:5173"
),
new DatabaseManifest(List.of("vn.metaone.crm.entity")),
new CapabilityManifest(
List.of(
new CapabilityProvide("crm.product.search", "workspace"),
new CapabilityProvide("crm.deal.create", "workspace")
),
List.of("platform.notification"),
List.of("crm.deal.closed")
),
null,
List.of("crm.product.read", "crm.product.write", "crm.deal.read", "crm.deal.write"),
null,
new ConfigManifest(List.of(
new ConfigFieldDef("apiKey", "API Key", "CRM API Key", SECRET, true, "")
))
)Keep the marketplace stub in sync. In development,
MarketplaceServiceStubinmetaone-coreis the source of truth for manifests. Always update the stub when you change the manifest.