Resolves `AttributeError: 'DifferentialDiffusion' object has no attribute
'execute'` on older ComfyUI (<0.3.63) where the V3 schema migration has
not landed yet. The prior code called `.execute(model)[0]` directly,
breaking anyone still on the legacy `.apply(model)` API.
Introduce `modules/impact/utils.apply_differential_diffusion(model)`
which uses `hasattr` to pick the correct branch at runtime:
- `.execute` -> V3 classmethod (ComfyUI >= 0.3.63)
- `.apply` -> legacy instance method (older)
- otherwise -> AttributeError with upgrade guidance
Replace all 7 direct call sites (animatediff_nodes, core x2,
impact_pack x2, segs_nodes, segs_upscaler) with the helper. The
existing import guard in segs_upscaler is preserved; the helper's
deferred import means ImportError still propagates for very old
ComfyUI builds without `comfy_extras.nodes_differential_diffusion`.
Fixes GitHub issue #1177.
Also add an E2E test harness:
- docs/E2E_TEST_STRATEGY.md — isolated-launch workflow with
--disable-all-custom-nodes + --whitelist-custom-nodes, Playwright
smoke test, workflow execution via /prompt + /history + /view,
verification criteria, operational notes.
- tests/e2e_dd_compat.py — reference test that runs SEGSDetailer
with noise_mask_feather=20 on a real input image, asserting
status==success and non-zero pixel delta between input and paste
previews (proves the detailer loop and compat shim actually ran).
- Move readLinkedNumber, getDrawColor, computeCanvasSize to common.js
- Import shared functions in mask-rect-area.js and mask-rect-area-advanced.js
- Remove duplicate implementations from both MaskRectArea modules
- Clean up unused debug parameter in syncLinkedInputsToProperties
## Overview
This PR improves both MaskRectArea and MaskRectAreaAdvanced nodes by allowing them to accept values from connected INT nodes, while preserving backward compatibility with existing workflows.
It also fixes several UI and preview issues that prevented the canvas from updating correctly when values were driven by links.
Fixes#1126
## Key changes
### 1. Typed INT inputs support (backend)
- Both MaskRectArea and MaskRectAreaAdvanced now declare proper INT inputs in INPUT_TYPES.
- This allows parameters such as x, y, width, height, and blur_radius to be driven directly by other nodes.
- Existing workflows that relied on node properties remain supported via fallback logic using extra_pnginfo.
### 2. Live preview correctly updates when inputs are linked (frontend)
- The canvas preview now updates immediately when values come from linked INT nodes.
- This is achieved by synchronizing linked input values into node.properties during canvas rendering, avoiding reliance on widget callbacks or execution timing.
- This directly resolves the behavior reported in issue #1126.
### 3. Node height and layout fix (frontend)
- The node height calculation was corrected to use the actual widget layout (last_y) instead of input/output counts.
- Nodes can now both grow and shrink correctly when resized or when widget content changes.
- This removes excessive empty space below the widgets and canvas.
### 4. Widget duplication prevention
- Frontend logic now detects when widgets are already created by Python and avoids recreating them in JavaScript.
- This prevents duplicated widgets and keeps the node UI consistent.
### 5. Comment cleanup
- Remaining comments in Spanish were translated to English for consistency and maintainability.
## Backward compatibility
- Existing workflows continue to work without modification.
- Default behavior and mask output remain unchanged unless inputs are explicitly linked.
## Motivation
These changes make the nodes composable with the rest of the graph (especially math and control nodes), improve the reliability of the preview, and fix UI inconsistencies without introducing breaking changes.
* Update dims getting logic in IterativeLatentUpscale to assume that
height and width are at the end of the latent's dimensions.
* Update dims getting logic in IterativeLatentUpscale to assume that
height and width are at the end of the latent's dimensions.
* re-order args
Fix Reactor Masking Helper tensor concatenation issues
- Ensure all tensors are on the same device before concatenation.
- Add batch dimension to single images to support batched concatenation.
- Enforce height and width matching via upscaling to prevent dim mismatch.
- Handle channel mismatches by truncating to the minimum channel count.
- Remove unsafe tensor repetition to avoid excessive RAM usage.
- Prevent RuntimeErrors when concatenating images of varying sizes or devices.
* Optimize MaskListToMaskBatch
The complexity of the original implementation is O(n^2). Optimize it to O(n).
* Update util_nodes.py
robust mask upscale
---------
Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
* Optimized SEGSPaste to reduce memory usage
* Optimized SEGSPaste to reduce memory usage
* Changed behavior of SAM2VideoDetectorSEGS when BBOX doesn't return any segs
* changed behavior of SegsVideoDetector again. It will now try to detect bboxes on the reversed video if no bboxes are found. It will only give up once even the reversed run doesn't yield any bboxes
* changed Videodetector behavior to predict reverse when not finding any bboxes
* Update segs_nodes.py
---------
Co-authored-by: Kaski <23-23enterprise@gmx.de>
Co-authored-by: Dr.Lt.Data <128333288+ltdrdata@users.noreply.github.com>
* fix: Handle clipspace files in PreviewBridge mask editor and restore fresh image behavior
- Fix KeyError when using mask editor multiple times
- Add register_clipspace_image() method to detect and register clipspace files
- Resolve timing issue between frontend JS conversion and backend processing
- Restore original "fresh start" behavior for new image generations
- Clear mask cache when images/latents change to ensure clean slate for new content
- Maintain backwards compatibility with existing preview bridge functionality
- Add dual registration for clipspace paths and preview IDs
Fixes issue where second+ mask saves would fail with:
KeyError: 'clipspace/clipspace-mask-XXXXX.png [input]'
Also fixed regression where new images would retain previous masks instead of starting fresh.
* Fix restore_mask 'always' and 'if_same_size' modes in PreviewBridge
- Fixed 'always' mode to properly preserve masks when changing input images/latents
- Fixed 'if_same_size' mode to preserve masks when switching between same-sized images
- Modified cache clearing logic to preserve cache for both 'always' and 'if_same_size' modes
- Updated restoration logic to handle size comparison correctly for 'if_same_size'
This addresses the issue where masks were being cleared even when restore_mask was set to 'always' or when switching between same-sized images with 'if_same_size'.
Fixes the issue discussed in PR #1009