Kevin

Plugin Architecture

Self-describing plugin manifests + lifecycle.

Plugin Architecture (v2026-09-30T104013Z-5e473105f4) 2026-09-30 | Self-describing plugin manifests + lifecycle. 1 - PLUGIN REGISTRATION - Plugin registration and discovery Plugin Developer curl -X POST http://localhost:8001/api/flo/register-plugin POST /api/flo/register-plugin GET /api/flo/services/{service_id} Daemon daemon/src/flo/flo_server.py POST /api/flo/register-plugin GET /api/flo/services daemon/data/plugin_registry.json plugin_registry.json service_id port url Plugin registr… Port allocatio… 2 - SERVICE ADVERTISEMENT - Service advertisement to Flo Plugin Service daemon/src/main.py asyncio.create_task(startup_tasks()) advertise(mqtt_client, ...) MQTT Broker localhost:1883 mx://flo/advertise mx://flo/registry MQTT Broker State retained messages service_id url flo_subjects Service startup Advertise to F… 3 - SERVICE DISCOVERY - Service discovery and communication Service A daemon/src/chip_api.py get_walt_url() httpx.post(f'{get_walt_url()}/v1/messages', json=payload) Service B daemon/src/main.py asyncio.create_task(startup_tasks()) advertise(mqtt_client, ...) MQTT Broker localhost:1883 mx://flo/advertise mx://flo/registry Query Flo for… Service B URL 1. Plugin Developer sends regi… 2. Daemon allocates port and r… 3. Plugin Service starts and c… 4. Plugin Service advertises t… 5. Service A queries Flo for S… 6. Service A calls Service B u… Plugin registration request { "service_id": "my_plugin", "desired_port": 9001, "flo_subjects": ["events/my_plugin"], "flo_alert_panel": "/ui/my_plugin" } Port allocation response { "service_id": "my_plugin", "port": 9001, "url": "http://localhost:9001", "mqtt_broker": "localhost:1883", "config": { "MQTT_HOST": "localhost", "MQTT_PORT": 1883, "SERVICE_PORT": 9001, "SERVICE_ID": "my_plugin" } } 25 of 25 identifiers appear only in design docs, not in code — this shows SPECIFIED behaviour, not verified implementation. The MQTT broker configuration is assumed to be running on localhost:1883. Service discovery relies on the MQTT broker's retained messages. Legend actor = initiates work · process = code path · store = state on disk · bus = durable queue · dashed = separate process cyan = request flow · pink = state read/write · dashed green = pull / return path · red = refusal As of 2026-09-30 10:40 UTC, from commit 5e47310

Provenance

This drawing is generated, not drawn. It is rebuilt from the source files below, so when they change the picture changes — a diagram here cannot quietly describe a system that no longer works this way.

Owner
Kevin
Slug
plugin-architecture
Rendered
2026-09-30T104013Z
From commit
5e473105f4
Updated
30 Sep 2026, 10:40 UTC
Sources at
5e47310
Watches
3 paths
  • plugins
  • daemon/docs/PLUGIN_ARCHITECTURE.md
  • daemon/docs/PLUGIN.md