- Detect subgraph instance scope and distinguish top-level vs nested nodes
- Aggregate inner resolved models for outer subgraph instances so menus show
promoted and hidden models together
- Patch both class prototypes and individual node instances when they define
getExtraMenuOptions or getMenuOptions, preserving native menu hooks
- Re-inject context menu after loadedGraphNode and queueMicrotask for
subgraph-created nodes
- Add tests for menu injection on overridden getMenuOptions and instance
patching, plus subgraph scope and aggregation behavior
- Wrap node.widgets.splice in rgthree Power Lora Loader adapter so removals
made through the context menu trigger model resolution updates.
- Delay node context menu analysis when a workflow refresh is already
pending to avoid stale analysis.
- Extend workflow refresh retry logic to also retry when ComfyUI is still
serializing the previous workflow after a node widget change.
- Add tests for context menu removal detection, refresh retry behavior,
and deferred context analysis.
When the resolver dialog is already visible on the Missing Models tab,
showResolvedNodeModelInResolver now reuses the existing browser instead
of forcing a reload or requeuing the selection. This avoids unnecessary
UI refreshes and keeps the current view stable.
Changes:
- web/resolver/model_resolver.js: skip reopen/queue when the dialog is
already visible on the missing tab; prefer existing browser selection
- web/resolver/views/missing_browser_methods.js: support
preferExistingBrowser in selectWorkflowModelReference and center the
selected row instead of scrolling to nearest
- tests/test_downloads_tab_workflow_route.mjs: cover reuse behavior and
row-patching/centering
- Configure callback-driven model widgets for LoRA Manager, LoraLoaderV2,
Lora Stacker, and Power Lora Loader nodes in graph and loaded graph hooks
- Track callback-driven widget states to trigger context analysis and
dialog refresh when LoRA lists or strengths change via widget callbacks
- Add signature helpers for callback-driven model list and strength changes,
including Power Lora Loader dynamic lora_N widgets
- Extend Loaded Models tab with model DOM keys, identity normalization,
copy-value updates with active/inactive grouping, and targeted strength
updates from node widgets without full re-render
- Add tests verifying callback-driven refresh behavior, suppression respect,
Power Lora Loader strength chip updates, and LoRA Manager list membership
signature tracking
Allow dragging the docked Model Resolver dialog from its drag handle to
undock it into a floating window, with a live undock drop preview.
- Remember the dock container width and reuse it for the undock preview
- Restore the pre-dock floating size instead of falling back to defaults
- Restrict topbar drag while docked to the dedicated drag handle
- Update tests to cover the new docked drag lifecycle and preview markup
Replace graph reconfigure with targeted widget updates so applying resolved models does not re-trigger node context analysis or duplicate dialog refreshes. Add workflow refresh suppression state, defer ComfyUI model catalog refresh until after widget linking, and track missing-workflow signatures separately from general workflow changes.
Queue workflow model reference selection requests in the dialog, wait for
workflow analysis to complete before attempting selection, and handle
superseded or timed-out requests gracefully.
- Track pending selection requests on the dialog with status fields
- Apply queued selections from lifecycle graph methods after analysis
- Await loadWorkflowData/loadLoadedModels so the caller can proceed
after tab content is actually ready
- Add timeout handling with user-visible warnings when selection cannot
complete
- Cover queueing, superseding, waiting, and completion in JS tests
Add openResolverForDetectedMissingModels() in model_resolver.js to
keep the current resolver display state when missing models are
detected: if the resolver dialog is already visible, schedule an
active workflow refresh instead of re-activating the button; if it
is hidden, activate the resolver button as before.
Update the auto-open-on-missing path to use the new method, and
adjust/add tests to cover the preserved display mode behavior.
- Adopt ComfyUI's ComfyExtension/comfy_entrypoint API in __init__.py when
available, falling back to legacy NODE_CLASS_MAPPINGS/DISPLAY_NAME_MAPPINGS
on older runtimes so the node loads across ComfyUI versions.
- Hook into beforeRegisterNodeDef, loadedGraphNode, and afterConfigureGraph
in web/resolver.js so marker nodes are patched during registration, graph
load, and initial render.
- Teach model_resolver.js to recognise the marker node by every known class
property shape, patch its type on creation, enforce a minimum size with
setSize() when present, and dirty the canvas so changes are reflected.
Replace scattered api.fetchApi(...) + response.ok + response.json() boilerplate
across all web/modules with a unified this.fetchJson() helper defined on the
base dialog class.
Changes:
- dialog.fetchJson(url, options, context) handles headers, status checks, and
JSON parsing in one place
- Extracts server-side error messages (errData.error) for better UX
- Optional silent flag suppresses notifications for background/refresh requests
- All callers simplified: async return, shorter bodies, consistent error handling
- BOM removed from workflow_update_methods.js and tabs_loaded_methods.js
- README.md: updated badge labelColor from 111827 to 1a1a1a for consistency
- core/workflow_analyzer.py: add LoaderGGUF and gguf_name mapping to diffusion_models
- web/resolver/model_resolver.js: rename panel title from 'Model Resolver' to 'Resolver'
- Add frontend_logs_enabled/frontend_log_level and backend_logs_enabled/backend_log_level
toggles and selectors in the Options panel (web/resolver/views/options_methods.js)
- Sync frontend logging settings from localStorage / server settings into the
frontend logger on startup and settings load (download_target_methods.js)
- Apply backend logging settings from server settings in the Python backend
(__init__.py), loading control state on startup and after saves
- Make frontend Logger resilient to stored configs that lack an 'enabled' flag
and to legacy/invalid moduleSettings levels (logger.js)
- Guard default module logger level initialization against undefined settings
(log_funcs.js)
- Replace scattered console.log/usages with module-level log.debug calls across
resolve_download_methods.js, model_resolver.js, and workflow_state_methods.js
- Bump log system package version to 1.5.6 (core + web)
- Guard workflow-tab-click handler with setTimeout and generation ownership check to avoid stale state updates
- Add generation-based refresh cancellation so outdated retry attempts are discarded
- Expand workflow signature to detect more model reference types, normalize widget values, and include subgraph definitions
- Add isLikelyWorkflowTabClickTarget to distinguish workflow tab clicks
from generic document clicks, preventing false 'workflow-change'
triggers and unnecessary refresh cycles.
- Add getWorkflowSignatureData to produce a stable, normalized signature
for workflow data (sorted nodes/links, top-level signature included).
- Update document-click handler to use a new 'workflow-tab-click' reason
via the click-target heuristic.
- Simplify refreshForActiveWorkflowChange retry logic by removing the
pending-graph-switch special case, since click origin is now explicit.
- Patch app.loadGraphData to dispatch custom event after loading,
ensuring workflow handlers fire when switching active workflow
- Add document-click handler to catch workflow changes initiated by clicks
- Pass event options through removeEventListener for proper cleanup
- Detect possible pending graph switch on document-click and reduce
max refresh attempts from 8 to 3 to avoid stale graph timers
Replace all link dialog terminology with resolver terminology
throughout the codebase, including module names, CSS classes,
IDs, JS variables, SVG gradient IDs, and log module names.
Remove the old web/linker/ tree and introduce the new web/resolver/
tree with parallel structure. Also replace core/linker.py with
core/resolver.py.