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; the host installs it before activate(hc) runs. 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 tears down tracked registrations automatically, then calls
deactivate()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 that the host tracks automatically on deactivation. Dispose custom resources (timers, focus sync, etc.) in deactivate() or React effect cleanup.
See Permissions for the capability model and Dev workflow for unpacked development loading.
