The server round-trip (render_bridge + is_driven + send_sync + POST) could never
detect the common driver: ComfyUI inlines a Primitive's value as a literal in the
prompt and strips the node, so is_driven (which looks for a [id,slot] link) was
blind to it — nothing drove. Proven in a live ComfyUI via browser automation.
Replace it with a client-side approach:
- getAngles() reads a connected input's value by following the graph link to its
source (Primitive/static), else the widget — a connection wins over the control.
- A graphToPrompt wrapper refreshes each node's render_b64 from current values
before every run, so the driven value (incl. increment animation) is baked into
the image for that queue. execute() just decodes render_b64, unchanged.
- heading/city (hidden behind the compass/search overlays) are auto-exposed as
input sockets via convertWidgetToInput, guarded against reload double-convert;
their manual controls still drive when unconnected. Persistence verified across
save/reload.
Removes render_bridge.py, js/driven.js, is_driven, the hidden node_id/prompt
inputs, renderWith, and their tests. Verified end-to-end (real queue, output
brightness tracks driven intensity 0.3->133, 3.0->255) in the live ComfyUI.