Architecture
Two runtimes
Plugins can ship a renderer entry, a main entry, or both:
| Entry | Runs in | Purpose | Sandbox |
|---|---|---|---|
| renderer | Renderer (React) | Settings panels, sidebar UI, request tabs | No SES — contextIsolation plus IPC-only hc |
| main | utilityProcess + SES | HTTP hooks, custom IPC, background logic | SES lockdown() in the child process only |
Renderer UI uses hc.react, the host's React instance. Do not bundle React in your plugin; call installReact(hc.react) and use the JSX runtime documented in React and JSX.
Main-process plugin code reuses the same utilityProcess script runner infrastructure as request scripts. lockdown() runs only in that child process — never in the Electron main process or renderer.
Lifecycle
- Install — HarborClient unpacks the
.hcpfile touserData/plugins/<id>/, validatesmanifest.json, and shows a permissions confirmation dialog. - Discovery — On startup, HarborClient scans
plugins/*/manifest.jsonfor installed plugins and reloads any unpacked plugin paths saved from development sessions. - Activation — Plugins activate lazily (for example when the user opens a contributed settings section). The host loads the entry module and calls
activate(hc). - Deactivation — On disable or unload, the host disposes all entries in
hc.subscriptions, then callsdeactivate()if exported. - Uninstall — Removes an installed plugin directory and clears stored enablement state. Unpacked plugins are removed from the dev registry only; your source folder on disk is not deleted.
Registrations from hc.ui.* and similar APIs return disposables. Push them onto hc.subscriptions so the host can clean up automatically on deactivation.
See Permissions for the capability model and Dev workflow for unpacked development loading.