A template or negative box wired to a subgraph input showed an empty row on the subgraph node. The subgraph node now gets the full editor, reading and writing the value ComfyUI keeps for the promoted input.
A new eye button beside Load, Save and Clear marks every upstream variable that neither the template nor the negative template reads as internal. Assemblers below each writer are checked first and keep what they read; a Context module is flipped only when none of its variables is in use. Undo in the toast puts every widget back unless it was edited since.
Widgets marked data-wp-reveal get a wp-reveal event with the target before the blink looks: Context unfolds the bundles around the module, Toggles its label groups, the Injector its folded row list. Subgraphs are entered, never unpacked. The trace link underlines only its word.
WP Context uses the kit's row-drag gap and line (bundle-coloured inside a bundle); a dragged bundle dims; a closed bundle takes drops on the middle of its header and opens.
Bump @dumiflex/wp-kit to 0.19.0. Toggles and the Context Injector drag on the kit's useRowDrag; Toggles groups reorder and toggles can drop below a group; grid tiles size to their content.
- Group layout is a grid button beside the icon and colour buttons.
- Control and output dots' tooltips say the toggle's name.
- A merged socket line says how many go in and out, names on hover.
- A Buttons toggle takes two tiles once two fit.
- A folded group keeps its toggles' input dots on its title.
- Socket carets line up with the group carets; control icons use the
rows' colours.
- Dots are placed from the layout, so a row being dragged doesn't drag
them along.
Rows or Grid for the node and for each group, in both modes and every style. Grid tiles wrap to the node's width; wired toggles' dots sit on thin socket lines under a group's tiles, control dots packed on the left and outputs on the right, and a group's lines merge into one like the Context Injector's merged wires.
A toggle can say what its variable writes while off, with its own negative. Either a Value or an Off value makes the variable hold text; with neither it writes true/false. $name.bool reads the switch either way.
Wildcard steps list their options with weights and why each was cut, the pool chain, locked seed, separator and matched value; fixed values, combines and node templates show what they read; constraint steps link the steps they re-weighted; Model Info, Toggles, Injector and Context Loop rows carry their own facts.
lookup_var reads $name.bool from the toggles' on/off table; example 2's Var → Bool reads $quick_preview.bool since the Quick toggle's Value (12) now fills $quick_preview. Tests, docs note and release-notes line.
Variables grouped into per-node cards with kind squares, module facts, toggle true/false and value + .bool, Injector type chips, Loop frame line; long values fold until Show all; .axis/.bool/tags as kit chips. Trace stays numbered run order. Show node blinks the module or field on the canvas. Grouped right-click menus with a kind header. Loop trace rows, node warning labels and links.
A toggle with a Value writes it to its variable while on and nothing while off; its Negative goes with the variable. $name.bool reads the switch (true/false) across nodes, in text and in conditions, through __wp_toggle_bools__. Payloads reading $name.bool stamp schema 12; bool is reserved as a tag group.
Each toggle's settings open in a kit Modal: name, variable, looks (icon, icon/name/control colours on kit IconPicker and ColorField), Pick one value and negative, style, needs, when off. The header and the row wear the toggle's looks; the icon is a column beside the name and $var. Labels take an icon and colour. Window warnings use the kit Banner. Bundle guide raised to 670 KB.
* feat(note): pick any extension picture, and keep the Pictures panel open after adding
* feat(note): show the extension's pictures only once you search
* feat(note): preview the note as the node draws it, and let the icon picker fill the editor
The text and a live preview move into a window like the module editors
(NodeEditWindow, shared with the Toggles editor). The node keeps tone,
look, colour, title, pin and the bookmark settings. An open Note or
Bookmark editor now lets presses on its background through, so the node
drags.
Graph walkers marked every WP Toggles variable internal, so the Assembler
showed none. Each toggle now has a globe (internal by default), Pick one
gets a node-wide style, the Value field is a rich input that warns about
inline picks and missing variables, and toggles drag into and out of groups.
Tailwind 4's preflight resets padding, margin and border on every element in @layer base, which ranked above the kit's @layer wp-extension, so the Popover lost its padding (Test Runner picker flush against its edges). layers.css, imported first, ranks wp-extension above base.
* feat(tutorials): in-depth Context Loop, Context Injector and Image Filter videos
N05 walks the whole Context Loop (frames vs batch size vs Run count, Edit
frame chips, Override Context seed, strategies, the seeds panel, Ctrl/Alt
click, values, a rule on $iteration, Seed List, Hold, Bypass loop). N04
takes the Context Injector apart and N12 the Image Filter (labels, prompt
edits with clip, the mask painter, Compare, Zoom, Send to Loop, the node's
settings). The old Nodes videos move to their new numbers (Debug N03,
Label & Grid N13, Note N14, Bookmark N15); N12 replaces the old N01.
* fix(tutorials): tick both rows in T03's bulk edit
The selection bar slides in after the first tick and moves the rows, so the
second click could land where its row used to be. Tick one row at a time and
check each one took.
* fix(tutorials): scroll T05's rules into view before boxing them
scrollTo now falls back to scrolling the part's own scrolling box when the
wheel doesn't move it, and T05 scrolls each branch (and the second action)
to the upper screen before its callout, so the boxes are on screen.
* fix(tutorials): narrate T06's canvas build so it plays at normal speed
The two builds had no line, so the render squeezed them to 4.5x and the
hand looked rushed. A line over each keeps them at normal speed.
* fix(tutorials): a hand at work plays at most 2x in the render
The Tutor now records when the hand clicks, drags, types or presses a key
(cues.json acts), and render.mjs speeds a silent stretch with hand work up
by at most 2x instead of up to 8x, so builds don't look rushed. The ten
longest silent builds (T04, A04, A05, A06, A09, A10, A12, L03 and two in
N14) get a line, so they play at normal speed.
* fix(tutorials): give N04's Injector room beside the stand-in nodes
The Injector landed on the first text box and covered its output, so the
first wire never connected. The stand-ins sit further right, the Injector
further right still, and the canvas slides left before the Context step.
* fix(tutorials): keep both ends of N12's new wires on screen
The mask wire was dragged from the filter to a node that had scrolled off
the top, so it dropped on empty canvas. The canvas now fits the nodes of
each wire into the free part of the screen first, and the new Set Latent
Noise Mask goes under the refine sampler.
* fix(tutorials): N05 and N04 fixes from the first takes
N05: zoom in on the Seed List while it's talked about (it sat under the
caption), and drop the callout labels that covered the frame chips and the
template. N04: narrate the Context / Assembler / preview build (36 s of
silence) and move the hand off the rows so the globe tooltip closes.
* fix(tutorials): paint N12's mask on the painter's canvas
In paint mode the mask painter replaces the detail image, so the strokes
aimed at an image that was no longer there.
* fix(tutorials): a single click doesn't hold a long wait at 2x
A Run click followed by a long wait counted as hand work, so the wait played
at 2x instead of being squeezed. A stretch now needs two or more hand
actions to be capped.
* fix(tutorials): tuck N12's picker away with its minus button
Escape in Detail goes back to the grid instead of tucking the picker away,
so the waiting pill never showed.
* fix(tutorials): box N12's two extra slots as a pair
The callout took one locator matching both slot dots, which strict mode
refuses.
* fix(image-filter): keep the picker's keys after a view change
Switching mode or leaving the painter removed the focused control and dropped
focus to body, so the picker's keys went to the canvas bookmarks. Focus goes
back to the picker. N12 hands the keys back before Compare and Zoom.
* fix(tutorials): L05 waits for Role's save to store a history entry
* fix(tutorials): a few clicks across a long wait don't cap the squeeze
* fix(tutorials): review 2026-11-11 first half (lines over empty canvas, late boxes, N12 framing)
* fix(tutorials): review 2026-11-11 A09-A19 findings
* fix(tutorials): review 2026-11-11 L03, L05, N14, E4 findings; jumpTo keeps tall notes above the caption
* fix(tutorials): A06 and T05 build their Context before the line
* fix(tutorials): N14 keeps the label's peek open through its line
* fix(tutorials): N12 boxes the extra slot rows; callouts fall back to the raw box
* fix(tutorials): N14 hovers the label before its line
* fix(tutorials): N14 keeps the hover card up while its line plays
The editor's tools (text toolbar, bookmark zoom box) need about 358 px and
the editor opened at 340, so they spilled past the edge. FORM_WIDTH is
360, the toolbar wraps on a narrower note, and the fitted size goes
through setSize so Nodes 2.0 hears it.
Restores clicks on a note's own buttons and links in Nodes 2.0 (specificity regression from #328), and lets the wheel scroll a long textarea under the wheel shield even when Firefox reports its overflow as visible.
Hidden rows inside a collapsed bundle no longer raise the WP Context width floor, and a collapsed bundle's header shows a dot for the worst conflict and library state among the rows it hides.
While a WP Note is being edited, the frameless pass-through gives the pointer back to the editor (legacy and Nodes 2.0), so Firefox's overlay scrollbars respond on hover. It takes it again when editing ends.
Without a Context the preview said '(template empty or unresolved)' about
text with nothing to resolve. It now reads 'plain text', counts $names
nothing sets as unresolved, and the empty variables row explains itself.
The negative row's line height no longer clips descenders.
The last-execute strip decided 'has run' from a non-empty source text or
a choice note, so Var → Int / Float / Bool reading an unset variable kept
saying 'run workflow to see result' instead of the amber default. The
host now passes an executed flag, and the strip names the unset variable.
In the legacy renderer every DOM widget sits in one layer over the
canvas, and ComfyUI's own clipping only cuts out the selected node, so a
WP panel showed through any node dropped on top of it. On each canvas
draw, each WP widget now gets a clip-path that leaves out the nodes
drawn after its own. Cleared under Nodes 2.0.
* fix(bundles): fill a child's missing payload hash so a new bundle isn't drifted
A bundle child saved without payload_hash (hand-made or imported packs,
like the tutorial library) came onto the canvas with no hash, and the
canvas reads a hashless row whose id is in the library as drifted. GET
now gives such a child the hash of its own payload.
* docs(release-notes): bundle children no longer drifted on insert
The Focus button on an unresolved-Assembler warning now opens the graph the node lives in (into a subgraph or back out to the root) before centring, selecting and flashing it, through a shared showGraph helper the Debug viewer's Show node uses too. The pre-run scan starts from the root graph, and the flash re-finds the Nodes 2.0 element once it is drawn.
Import / Export gets a Wildcard files (.zip) button: picks become Dynamic Prompts / Impact Pack .txt files (engine/wildcard_export.py, POST /wp/api/export/plain), with a README listing what has no plain form. The community site vendors the exporter.
* fix(extension): explain an empty wildcard pool when no option has tags
* feat(wildcards): filter a wildcard's pool by a run-time variable
A $name term in a Pool filter or a reference filter reads the variable
when the prompt runs: options tagged with its value stay, options with no
tag in that value's group stay too. An unset variable or a value that is
no tag on the wildcard drops that term and files filter_variable_no_tag.
Constraints still apply on top. Stamps schema 11 (MAX_KNOWN 11).
* test(syntax): cover the filter variable helpers in the syntax suite
Current frontends give nodes text ids ("-10") and the root graph a UUID id, so walkers never crossed a subgraph's edge: variables set outside showed as missing inside. Nodes 2.0 only read the subgraph badge when a node rendered; each SubgraphNode now gets one badge getter up front and a change bumps a revision on ComfyUI's own reactive store. The Context Loop and Seed List chevrons sit at the right edge, level with the label.
The preview dropped 11 instance keys the engine reads (constraint reach, cell/exception overrides, derivation branch edits, hold seeds), so it could show picks the run never makes. A test now checks the whitelist against the engine handlers.
Picking a LoRA inside <lora: inserted only the path, leaving no weight and no closing bracket. Commits now close the reference (or keep an existing weight), absorb a < the user typed, and rewrite <embedding:...> into embedding:name.