Architecture and Boundaries
Applies to PCL N Plugin SDK 0.2.5.
SDK
0.2.5· Product runtime: PCL N Desktop (AOT) + PCL.Plugin.Sidecar (CoreCLR)
PCL N Desktop (AOT host — no third-party plugin IL)
└─ PluginSidecarSupervisor / length-prefixed JSON IPC
└─ PCL.Plugin.Sidecar (CoreCLR process)
├─ Validate and install .pnp packages
├─ Stable services + UI data-chain
├─ Dependencies, lifecycle, safe mode, uninstall
└─ Shared PCL.N.Plugin.Abstractions ABI
└─ Third-party plugins (unloadable ALC inside Sidecar)Layers
| Layer | Responsibility | Third-party reference? |
|---|---|---|
| PCL N Desktop | Launcher UI, Minecraft features, generic UI render, sidecar supervision | No |
| PCL.Plugin / Sidecar | Load, security, market, recovery, host bridges, UI manifest/trees | No |
| PCLN.Plugin SDK | Public ABI, tooling, analyzers, tests, packaging | Yes |
PCL.Plugin is private. Plugins only depend on public NuGet packages (PCLN.Plugin.Abstractions, …).
Product runtime (required reading)
- Host is AOT by default — release builds of
PCL-N-Editiondo not embed third-party plugin IL. - Plugin platform runs in Sidecar —
PCL.Plugin.Sidecaris supervised by the host over IPC (catalog, install, UI data-chain, feedback, …). - Plugin ABI is unchanged — implement
IPclNPluginand usecontext.Services; never referencePCL.DesktoporPCL.Plugin. - UI — settings/plugin pages are driven by Sidecar data-chain (manifest / page tree / actions); the host injects navigation and renders generically.
- Legacy in-process overlay (
PclWithPlugin) is for debug/special builds only, not store distribution.
Host implementation notes live in the main repository:
docs/architecture/plugin-sidecar-ipc.mddocs/architecture/native-aot-desktop.md
Forbidden dependencies
PCL.ApplicationPCL.DesktopPCL.Plugin- Launcher private DI containers
- Private CLR namespaces or reflection into host internals
Analyzers PNPSDK001–003 and PNPSDK006 enforce this at compile time.
Allowed interaction
IPluginContextand stableIPluginServiceIDs- Public DTOs such as
PluginInstanceInfo - Capabilities (for example settings pages)
- Manifest-declared services, permissions, dependencies, and UI
- Host-published surfaces/slots
- Plugin private directories from
context.Directories IPluginPackageAssetServicefor read-only files from the installed signed package (file-table + SHA-256)
Load isolation
Inside the Sidecar process, each plugin uses a collectible AssemblyLoadContext:
- Abstractions are shared from the default context so ABI type identity matches
- Private managed dependencies resolve from the plugin package
- Native libraries probe
runtimes/<rid>/native/ - Stop releases registrations and attempts unload
ALC isolation is not a security sandbox. Signing, permissions, review, and user trust remain mandatory.
Why declarative UI
Direct Avalonia visual-tree mutation couples plugins to control internals. Surfaces/slots and the Sidecar data-chain keep contracts as stable IDs, version ranges, and data nodes so the host can enforce permissions, resolve conflicts, apply safe mode, and revoke contributions on unload.
