When a Saver's load_saved / prompt_lists were promoted to subgraph inputs, changing them on the subgraph node never ran the Saver's callbacks: the prompt didn't load, the list didn't refilter, and the outer dropdowns kept a stale snapshot of the options. - Add js/subgraph_widgets.js (pure module): find the widget that supplies a value through nested subgraphs, and hook the subgraph node's outer widget callbacks to forward changes to opted-in nodes inside. Re-hooks on widget-promoted and when the frontend silently rebuilds an outer widget (input._widget slot watcher). - Saver mirrors the outer widgets: outer changes run the normal callbacks; inner values and option lists are pushed back out, including to a Primitive feeding the subgraph node. Unchanged values are ignored so a Primitive's per-queue re-apply doesn't reset the selection. - Save / Delete / load use the outer list name when promoted. - Add plain Node tests (tests/), a mock workflow loader and the bug-report workflow as a fixture. - Rename AGENT.md to AGENTS.md; document promoted widgets, testing and README style. - Bump version to 1.8.1.
Tests
Plain Node tests for the pure JS modules (no npm dependencies, no browser, no ComfyUI).
node tests/subgraph_widgets.test.mjs # promoted subgraph widgets: source lookup + change forwarding
Each script exits non-zero on failure.
Files
workflowLoader.mjs-- mockLGraph/LGraphNodestand-ins (MockGraph,MockNode,makeContainer) andloadWorkflow(workflow), which builds them from a serialized workflow (UI format 0.4, root +definitions.subgraphs). Widgets come fromwidgets_values_named; a container's widgets are its promoted inputs, valued from its ownwidgets_values_named, with a callback that only stores the value (like the frontend's store-backed outer widgets). Adapted from ComfyUI-Enhancement-Utils.subgraph_widgets.test.mjs--js/subgraph_widgets.jsagainst the fixture below and hand-built nested subgraphs: the widget that supplies a value (own widget, outer widget, outermost widget through nesting, unknown when the outer input is fed by another node), the nodes a container input feeds, wrapping / re-wrapping outer widget callbacks and forwarding changes to opted-in nodes.fixtures/saver_subgraph_promotion.json-- the workflow from the subgraph bug report. One subgraph with two Prompt Stash Savers: "Promoted to subgraph" hasload_saved/prompt_listslinked to subgraph inputs (outer valuesSystemPrompt Klein 9B/WAN Video Prompts, stale inner valuesNone/Flux); "Primitive inside subgraph" is driven by two Primitive nodes inside the subgraph.
Limits
The mocks cover graph structure only. Frontend behaviour still needs checking by hand (see "Testing" in AGENTS.md): that both renderers call the outer widget's callback, that writing .value / .options on it updates what is shown, and Vue re-rendering.