Appearance
DevOps branch reference
The DevOps branch of the Studio Explorer contains one working screen, Extensions. The nodes Source Control, Build, Deployment and Packages are shown as "coming soon" in the Explorer and are not available in this release. For deployment of backend services and the plugin build pipeline see Deployment, Build, test and publish and Code extensions.
Extensions
Extensions is where an administrator installs, upgrades, configures, disables and uninstalls the extension plugins of the tenant, and where packages (themes, template packs, AI packs and plugin packages) are registered in and installed from the marketplace catalog. It has two tabs: Installed Plugins and Marketplace Catalog. Installing is always an explicit consent step that discloses what the plugin will be able to do. Tenant administrators and release managers use it. The Explorer node opens the screen whose title reads "Marketplace". For the publishing workflow and the catalog concepts see Marketplace and publishing.
Where to find it: Workspace > DevOps > Extensions. Page key marketplace.
Key concepts
| Term | Meaning |
|---|---|
| Plugin | A unit of extension described by a manifest: id, version, publisher, distribution mode, contributions (blocks, actions, functions, and so on), network scopes and dependencies. |
| Installation | The tenant's record that a plugin version is installed (state installed or disabled), with its configuration and the capability consent that was approved. |
| Catalog entry | A plugin the current Studio build ships (code and manifest). The list on the Installed Plugins tab merges the build's catalog with the tenant's installations. |
| Capability disclosure | The list derived from the manifest shown at install time: what the plugin registers, which network addresses it can reach, and whether its metadata is locked or editable. The approved disclosure is stored verbatim as the consent record. |
| Distribution | locked (contributed metadata cannot be edited by the tenant) or editable (contributions become ordinary tenant-editable metadata). |
| Marketplace package | A catalog listing (packageId, version, type, author, license, payload) that can be published for other tenants. Statuses draft and published. |
| Package type | One of application, plugin, connector, widget, theme, report-pack, workflow-pack, ai-pack, localization-pack, template-pack. |
Installed Plugins tab
The left grid ("Plugin catalog") lists every plugin id, with its publisher and version below the id, and a State chip:
| State chip | Meaning |
|---|---|
available (outlined) | Shipped with this build, not installed for the tenant |
installed (green) | Installed and active |
disabled (amber) | Installed but switched off |
The grid supports search ("Search plugins") and a State filter. The empty text reads "No plugins are available to this Studio build. Phase 21's marketplace distribution supplies catalogs; hosts embed plugin code at build time."
Banners above the grid:
| Banner | Shown when |
|---|---|
| "Installations unavailable: reason" | The installation list could not be loaded |
| Plugin diagnostics (code and message, warning) | The installed set has dependency or version problems |
| "Installed but not shipped with this build (contributions unavailable here): ids" | The tenant has an installation whose code this build does not contain |
| "Upgrade available for id: installed vA, this build ships vB - its contributions stay inactive until upgraded." | The installed version differs from the build's version |
| "reason - the catalog is read-only." | The user lacks the install capability |
Selecting a row opens the detail panel:
| Element | Description |
|---|---|
| Header | Plugin id, version chip, publisher chip, distribution chip |
| Warning | "This build does not ship this plugin's code - its contributions are unavailable in this session." when only the installation record exists |
| Contributes | One line per contribution kind with its count; blocks, actions and functions list their type or name |
| Network scopes | Addresses the plugin may reach |
| Depends on | Each dependency as id @ range with "satisfied by installed vX", "NOT satisfied - installed vX" or "not installed" |
| Buttons | Install... (not installed, code available), Upgrade to vX... (installed version differs and code available), Disable... (installed), Enable (disabled), Uninstall... (installed or disabled) |
| Data note | For plugins that declare a data-erasure hook: "Uninstall keeps this tenant's data" - the hook runs only on tenant offboarding |
| Configuration (JSON) | Text area pre-filled with the stored configuration (default {}); Save configuration is disabled while the JSON is invalid ("Not valid JSON") |
Consent panel (Install and Upgrade): title "Install id vX?" or "Upgrade id vA -> vB?". Content:
| Line | Meaning |
|---|---|
| "Register N kind" | Each contribution kind and its count |
| "Reach the network at scope" | One line per declared network scope |
| "Distribution: locked - its contributed metadata cannot be edited by this tenant" or "editable - contributions become ordinary tenant-editable metadata" | Distribution mode |
| Error alerts (code and message) | Dependency resolution failed, or an upgrade migration gate failed; the panel then only offers Close |
Buttons Approve & install or Approve & upgrade, and Cancel. An upgrade also runs the new version's upgrade migration hook before the upgrade is sent; if the hook fails, its message is shown and nothing is changed.
Impact panel (Disable and Uninstall): title "Disable id?" or "Uninstall id?". It lists the installed plugins that depend on this one ("Installed plugins depend on it: ..."), and the artifacts that use Blocks from the plugin (found through the where-used index): "N artifacts use Blocks from this plugin - uninstalling breaks them" for uninstall, or "new authoring loses these Blocks; existing usage keeps its saved definitions" for disable. When neither exists it says "Nothing depends on it and no artifact references its Blocks." Buttons Uninstall anyway or Disable anyway, and Cancel.
Marketplace Catalog tab
Two lists and a registration form.
| Panel | Content |
|---|---|
| Published catalog | Every published package across tenants: name, type chip, "packageId - vX - author - license", status chip. Packages of type template-pack, theme and ai-pack show Install |
| My packages | This tenant's own listings at any status. Drafts show Publish and Withdraw |
Register a new package form:
| Field | Type or values | Default | Required | Description |
|---|---|---|---|---|
| Package ID | Text | empty | Yes | Unique together with Version |
| Name | Text | empty | Yes | Display name |
| Version | Text (semantic version) | 1.0.0 | Yes | Malformed values are rejected |
| Package type | Select of the ten package types | widget | Yes | |
| Platform compatibility (erpVersion) | Text | * | Yes | Exact 1.2.3, caret ^1.2.0, tilde ~1.2.0, or * |
| Author name | Text | empty | Yes | |
| Author email (optional) | Text | empty | No | |
| License | Text | empty | Yes | |
| Description (optional) | Multi-line | empty | No | |
| Dependencies (JSON array, optional) | JSON | [] | No | For example [{"id": "acme.core", "versionRange": "^1.0.0"}] |
| Screenshots (one URL per line) | Multi-line | empty | No | Listing metadata |
| Changelog | Multi-line | empty | No | Listing metadata |
| Supported countries | Text, comma-separated ISO codes | empty | No | For example US, IN, AE |
| Supported industries | Text, comma-separated | empty | No | For example retail, manufacturing |
| Pricing | Select Free, Paid; with Paid an Amount (USD) field | Free | No | Stored as {"model":"free"} or {"model":"paid","amount":N,"currency":"USD"} |
| Populate from an existing Theme | Select and Populate (type theme only) | none | No | Fills the payload from one of the tenant's themes |
| Agents to include | Text of agent codes and Fill from AI Studio (type ai-pack only) | empty | No | Exports the agents with their tools, skills, memory and hand-over settings as the payload (no document text) |
| Payload JSON | Multi-line JSON | empty | Required for the listing to be installable | For example {"definitionJson": "..."} for a theme, {"portalName": "...", "portal": { ... } } for a template pack |
Register draft is enabled when Package ID, Name, Version, Author name and License are filled. The form clears after a successful registration.
Install results are announced in a banner: for a theme or template pack "Installed as a new theme draft "name" - review it in the Themes screen before publishing." (or the Portals designer); for an AI pack "Installed the AI pack "name": its agents are drafts in AI Studio (existing ones with the same codes were kept) - test and publish them."
Actions
| Action | Effect | API |
|---|---|---|
| Install (plugin, after consent) | Records the installation with the approved disclosure | POST /api/v1/authoring/plugins with pluginId, version, manifestJson, grantedCapabilitiesJson |
| Upgrade (after consent) | Replaces the manifest and version, keeps configuration | POST /api/v1/authoring/plugins/{pluginId}/upgrade |
| Enable / Disable | Sets state installed or disabled; disabling deactivates AI tools the plugin owns, enabling reactivates them | POST /api/v1/authoring/plugins/{pluginId}/enable and /disable |
| Uninstall | Marks the installation uninstalled and deactivates the plugin's AI tools; tenant data is kept | DELETE /api/v1/authoring/plugins/{pluginId} |
| Save configuration | Validates against the plugin's declared configuration schema when it has one, then stores | PUT /api/v1/authoring/plugins/{pluginId}/config with {"configJson":"{...}"} |
| Register draft | Creates a draft listing | POST /api/v1/marketplace/packages |
| Publish | Publishes a draft whose dependencies are all published | POST /api/v1/marketplace/packages/{packageId}/{version}/publish |
| Withdraw | Deletes an unpublished draft | DELETE /api/v1/marketplace/packages/{packageId}/{version} |
| Install (package) | Materializes the package in the tenant | POST /api/v1/marketplace/packages/{packageId}/{version}/install |
| List | Installed plugins; published catalog; own packages | GET /api/v1/authoring/plugins, GET /api/v1/marketplace/packages, GET /api/v1/marketplace/packages/mine |
Further plugin endpoints, not on this screen: POST /api/v1/authoring/plugins/upload (multipart .spk), POST .../{pluginId}/upload (upgrade with a new package; force=true overrides the upgrade guard), GET .../{pluginId}/health, GET and PUT .../{pluginId}/deployment (EMBEDDED or SERVICE), PUT .../{pluginId}/feature-flags, GET .../{pluginId}/audit-log, POST .../{pluginId}/rollback, POST .../{pluginId}/force-unload. Package reviews: GET and POST /api/v1/marketplace/packages/{packageId}/reviews (rating 1 to 5).
Procedures
Install a plugin shipped with the build:
- Open Extensions and select the row
acme.timesheet-extras(stateavailable). - Read the detail panel, then select Install....
- In the consent panel read the lines, for example "Register 2 blocks" and "Reach the network at https://api.acme.example", then select Approve & install.
- The row turns
installed. Paste a configuration such as{"defaultRounding": 15}and select Save configuration.
Remove a plugin safely:
- Select the installed plugin and Disable.... Read the impact panel; the artifacts that use its Blocks are listed.
- Select Disable anyway. Test the affected pages. Re-enable with Enable if they break.
- Only then select Uninstall... and Uninstall anyway.
Publish a theme as a package:
- Open the Marketplace Catalog tab. Enter Package ID
acme.theme-ocean, NameOcean, Version1.0.0, Package typetheme, Author name, LicenseMIT. - Choose the theme in Populate from an existing Theme and select Populate; the Payload JSON is filled.
- Select Register draft, then Publish in My packages. Other tenants can now Install it.
Statuses and lifecycle
Plugin installation:
| State | Transitions |
|---|---|
installed | Disable gives disabled; Uninstall gives uninstalled; Upgrade keeps installed |
disabled | Enable gives installed; Uninstall |
| uninstalled | Not shown; a new Install creates a fresh installation |
Each lifecycle change writes a plugin audit entry with the action INSTALL, UPGRADE, CONFIGURE, ENABLE, DISABLE, UNINSTALL or ROLLBACK, readable through GET /api/v1/authoring/plugins/{pluginId}/audit-log.
Marketplace package: draft to published; a draft can be withdrawn (deleted). Published packages cannot be withdrawn.
Permissions
| Operation | Capability |
|---|---|
| Install, upgrade, enable, disable, uninstall, configure, feature flags, rollback, force unload, deployment change, upload | INSTALL_PLUGINS on plugin |
| Register, publish, withdraw a package | PUBLISH_PACKAGES on package |
Install a package of type theme | AUTHOR on theme |
Install a package of type template-pack | AUTHOR on portal |
Install a package of type plugin | INSTALL_PLUGINS on plugin |
| Browse, read reviews, list installations, health, audit log | none |
Studio reads the actor's capabilities on load and disables the buttons with the title "Managing plugins is not permitted for your role" or "Publishing marketplace packages is not permitted for your role". The server enforces the same capabilities; a denied call answers Actor "x" lacks INSTALL_PLUGINS on plugin for tenant T.
API and CLI
bash
erp plugin list
erp plugin search timesheet
erp plugin install acme.timesheet-extras --manifest plugin.json
erp plugin publish ./dist/acme-timesheet-extras.spk --env prod
erp plugin force-unload acme.timesheet-extras
erp registry list --type theme
erp registry mine
erp registry publish acme.theme-ocean 1.0.0 --type theme --name Ocean --author "Acme" --license MIT --payload-file ocean.json
erp registry install acme.theme-ocean 1.0.0
erp tenant plugin list 7
erp tenant plugin enable 7 tenant-c-payroll --application HCM
erp api get /api/v1/authoring/plugins/acme.timesheet-extras/audit-logerp registry install for a package of type plugin installs the package whose payload names an spkFileId, through the same install pipeline as a package upload. erp tenant plugin install|enable|disable|list manage tenant extension bindings (/api/v1/platform/tenant-extensions), the runtime binding of remote extension services, which is distinct from the plugin installations shown on this screen. See CLI operations reference and Customize an installed plugin.
Limits and behavior
- The Installed Plugins tab installs the manifest-only plugins whose implementation ships inside this Studio build. Backend
.spkpackages are installed by upload or byerp plugin publish; their lifecycle (health, deployment mode, rollback) is exposed by the API above. - Package installs: only
template-pack,theme,pluginandai-packare installable. The Studio screen offers Install fortemplate-pack,themeandai-pack. Any other type answersOnly "template-pack"/"theme"/"plugin"/"ai-pack" packages install this way - "type" is not supported yet. - A theme or template pack installs as a new draft in the tenant; a theme name that already exists is made unique.
- Publishing requires every declared dependency to resolve to an already published package that satisfies its
versionRange. - Configuration is stored per tenant and survives upgrades.
- Uninstall never deletes tenant data.
- Pricing, plugin signing and security certification are not part of this release; the pricing field is stored as listing metadata only.
Errors and troubleshooting
| Message or symptom | Cause | Fix |
|---|---|---|
"x" is already installed for tenant T | Duplicate install | Use Upgrade or Enable |
pluginId, version, and manifestJson are required to install a plugin | Incomplete API call | Supply all three |
No plugin installation "x" for tenant T | Not installed | Install first |
configJson does not satisfy this plugin's declared configSchemaJson: ... | Configuration violates the plugin's schema | Correct the JSON |
| "Not valid JSON" under Configuration | Syntax error | Fix the JSON |
packageId, name, version, packageType, erpVersion, authorName, and license are required | Missing field | Fill the field |
Malformed semver version "x" / Malformed erpVersion range "x" | Bad version or range | Use 1.2.3, ^1.2.0, ~1.2.0 or * |
Dependency on "x" has an unparseable versionRange "y" | Bad dependency range | Correct the dependencies JSON |
Package "x" version v is already registered | Duplicate listing | Increase the version |
Cannot publish "x": unresolvable dependencies [...] | A dependency is not published | Publish the dependency first |
"x" version v is not a draft | Publish or withdraw on a published package | Register a new version |
This plugin package has no "spkFileId" payload | Plugin package without a file reference | Re-register with the payload |
uploaded JAR is for plugin "a", not "b" | Upgrade file belongs to another plugin | Use the right package |
plugin upgrade failed at stage S: message (reverted to vX) | The upgrade failed and was reverted | Read the stage and message |
"x" has no previous version to roll back to | Rollback with no earlier version | None |
| Upgrade panel shows only error alerts | Dependencies unsatisfied or upgrade gate failed | Install or upgrade the dependency, or fix the migration hook |
