- Replace direct comfyApiBridge import in WorkflowNodesTab with getRawHostApp (ADR 0007).
- Reset security prefs snapshot in _reset_security_state_for_tests so tests that toggle MAJOOR_REQUIRE_AUTH are not influenced by an earlier ensure_security_bootstrap publishing require_auth=False.
- Call _reset_security_state_for_tests from _clear_write_auth_env helper for proper isolation.
- Rebuild frontend bundle.
- ImageOps preview bridge: stream cropped contain-fit rect of __imageops_state.canvas (removes square scope/letterbox); fall back to full canvas when user pan/zoom is active. Signature-cached encode (WeakMap) avoids re-encoding on every poll tick.
- Floating viewer: skip metadata enrichment for imageops-live-preview source; preserve user pan/zoom across stream frames of the same node; remove inline CSS overrides that blocked the MFV transform.
- Workflow Nodes panel: graph-selected node is auto-expanded, promoted to first position in its container, scrolled into view, and gets a subtle blue highlight (is-selected-from-graph).
The Settings -> Security toggles (Allow Remote Full Access, Allow HTTP Token Transport, Require Token For All Writes) were persisted in the DB but ignored by _check_write_access() and the bootstrap-token endpoint, which only read MAJOOR_* env vars. Remote LAN clients hit 'Write access is blocked' even with all toggles enabled.
- New security_prefs_snapshot module: thread-safe in-memory snapshot of persisted prefs, hydrated at ensure_security_bootstrap() and republished on every set_security_prefs(). Read synchronously by guards.
- security.py::_resolve_security_flag(pref_key, env_var, default): single read site, snapshot-first / env-fallback. Used for allow_remote_write, require_auth, allow_insecure_token_transport.
- _bootstrap_enabled() also returns True when allow_remote_write is set in the snapshot (UI consent for remote bootstrap).
- bootstrap-token / rotate-token accept plain HTTP transport when allow_insecure_token_transport is on.
- Friendlier defaults so first install works zero-config on LAN: allow_remote_write=True, allow_insecure_token_transport=True. Auto-generated API token still gates writes.
- Error messages updated to point users to Settings -> Security instead of only env vars.
- README rewritten to put the UI flow first; env vars as headless fallback.
- pyproject.toml: per-file ignore F401 for routes/core/security.py since it is the single import point that re-exports from sub-modules.
- Early-fetch immediate (no setTimeout 800ms), persisted scope/sort key, includeTotal=false.
- Snapshot persisted in localStorage (was sessionStorage), with legacy migration.
- MIN_LOADING_SKELETON_MS=0; skeleton hides as soon as assets are present.
- New scheduleSnapshotHeadRefresh: re-fetch page 0 after fast-path cached:true and upsert new items at correct sort position. Fixes recent assets disappearing on scope switch (custom->output).
- offset=max(offset, assets.length) in didHydrate branch so prefetch loads next page, not page 0 again.
- refreshDuplicateAlerts non-blocking (fire-and-forget).
- Race guards: scheduleDeferredExecutionReload skips reload if scope/filter changed during prompt execution; scheduleSnapshotHeadRefresh aborts if context changes mid-fetch.
- Includes other staged misc edits (config, scanner, watcher, components).
The toolbar was redesigned from inline <select> to icon buttons + popovers.
Update the test to match the new structure:
- check for .mjr-mfv-guides-trigger and .mjr-mfv-ch-trigger in bar
- expect formatSelect.value to be 'off' when _overlayMaskEnabled is false
- add viewer.element to the mock so the popover appendChilds don't throw
- sidebarRunButton: add _walkAllNodes() to mirror ComfyUI's native
beforeQueued/afterQueued widget cycle on all nodes incl. inner subgraph
nodes so control_after_generate (randomize/increment/decrement) is
applied correctly on each MFV run
- widgetAdapters: _syncWidgetDomElement falls back to
cachedDeepestByFrame.widget.inputEl for PromotedWidgetView so typing
in the sidebar updates the canvas textarea of subgraph outer widgets
in real time
- widgetAdapters: spinner step forced to 1 for integer widgets;
widget.value restored after callback to bypass step2 snapping
- Remove stale storage event listener in SettingsPanel.js
- Add checks for window object in LiveStreamTracker.js, floatingViewerManager.js
- Implement onScopeDispose for storage event listener in usePanelStore.js
- Add check for window object in MajoorPanel.svelte
- Adjusting the infinite scroll loading point to 4 card rows from the bottom
- Improving grid state restoration after reloads
- Enhancing the early fetch mechanism for faster initial loads
- Optimizing execution runtime to handle large numbers of assets efficiently
- Updating viewer and run button behavior for better integration with ComfyUI
- Fix various bugs and edge cases
- Remove hardcoded DB reset notice from i18n dictionary
- Remove DB reset notice version check from versionCheck.js
- Delete unused imports and variables related to DB reset notice
- Unify filename key normalization: VirtualAssetGridHost and useVirtualGrid
now import and call getFilenameKey() from AssetCardRenderer instead of
duplicating the String().trim().toLowerCase() inline expression.
- Make virtualizer overscan adaptive: compute ceil(scrollHeight / rowHeight)
clamped to [3, 20] so tall viewports buffer more rows without wasting
memory on small ones; falls back to 6 when no scroll element is present.
- Preserve Shift+Click anchor on reconcileSelection: add preserveAnchor
option to setSelection (default false, no behaviour change for existing
callers) and pass it as true from reconcileSelection so pruning invisible
assets out of the selection no longer resets the range anchor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- nodes.py: MajoorSaveImage (PNG with generation_time_ms in text chunks) and MajoorSaveVideo (MP4 via PyAV, GIF, WebP with metadata persistence)
- extractors_png.py: read generation_time_ms from PNG text chunks
- extractors.py: extract generation_time_ms from merged EXIF data into metadata dict
- extractors_video.py: extract generation_time_ms from ffprobe format tags
- messageCenter.js: add generation-time-persistence tip and topbar MFV button announcement
- CHANGELOG.md: document topbar MFV button and custom nodes
- README.md: add Custom Nodes section with input tables
- docs/CUSTOM_NODES.md: full node reference and extraction pipeline docs
- docs/DOCUMENTATION_INDEX.md: add CUSTOM_NODES.md entry
- registry.py: re-export PromptServer, _request_path_and_method, _requires_auth,
_extract_app_paths, _extract_table_paths so tests and mypy can import them
- registerRealtimeListeners: add force option to upsertLiveAssetIntoGrid;
_mjrAssetIndexedHandler passes force:true to bypass query filter
- grid_loader_adaptive_paging test: add APP_DEFAULTS to config.js mock
- register_realtime_listeners test: use expect.objectContaining for upsertAsset
assertions to tolerate mtime injection
- FloatingViewer.impl.js: add missing _resetMfvZoom() method (was called
from floatingViewerLoader/Mode but never defined on the class)
- viewerShell.js: return genInfoTitle + genInfoTitleLeft from createViewerStageShell
- ViewerRuntime.js: destructure genInfoTitle + genInfoTitleLeft (were undefined
=> gen info body was never populated)
- floatingViewerPopout.js: inject document.documentElement.style.cssText as
:root{...} in popup head so ComfyUI CSS vars are available; set body
background to #0d0d0d; remove broken history.replaceState (Chrome blocks
it from about:blank)
- __init__.py: remove unused FailureSeverity/StageStatus imports
- Hook canvas.onNodeDeselected (was missing) so sidebar clears when
deselecting all nodes (click on empty canvas)
- Add DOM-level pointerup listener on canvas.canvas as fallback for
ComfyUI selection paths that bypass LiteGraph callbacks
- Add requestAnimationFrame retry in open() if canvas is null at call time
- Write widget values in real-time on input event (number + textarea)
instead of only on change/blur; partial states (-/./empty) are skipped
for number inputs; blur still clamps and syncs displayed value
- Multi-Pin references: toggle buttons A/B/C/D to pin up to 4 images
- Node Parameters sidebar: view/edit workflow node widgets inside MFV
- Run button in viewer toolbar for immediate re-queue
- Expandable text areas for long prompts
- Sidebar position setting (right/left/bottom) via Settings
- Toolbar layout: Run and Node Parameters pushed to far right
- Message Center: 2 new announcements for the features
- Docs: VIEWER_FEATURE_TUTORIAL, FLOATING_VIEWER_WORKFLOW_SIDEBAR
- CHANGELOG v2.4.5, README aligned
- Remove absolute positioning from rightArea, use flex:1 1 0 flow layout
- Move titleLine (filename+badges) to leftArea in compare mode for 3-column layout
- Mirror paddingLeft=84px to match paddingRight in compare mode for symmetry
- centerArea flex:0 0 auto in compare so mode buttons stay centered
- Export leftArea, centerArea, titleLine, titleWrap, modeButtons from toolbar
- Add overflow:hidden to left/right meta and areas for text truncation
- Split asset_path_service into smaller, more focused modules
- Introduce new protocols for asset context preparation
- Reorganize import statements for better clarity
- Extract helper functions to improve code readability and reusability
- Update type annotations to use Protocol for better type checking
- Mark "Frontend Consolidation post-Vue" as completed
- Update status of various refactoring tasks
- Add completion date (2025-06-11)
- Clarify checklist usage for individual PRs
- Update TODOs and criteria for acceptance
- Add EXECUTION_IDLE_GRACE_MS config to control post-execution delay
- Implement post-execution work scheduling to optimize resource handling
- Enhance asset upsert logic for live assets during stack finalization
- Add runtime status synchronization to backend
- Improve execution start/end handling with new job ID tracking
- Refactor live asset event processing to reduce complexity
- Optimize imports and event handling in various modules
- Add dynamic theming with radial gradients and blurred effects
- Refine layout and spacing for various components
- Enhance filmstrip appearance and behavior
- Improve info panel styling and positioning
- Update general styling for buttons, tooltips, and other elements
- Add keyboard shortcuts for video in-point (I), out-point (O), and navigation (Home/End)
- Implement swipe gesture for navigating between assets in the viewer
- Add option to copy prompt to clipboard (Ctrl/Cmd+C)
- Improve stack group card functionality and representative selection
- Optimize image preloading for smoother navigation
- Enhance audio visualizer with WebGL support and mode switching
- Refine feed card appearance and interaction
- Explicitly track AI-related properties for Vue reactivity
- Ensure updates after backfill operations are detected
- Improve tracking for workflow, generation data, AI info, auto tags, caption, and vector
- Add grid snapshot caching to improve performance and reduce server requests
- Implement sessionStorage-based cache storage with size and TTL limitations
- Update grid loader to interact with the snapshot cache
- Modify asset upsert logic to work with cached snapshots
- Add functions to remember and retrieve snapshots
- Update CSS class names for grid skeleton layout
- Add support for string paths in addition to object arrays
- Implement new buildKey function for generating unique keys
- Introduce SUPPORTED_PATH_EXT_RE regex for valid file extensions
- Update pushItem and addItems functions to handle string inputs
- Add new pushPathString function for processing string paths
- Add session storage for temporary token storage
- Implement logic to clear local storage token after bootstrap refresh
- Refactor token refresh process to handle remote cookie refresh without exposing token
- Update fetchAPI function to use new token refresh logic
- Add tests for new token handling behavior
- Implemented LiveStreamTracker to manage live streaming of images and videos.
- Introduced functions for loading and saving images and videos, including handling of various formats.
- Added event listeners for new generation outputs and preview streaming integration with ComfyUI API.
- Established hooks for node selection changes to track and manage content updates.
- Created utility functions for parsing URLs and file paths to streamline input handling.