## Problem
The Media Assets panel's loading state is currently determined by the
loading state of the assets store (or something similar). When the store
is refetching and reconciling, it displays a loading spinner briefly on
the entire panel. This causes the following issues:
1. **Visual jarring**: The loading spinner creates an unpleasant visual
flash
2. **Unnecessary reflow**: All assets must re-render after the loading
state changes, causing layout reflow
3. **Performance degradation**: Re-rendering all items is
computationally expensive
## Expected Behavior
Items should be able to be inserted into the list without:
- Re-rendering any other items
- Showing a jarring loading flash
- Causing unnecessary reflow
The loading state of individual items should be decoupled from the
panel's overall loading state, allowing for incremental updates to the
list without affecting the entire panel's UI.
## After
(ignore random progress spinner, removed it after taking the video)
https://github.com/user-attachments/assets/95d7f111-e844-44e2-a0c6-6bcbc4a34797
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7449-fix-refreshing-assets-causes-entire-panel-to-re-render-enter-loading-state-2c86d73d365081be8206f9fdbbf66772)
by [Unito](https://www.unito.io)
## Summary
Makes the existing "Release: Version Bump" workflow run at 00:00 UTC
every day.
## Details
- concurrency keeps only one run active while manual dispatch remains
available for ad-hoc bumps.
- inputs are normalized inside the workflow so scheduled runs (which
lack `workflow_dispatch` inputs) safely fall back to `patch`/`main`, and
the version bump + PR formatting steps only use the optional
`pre_release` flag when it is provided
- each nightly invocation closes any lingering bot-authored
`version-bump-*` PRs/branches before creating a new patch PR, preventing
stale locale bumps from conflicting
- checkout now disables credential persistence and `pnpm/action-setup`
is pinned to a commit for supply-chain safety.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7410-ci-make-nightly-release-happen-automatically-every-night-2c76d73d3650813a9e02ee8878370929)
by [Unito](https://www.unito.io)
## Summary
This change extends
https://github.com/Comfy-Org/ComfyUI_frontend/pull/7154 by making sure
the `prompt` metadata tag is parsed before the legacy A1111 fallback
when files are dropped onto the canvas.
ComfyUI embeds two structured payloads into every first-class export
format we support (PNG, WEBP, WEBM, MP4/MOV/M4V, GLB, SVG, MP3,
OGG/FLAC, etc.): `workflow`, which is the full editor JSON with layout
state, and `prompt`, which is the API graph sent to `/prompt`.
During import we try format-specific decoders first and only as a last
resort look for an A1111 file by scanning text chunks for a `parameters`
entry. That compatibility path was always meant to be a best-effort
option, but when we refactored the loader it accidentally enforced the
order `workflow → parameters → prompt`. As soon as a dropped asset
contained a `parameters` chunk—something Image Saver’s “A1111
compatibility” mode always adds—the A1111 converter activated and
blocked the subsequent `prompt` loading logic.
PR #7154 already lifted `workflow` ahead of the fallback, yet any file
lacking the `workflow` chunk but holding both `prompt` and `parameters`
still regressed. Reordering to `workflow → prompt → parameters`
preserves the compatibility shim for genuine A1111 exports while
guaranteeing native Comfy metadata always wins, eliminating the entire
class of failures triggered merely by the presence of the word
`parameters` in an unrelated metadata chunk.
Fixes https://github.com/Comfy-Org/ComfyUI_frontend/issues/7096, fixes
https://github.com/Comfy-Org/ComfyUI_frontend/issues/6988
## Related
(fixed by https://github.com/Comfy-Org/ComfyUI_frontend/pull/7154)
- https://github.com/Comfy-Org/ComfyUI_frontend/issues/6633
- https://github.com/Comfy-Org/ComfyUI_frontend/issues/6561
---------
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This pull request updates the
`.github/workflows/pr-update-playwright-expectations.yaml` workflow to
improve how changed Playwright snapshot files are detected and handled,
ensuring that both tracked and untracked (new) files are included
throughout the process. The changes also add robustness to file
operations and improve the accuracy of change summaries.
**Improvements to snapshot detection and staging:**
* The workflow now detects both tracked and untracked (new) snapshot
files in `browser_tests/` when preparing changed files for staging,
ensuring that new snapshots are not missed.
* When copying changed files to the staging directory, the script now
skips files that no longer exist (e.g., deleted files), preventing
errors and unnecessary operations.
**Enhancements to change summary and commit logic:**
* The summary of changes now includes both tracked and untracked files
in `browser_tests/`, and the output is expanded to show up to 50 files
for better visibility.
* The logic for determining whether there are changes to commit now
checks for both tracked and untracked changes, ensuring commits are only
made when necessary.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7423-Fix-snapshot-updates-commit-stage-2c76d73d36508195914ec92f37937e67)
by [Unito](https://www.unito.io)
This pull request improves the snapshot staging process in the
Playwright expectations update workflow. The main focus is to ensure
both modified and newly added snapshot files are correctly detected and
handled, and to avoid errors when files have been deleted.
**Snapshot file detection and handling improvements:**
* The workflow now detects both modified and untracked (new) snapshot
files by combining output from `git diff` and `git ls-files --others`,
ensuring all relevant snapshot changes are staged.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7422-fix-enhance-snapshot-update-process-to-include-untracked-files-2c76d73d365081cc8023d9ed29b8781f)
by [Unito](https://www.unito.io)
## Summary
Ensures the nodes get their own compositing layers during scale
transform (tracked via mouse wheel events), which prevents rasterization
during transform. Adds forced reflow at end of transform to ensure
layers are always at correct resolution (fixes blurriness and some
readability issues).
Videos show testing this branch first then testing main - doing layer
visualization, paint (include paint operations calculations and actual
raster) visualizations, and cpu usage monitoring.
https://github.com/user-attachments/assets/c5fab219-0b32-4822-9238-c4572f0d6a44https://github.com/user-attachments/assets/7e172e8d-cc5b-4dcd-aa07-1dfc3eb65bac
## Summary
Remove keyDown provider on the LGraphNode, remove inject on widget.
## Changes
- **What**: LGraphNode.vue ImagePreview.vue
- **Breaking**: <!-- Any breaking changes (if none, remove this line)
-->
- **Dependencies**: <!-- New dependencies (if none, remove this line)
-->
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7421-refactor-stop-fighting-the-DOM-2c76d73d365081e6b5e9c99a61bbd883)
by [Unito](https://www.unito.io)
Prior to the release of subgraphs, there was a single graph accessed
through `app.graph`. Now that there's multiple graphs, there's a lot of
code that needs to be reviewed and potentially updated depending on if
it cares about nearby nodes, all nodes, or something else requiring
specific attention.
This was done by simply changing the type of `app.graph` to unknown so
the typechecker will complain about every place it's currently used.
References were then updated to `app.rootGraph` if the previous usage
was correct, or actually rewritten.
By not getting rid of `app.graph`, this change already ensures that
there's no loss of functionality for custom nodes, but the prior typing
of `app.graph` can always be restored if future dissuasion of
`app.graph` usage creates issues.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7399-Cleanup-app-graph-usage-2c76d73d365081178743dfdcf07f44d0)
by [Unito](https://www.unito.io)
## Summary
Make image preview keyboard accessible, set the key listener on the node
itself for more robust and intuitive handling, also add better aria
labels.
Follow up PR: same on Video preview.
## Changes
- **What**: LGraphNode.vue, ImagePreview.vue
- **Breaking**: <!-- Any breaking changes (if none, remove this line)
-->
- **Dependencies**: <!-- New dependencies (if none, remove this line)
-->
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7252-fix-image-preview-a11y-2c46d73d3650815b9496f3d36a8942bf)
by [Unito](https://www.unito.io)
## Summary
Add frontend setting to override live preview method per prompt
execution.
## Changes
- **What**: New setting `Comfy.Execution.PreviewMethod` allows users to
override preview method (default/none/auto/latent2rgb/taesd) from
frontend. Applied to Queue Prompt, Queue Front, Run Selected Nodes, and
Auto Queue.
- **Dependencies**: Requires backend support from
comfyanonymous/ComfyUI#11261
## Review Focus
- `'default'` option does not send `preview_method` to backend (uses
server CLI setting)
- Legacy UI intentionally not modified (deprecated, maintains backward
compatibility)
- `versionAdded: '1.35.3'` assigned tentatively; adjust as needed for
actual release version
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7385-feat-add-live-preview-method-setting-for-prompt-execution-2c66d73d365081759c9cebaec29f451c)
by [Unito](https://www.unito.io)
## Summary
When Chrome is maximized with GPU acceleration and high DPR, calling
drawImage(canvas) + drawImage(img) in the same frame causes severe
performance degradation (FPS drops to 2-10, memory spikes ~18GB).
Defer image preview rendering using queueMicrotask to separate the two
drawImage calls into different tasks.
### Problem
Severe performance degradation in ComfyUI when dragging connection lines
in litegraph mode:
- FPS drops from 60 to 2-10
- Memory spikes from 36GB to 54GB (~18GB increase)
- CPU jumps from 2% to 15%
- Other Chrome tabs (e.g., YouTube) also stutter
### Environment
- Affected: Chrome with GPU acceleration, maximized/fullscreen window,
high DPR (1.75)
- Not affected: Firefox (WebRender), Chrome in windowed mode, Chrome
with GPU acceleration disabled
### Problem only occurs with:
- GPU acceleration enabled
- Chrome maximized/fullscreen
- An image loaded on canvas (e.g., LoadImage node with preview)
### Root cause: The bug is triggered when two drawImage() calls execute
in the same frame on the same canvas:
- ctx.drawImage(bgcanvas, ...) - copying background canvas to foreground
- ctx.drawImage(img, ...) - rendering image preview in node widget
## Screenshots (if applicable)
Before
https://github.com/user-attachments/assets/76005c10-3430-4d75-a7ed-58f61d18688c
After
https://github.com/user-attachments/assets/5a15b0f9-3935-4428-879b-e55390abff22
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7394-fix-work-around-Chrome-GPU-bug-causing-severe-lag-when-dragging-links-2c66d73d365081469d73d98bf1aa421a)
by [Unito](https://www.unito.io)
## Summary
<!-- One sentence describing what changed and why. -->
## Changes
- **What**: <!-- Core functionality added/modified -->
- **Breaking**: <!-- Any breaking changes (if none, remove this line)
-->
- **Dependencies**: <!-- New dependencies (if none, remove this line)
-->
## Review Focus
<!-- Critical design decisions or edge cases that need attention -->
<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->
## Screenshots (if applicable)
<!-- Add screenshots or video recording to help explain your changes -->
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7395-chore-fix-playwright-expectations-2c66d73d3650819d8913d80be55d7908)
by [Unito](https://www.unito.io)
---------
Co-authored-by: github-actions <github-actions@github.com>
## Summary
Removes custom LoRA feature from subscription benefits display for
standard and founder tiers.
## Changes
- **What**: Removed `customLoRAs` benefit entry from `BENEFITS_BY_TIER`
for standard and founder tiers
## Review Focus
- Verify custom LoRA feature is completely removed from subscription UI
Related to #7391
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Standard tier was incorrectly displaying custom LoRA as a benefit.
Refactored to use strongly-typed benefit configuration.
## Changes
- **What**: Created `BENEFITS_BY_TIER` configuration to explicitly
define tier benefits
- **Type Safety**: Added `TierKey` type and improved type constraints
throughout
- **Fix**: Excluded `customLoRAs` from standard tier (only
creator/pro/founder get this feature)
## Review Focus
Verify standard tier no longer shows custom LoRA feature in subscription
panel
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7391-fix-remove-custom-LoRA-feature-from-standard-tier-2c66d73d36508149ad6ff7bba6333109)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Add Jobs API infrastructure in preparation for migrating from legacy
`/history`, `/history_v2`, and `/queue` endpoints to the unified `/jobs`
API.
**This is PR 1 of 3** - Additive changes only, no breaking changes.
## Changes
- **What**:
- Add Zod schemas for runtime validation of Jobs API responses
(`JobListItem`, `JobDetail`)
- Add `fetchQueue`, `fetchHistory`, `fetchJobDetail` fetchers for
`/jobs` endpoint
- Add `extractWorkflow` utility for extracting workflow from nested job
detail response
- Add synthetic priority assignment for queue ordering (pending >
running > history)
- Add comprehensive tests for all new fetchers
- **Non-breaking**: All changes are additive - existing code continues
to work
## Review Focus
1. **Zod schema flexibility**: Using `.passthrough()` to allow extra API
fields - ensures forward compatibility but less strict validation
2. **Priority computation**: Synthetic priority ensures display order:
pending (queued) → running → completed (history)
3. **Test coverage**: Verify tests adequately cover edge cases
## Files Added
- `src/platform/remote/comfyui/jobs/` - New Jobs API module
- `types/jobTypes.ts` - Zod schemas and TypeScript types
- `fetchers/fetchJobs.ts` - API fetchers with validation
- `index.ts` - Barrel exports
-
`tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts`
- Tests
## Next PRs
- **PR 2**: Migrate `getQueue()` and `getHistory()` to use Jobs API
- **PR 3**: Remove legacy history code and unused types
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7169-feat-Add-Jobs-API-infrastructure-PR-1-of-3-2bf6d73d3650812eae4ac0555a86969c)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Cause
When graphs are actually exported, several layers of cleanup are
applied. Among these is link compression. Any widgets with inputs that
aren't used do not have inputs stored in the workflow. This was
implemented for backwards compatibility with the old "convert to input"
system for widgets. As part of this process, the target_slots on links
are rewritten such that they point to the index of the widget as if
unconnected widgets did not exist.
This "incorrect" state for links is only corrected AFTER a workflow has
loaded because the 'fix' method needs nodes to be initialized in order
to calculate the correct target_slot
This becomes a problem when subgraphs are introduced. SubgraphInputs
need to resolve a link to its target slot in order to construct a clone
of the linked widget DURING the loading process. Since this target slot
is not accurate, this can result in the cloned widget having the wrong
type.
For a minimal reproduction:
- Create a subgraph with an Empty Latent Image with batch_size linked to
the Subgraph Input
- Export the workflow
- On load, the batch_size has step and min attributes which incorrectly
correspond to width
## Fix
There's multiple possible ways to address this and input on direction is
appreciated
- Fix links before loading graph
- Likely to break with any dynamic state
- Fix links, then load graph again
- Ugly, bad performance, dynamic state may require multiple passes to
correctly ripple
- In the Subgraph code, ignore target_slot and instead `.find()` input
with matching linkId (proposed)
- Promising, but means accepting that state is just wrong sometimes.
Another forever footgun.
- Entirely remove the input compression
- Some people may complain, and old workflows still need to be supported
- Only remove target_slot redirection inside subgraphs
- Creates ugly logical difference between what happens inside and
outside subgraphs.
- Still leaves old workflows broken
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7388-Remove-target_slot-compression-from-subgraph-exports-2c66d73d3650815d8c96c5047958ab67)
by [Unito](https://www.unito.io)
Fix flaky "Can drag-and-drop animated webp image" test that was reading
the widget value before the upload completed, causing intermittent
failures where filenames appeared truncated. Added `waitForUpload`
option to `dragAndDropFile` helper that waits for the `/upload/`
response before returning. This is opt-in since not all drag-and-drop
operations trigger uploads (e.g., loading workflows from media files).
## Summary
Fix the flakiness of [this
test](https://fad8c753.comfyui-playwright-chromium.pages.dev/#?testId=967c1c643b6ca86a362c-8b516e2c224693bf7657)
by converting it from using snapshots to just normal locators.
The LiteGraph prompt that opens when click canvas widgets
(number/string) is still the raw DOM dialog created by
`LGraphCanvas.prototype.prompt`. That implementation wires its "click
outside to close" handler inside a `setTimeout` and ignores outside
clicks for ~256 ms after the dialog appears. It also never updates Vue
state or exposes a ready attribute/event we can observe from Playwright.
Because the UI offers no deterministic signal, using a short intentional
wait that matches the real guard is reasonable. We assert the dialog
becomes visible, call `await comfyPage.delay(300)` (just longer than the
256 ms guard), and then click outside. Without this wait the closing
click fires before the handler exists, so the dialog remains visible and
the test flakes. Until the widget exposes a ready hook, this scoped
delay is the most reliable approach and stays within Playwright guidance
("only sleep when there is no observable condition to await").
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7371-fix-make-flaky-legacy-prompt-dialog-test-use-locator-rather-than-snapshot-2c66d73d36508125b388e68861d7cd28)
by [Unito](https://www.unito.io)