Add the connector contract, reusable nodes and per-port intervals

Connectors are the device-facing node class third parties write, so the
surface they build against is versioned and documented: ConnectorNode carries
a declared contract version, a polling loop that publishes only what changed
and reports health around it, and parameters whose credential fields are
marked x-secret so the editor offers the secrets store instead of a text box.
They are found through the fluksio.node_types entry point group, with the
package's own metadata as the manifest. docs/connectors/ has the contract and
the authoring guide; connector-skeleton/ is a working one to copy.

The controller no longer knows what any node type is: start, stop and
report_health are protocol methods on Node, and the built-ins were migrated to
them first, so the hooks a connector implements are the ones the engine has
been driving all along.

Marking a node reusable moves its source to _lib/ and points the node at it by
name. Other flows instantiate it with their own ports and settings, one fix
reaches all of them, and a shared source still in use cannot be deleted.

Ports gained an interval: an output publishes, and an input wakes its node, at
most every n seconds. State keeps the latest value, so only the delivery is
skipped, and pressing Run is never throttled.

Also fixes autosave sending no version on its first save of a session, which
made every flow saved more than once conflict with itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Melvin Strobl
2026-08-15 23:57:44 +02:00
co-authored by Claude Fable 5
parent 7344eac262
commit 3724b68f23
22 changed files with 1541 additions and 62 deletions
+15 -6
View File
@@ -42,11 +42,15 @@ external interfaces. See `docs/architecture/structure.canvas` → *Backend M
- [x] Secrets/credentials store for node integrations managed via the API/UI
(encrypted at rest, referenced from node params as `{"$secret": "name"}`);
`.env` bootstrap-only
- [ ] Connector node contract: declared I/O schemas, UI-driven credential and
setup flow, polling/discretization behaviour, health reporting, packaging
metadata — plus an authoring guide and skeleton repo. Device-specific
nodes are written against it as external plugins; the registry follows
later
- [x] Connector node contract: `ConnectorNode` with a declared contract version,
a polling coordinator that deduplicates, `x-secret` parameters the editor
renders as a secret picker, and health reporting. Connectors are installed
packages found through the `fluksio.node_types` entry point group; the
contract is documented in `docs/connectors/` with a working skeleton at
`connector-skeleton/`. The registry follows later
- [x] Node lifecycle as a protocol (`start`/`stop`/`report_health` on `Node`),
replacing the controller's per-type isinstance chains — the same hooks a
connector implements, validated on the built-in nodes first
- [x] Flow persistence: `flow.json` plus node sources per flow, replacing the
watch-directory prototype
- [x] REST + WebSocket API over the engine: create/read/update flows, edit node
@@ -64,7 +68,9 @@ external interfaces. See `docs/architecture/structure.canvas` → *Backend M
draft. Saves carry the version they were based on, so a second client
editing the same flow is refused rather than overwritten
- [ ] Import/export of a flow as human-readable code plus a JSON structure
- [ ] Per-input/-output discretization interval setting
- [x] Per-input/-output discretization interval setting: a port publishes, or
wakes its node, at most every n seconds. State keeps the latest value, so
only the delivery is skipped
- [ ] Alert / notification handler
- [ ] Test nodes: a small node dragged onto an existing one, smoke or unit, blocking
deployment on failure
@@ -99,6 +105,9 @@ React + Vite, primarily desktop but usable on mobile. See `docs/architecture/str
- [x] Validation shown on the node it belongs to, and summarised in the dock
- [x] Publish control and draft markers in the flow bar, discard in the flow
panel, and a conflict dialog when another client got there first
- [x] Marking a node reusable, and placing a shared one from the palette
- [x] Secret picker for credential parameters, so a password never lands in
`flow.json`
- [x] Dashboard showing which flows run, which are stopped and which have
errors, with a switch per flow
- [x] Logs panel in the canvas dock, pause/resume beside Run, and replaying an