Skip to main content
Version: 0.1.x

Component Positioning​

Plugin management connects two chains:

  • Development chain: Reads plugin sources from hack/config.yaml and synchronizes source plugins to the apps/lina-plugins/ workspace.
  • Runtime chain: After the core framework scans plugin manifests, the admin workspace handles discovery, installation, enablement, disablement, uninstallation, and upgrade.

These two chains have clear responsibilities. Code synchronization only means plugin files appear in the local workspace; whether a plugin is installed, enabled, or upgraded successfully is still determined by the core framework runtime governance records.

Plugin Source Configuration​

Plugin sources are configured in the plugins.sources section of hack/config.yaml at the repository root:

plugins:
sources:
official:
repo: "https://github.com/linaproai/official-plugins.git"
root: "."
ref: "main"
items:
- "*"
FieldDescription
repoPlugin source repository URL
rootRoot path within the source repository where plugins live
refBranch, tag, or commit
itemsList of plugins to install; "*" means all plugins

You can configure multiple sources, e.g. an official plugin source and an internal enterprise source. Commands support filtering via source=<name>.

Note

The current version only supports open repositories as plugin sources. Private repository and dynamic plugin source installation will be supported in the future.

Plugin Workspace​

apps/lina-plugins/ is the fixed plugin workspace. Official plugins are typically mounted as a Git submodule; if the project wants to manage plugin source code independently, it can first convert to an ordinary directory:

make plugins.init

This command disassociates the submodule while preserving existing plugin code. If the directory does not exist, it creates an empty workspace.

Note

This command is optional — the directory conversion is performed automatically during installation. After execution, apps/lina-plugins/ becomes an ordinary directory where you can directly add, modify, or delete plugin source code.

Installing and Updating Source Plugins​

Install plugins:

make plugins.install

Update plugins:

make plugins.update

Before updating, the tool checks for uncommitted local changes in the plugin directory. By default, local modifications block the update to prevent overwriting developer changes. If you need to force the update:

make plugins.update force=1

Check status:

make plugins.status

The status output shows plugin ID, source, version, local installation state, local modification state, and remote sync status.

Admin Workspace Lifecycle​

After plugin code enters the workspace, the core framework scans plugin.yaml at startup and presents the plugin as "Discovered". The administrator then performs runtime lifecycle operations in the Extension Center:

OperationRuntime behavior
InstallCheck dependencies, run installation SQL, write plugin governance records
EnableProject menus, permissions, routes, hooks, scheduled tasks, and frontend resources
DisableHide menus and business routes; preserve data and governance records
UninstallClean up governance records; optionally preserve or clean up plugin-owned data
UpgradePreview, confirm, migrate, switch version, and invalidate cache for the target plugin

The distinction between disable and uninstall is important: disable only removes the runtime entry point while data remains; uninstall enters a cleanup flow, and if data cleanup is chosen, plugin-owned data may be unrecoverable.

Dynamic Plugin Upload​

WASM dynamic plugins do not depend on the source workspace for delivery. The build artifact is a .wasm file; after the administrator uploads it in the Extension Center, the core framework validates the artifact and reads the embedded manifest, routes, resources, and authorization declarations.

During dynamic plugin installation, the administrator must confirm hostServices authorization. Only after authorization confirmation does the core framework allow the plugin to access the corresponding core framework services and resource scope through pluginbridge.

Runtime Upgrade​

After plugin files are updated, the core framework may detect that the "effective version" and the "discovered version" are inconsistent. At this point the plugin enters a runtime upgrade state:

StateDescription
normalEffective version matches discovered version
pending_upgradeA higher version has been discovered, awaiting explicit administrator upgrade
upgrade_runningUpgrade in progress
upgrade_failedUpgrade failed; the old effective version is retained with diagnostics recorded
abnormalFile version is lower than the effective version or state is anomalous, requiring manual intervention

Before upgrading, you can view a preview including version diff, dependency check, SQL count, hostServices diff, and risk warnings. During upgrade execution, the core framework performs confirmation validation, acquires the runtime upgrade lock, runs lifecycle callbacks, executes upgrade SQL, synchronizes governance resources, switches the effective version, and refreshes the cache.

Multi-Tenant Governance​

Tenant-aware plugins can choose between global enablement or tenant-scoped enablement:

ModeBehavior
globalPlugin is installed and enabled once, effective for the platform or all tenants
tenant_scopedPlugin can be enabled or disabled per tenant

The specific enablement strategy is determined by the core framework governance records and the multi-tenant plugin, not by the frontend alone.

Best Practices​

  • After synchronizing plugin code during development, still install and enable the plugin in the admin workspace.
  • Check for local changes before updating plugin source code — avoid accidentally using force=1 to overwrite development work.
  • After uploading a higher version of a dynamic plugin, do not assume the new version is active — a runtime upgrade must be performed.
  • Before uninstalling a production plugin, confirm whether to preserve data and check for reverse dependencies.
  • Pin plugin sources to stable branches, tags, or commits — avoid using uncontrolled floating versions in production.