SDK Architecture
This document is the canonical architecture reference for@anikitenko/fdo-sdk.
Runtime Model
The SDK spans two runtimes:- Backend/plugin runtime:
- plugin class lifecycle (
init, handlers, stores, logging) - communicator and host IPC handling
- persistence and diagnostics
- plugin class lifecycle (
- Iframe UI runtime (FDO host managed):
- plugin UI code produced by
render() - host-injected browser/UI helpers
- React-hosted iframe render pipeline
- plugin UI code produced by
Lifecycle Model
Primary plugin lifecycle:init():- setup and registrations
- may fail; communicator returns stable failure payload
render():- returns UI source string
- serialized for host transport via explicit SDK methods
renderOnLoad():- optional payload for UI on-load behavior
- supported authoring forms: source string, function, or
defineRenderOnLoad(...)module
serializeRender()serializeRenderOnLoad()
Message Flow
Inbound host messages are validated in runtime contract validators:- envelope validation (
MESSAGE_TYPE, payload shape) - UI message payload validation (
handler,content)
PLUGIN_READYPLUGIN_INITPLUGIN_RENDERUI_MESSAGE
PLUGIN_INIT may include an optional content.apiVersion from the host. The SDK validates the value and enforces major-version compatibility against FDO_SDK.API_VERSION.
PLUGIN_INIT may also include content.capabilities to opt in privileged features for that plugin instance.
Failure behavior:
PLUGIN_INITfailure: empty capabilities +errorPLUGIN_RENDERfailure: fallback error UI +errorUI_MESSAGEfailure:{ error: string }
Storage Model
Storage is plugin-scoped throughPluginRegistry.useStore(...).
defaultstore:- in-memory
- scoped by plugin identity
jsonstore:- persistent
- requires explicit storage root (
configureStorageorFDO_SDK_STORAGE_ROOT) - path is namespaced by plugin scope
init(context)flush()dispose()- optional capability metadata and migration/version hooks
- privileged SDK features are capability-gated (
storage,storage.<backend>such asstorage.json,system.network,system.network.<transport>such assystem.network.https,sudo.prompt,system.hosts.write,system.fs.scope.<scope-id>,system.process.exec,system.process.scope.<scope-id>) - host grants are configured via
PluginRegistry.configureCapabilities(...)(usually through validatedPLUGIN_INITpayload) - diagnostics include granted capabilities and usage/denial counters for auditing
- diagnostics also include SDK handshake metadata (
sdkVersion,apiVersion, capability schema version, feature flags) for host compatibility gating - hosts should evaluate this handshake contract with
evaluateSdkHandshakeCompatibility(...)instead of ad hoc version checks
- SDK defines a strict contract validator for host privileged requests (
validateHostPrivilegedActionRequest) - current action contracts are intentionally scoped (
system.hosts.write,system.fs.mutate,system.process.exec) - host must enforce confirmation, path/command boundaries, and auditing; plugins should not receive generic arbitrary-write permissions
Validation Boundaries
Runtime validation currently covers:- plugin metadata (including BlueprintJS v6 icon name)
- serialized render payload shape
- host message envelope shape
- UI message payload shape
Extension Points
Stable extension points for plugin authors:FDO_SDKlifecycle methodsPluginRegistry.registerHandler(...)PluginRegistry.useStore(...)- mixins (
QuickActionMixin,SidePanelMixin) - DOM helper modules for UI-source generation
Internal Boundaries
Internal modules that should not be treated as public plugin API contracts:- communicator implementation details
- private registry internals
- store internals prefixed with
_fields - decorator internals outside documented behavior
Design Constraints
- prioritize predictable host/plugin boundaries over convenience
- avoid runtime assumptions leaking between backend and iframe contexts
- keep metadata, transport, and store contracts explicit and machine-readable
- preserve deterministic behavior in failure paths