Files
wizardchen d628fdf38f feat(plugin): standalone plugin hosts with Redis discovery
`WeKnora plugin-host` runs host plugins outside the app processes. It needs
no Kubernetes: it shares the app's database, object storage, Redis and
SYSTEM_AES_KEY.

Plugin host:
- Loads the installed host plugins of the kinds it runs
  (WEKNORA_PLUGIN_HOST_KINDS). It never migrates the database.
- Every 5s it announces itself and its plugins in Redis
  (weknora:plugin-host:<node>, TTL 15s).
- Serves its plugins at /p/{id}/{version}/... through a gateway. Calls must
  be HMAC-signed with a key derived from SYSTEM_AES_KEY (or JWT_SECRET);
  streams are relayed as they come.
- On shutdown it withdraws first, then lets calls in flight finish.
- Its node reports appear in the plugin's node list as `plugin-host:...`.

App nodes:
- Run the kinds WEKNORA_PLUGIN_EMBEDDED_KINDS names (default: every kind the
  machine can run; "none" hands all to plugin hosts).
- Call other host plugins on the least busy plugin host that runs the
  active version.
- A kind with no plugin host configured fails the load with the reason.
  With hosts configured, a missing one is a retryable "unavailable".
- Local plugins always get the loopback Host API address.
  WEKNORA_PLUGIN_HOST_API_URL is for plugins elsewhere, which also skip
  their egress proxy for that host.

Also:
- The reconciler takes runtime and manifest filters and a node role.
- The SDK client gains Raw for relaying.
- Deployment: a compose `plugin-host` profile, a Helm `pluginHost` Deployment
  (pods advertise their IP, app pods get the embedded kinds and Host API
  URL), .env.example entries.
- A plugins page in the docs site.
2026-09-26 10:19:25 +08:00
..