Commit Graph

405 Commits

Author SHA1 Message Date
Johnpaul Chiwetelu
1e71eae177 Persist template filters (#6657)
This pull request adds persistent filter and sort settings to the
template library, allowing users' filter choices and sort preferences to
be saved and restored across sessions. The main changes include
integrating the settings store with the template filtering composable,
updating the schema and core settings, and ensuring filter changes are
saved efficiently.

**Template Library Filter Persistence:**

*
[`src/composables/useTemplateFiltering.ts`](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L1-R32):
The filter state (`selectedModels`, `selectedUseCases`,
`selectedRunsOn`, and `sortBy`) is now initialized from the settings
store and changes are persisted back using debounced watchers. This
ensures user preferences are saved and restored.
[[1]](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L1-R32)
[[2]](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167R259-R291)
*
[`src/platform/settings/constants/coreSettings.ts`](diffhunk://#diff-9fb7e2cdcdc60a92bdb54698fb49909bd2a84a50ffb69e2b60529a948eeb9756R1056-R1083):
Added new hidden settings for template filter selections and sort
preference, with sensible defaults.
*
[`src/schemas/apiSchema.ts`](diffhunk://#diff-b769532e74f826ca909951c0c34331b9246efb3f6901ff95a856ecf01ad826beR504-R514):
Updated the settings schema to include the new template filter and sort
settings, ensuring type safety and validation.

**Default Behavior Adjustment:**

*
[`src/composables/useTemplateFiltering.ts`](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L200-R209):
Changed the default sort order when clearing filters to `'newest'` to
match the new default in settings.


https://github.com/user-attachments/assets/259e87e6-20b3-4c91-b1bf-4b7d70649878

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6657-Persist-template-filters-2a86d73d3650818ca46fda23a6528391)
by [Unito](https://www.unito.io)
2025-11-12 13:25:09 -07:00
Rizumu Ayaka
2cf3739236 refactor: use defineAsyncComponent for widget components (#6644)
currently, three.js is still being imported from the core extension. I'm
working on resolving this issue

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6644-refactor-use-defineAsyncComponent-for-widget-components-2a76d73d36508117a090eb5e4f0274e0)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <DrJKL0424@gmail.com>
2025-11-12 01:41:11 -08:00
Christian Byrne
d14c416cc4 cloud: fix credits tooltips (#6655)
Moves the refresh button's tooltip to the monthy bonus tooltip (correct,
intended tooltip assignments).

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6655-cloud-fix-credits-tooltips-2a86d73d365081b585ecf19af574a10a)
by [Unito](https://www.unito.io)
2025-11-11 17:45:13 -07:00
Christian Byrne
3c550e953a fix: improve template URL loading UX and prevent re-triggering (#6593)
Fixes the janky UX when loading templates via URL query parameters by
moving the loading logic earlier in the app lifecycle (from
GraphView.onGraphReady to
useWorkflowPersistence.restorePreviousWorkflow). The saved workflow now
loads first as a background tab, then the template loads as the active
tab, eliminating the visual flash where the saved workflow briefly
appears before being replaced. After loading, the template and source
query parameters are removed from the URL using router.replace to
prevent the template from re-loading on page refresh. This preserves
user work by keeping both workflows open in separate tabs and matches
the existing behavior when clicking templates from the dialog. All 15
tests pass including 3 new tests for URL cleanup.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6593-fix-improve-template-URL-loading-UX-and-prevent-re-triggering-2a26d73d36508137a0cae6cf92c842fc)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Christian Byrne <c.byrne@comfy.org>
2025-11-11 13:51:56 -07:00
Christian Byrne
0be1da2041 feat: navigate to previously active tab when closing current tab (#6624)
When closing a tab, the UI now returns to the most recently active tab
instead of always going to the first/next tab. This matches standard
browser tab behavior and prevents accidental edits in the wrong
workflow. Implementation uses a lazy-cleanup history array (max 32
entries) that tracks tab activations and skips closed tabs when finding
the previous tab to switch to. Fixes #6599


https://github.com/user-attachments/assets/0bb87969-fd01-4e6b-96e8-c0f741f23ff8

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6624-feat-navigate-to-previously-active-tab-when-closing-current-tab-2a36d73d365081f5be95db51ff7a03f6)
by [Unito](https://www.unito.io)
2025-11-11 11:03:35 -07:00
Terry Jia
879cb8f1a8 support panoramic image in 3d node (#6638)
## Summary

Adds panoramic image support to the 3D node viewer, allowing users to
display equirectangular panoramic images as immersive backgrounds
alongside the existing tiled image mode.

## Changes

- Toggle between tiled and panorama rendering modes for background
images
- Field of view (FOV) control for panorama mode
- Refactored FOV slider into reusable PopupSlider component

## Screenshots


https://github.com/user-attachments/assets/8955d74b-b0e6-4b26-83ca-ccf902b43aa6

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6638-support-panoramic-image-in-3d-node-2a56d73d365081b98647f988130e312e)
by [Unito](https://www.unito.io)
2025-11-11 04:02:12 -05:00
Benjamin Lu
b1050e3195 Fix session cookie creation race: skip initial token refresh, wrap extension auth hooks (#6563)
Fixes a race causing “No auth header available for session creation”
during sign‑in, by skipping the initial token refresh event, and
wrapping extension auth hooks with async error handling.

Sentry:
https://comfy-org.sentry.io/issues/6990347926/?alert_rule_id=1614600&project=4509681221369857

Context
- Error surfaced as an unhandled rejection when session creation was
triggered without a valid auth header.
- Triggers: both onAuthUserResolved and onAuthTokenRefreshed fired
during initial login.
- Pre‑fix, onIdTokenChanged treated the very first token emission as a
“refresh” as well, so two concurrent createSession() calls ran
back‑to‑back.
- One of those calls could land before a Firebase ID token existed, so
getAuthHeader() returned null → createSession threw “No auth header
available for session creation”.

Exact pre‑fix failure path
- src/extensions/core/cloudSessionCookie.ts
  - onAuthUserResolved → useSessionCookie().createSession()
  - onAuthTokenRefreshed → useSessionCookie().createSession()
- src/stores/firebaseAuthStore.ts
- onIdTokenChanged increments tokenRefreshTrigger even for the initial
token (treated as a refresh)
- getAuthHeader() → getIdToken() may be undefined briefly during
initialization
- src/platform/auth/session/useSessionCookie.ts
- createSession(): calls authStore.getAuthHeader(); if falsy, throws
Error('No auth header available for session creation')

What this PR changes
1) Skip initial token “refresh”
- Track lastTokenUserId and ignore the first onIdTokenChanged for a
user; only subsequent token changes count as refresh events.
   - File: src/stores/firebaseAuthStore.ts
2) Wrap extension auth hooks with async error handling
- Use wrapWithErrorHandlingAsync for
onAuthUserResolved/onAuthTokenRefreshed/onAuthUserLogout callbacks to
avoid unhandled rejections.
   - File: src/services/extensionService.ts

Result
- Eliminates the timing window where createSession() runs before
getIdToken() returns a token.
- Ensures any remaining errors are caught and reported instead of
surfacing as unhandled promise rejections.

Notes
- Lint and typecheck run clean (pnpm lint:fix && pnpm typecheck).

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6563-Fix-session-cookie-creation-race-dedupe-calls-skip-initial-token-refresh-wrap-extensio-2a16d73d365081ef8c22c5ac8cb948aa)
by [Unito](https://www.unito.io)
2025-11-07 21:30:49 -07:00
Benjamin Lu
ba100c4a04 Hide browser tab star when autosave is enabled (#6568)
- Hide "*" indicator in the browser tab title when autosave is enabled
(Comfy.Workflow.AutoSave === 'after delay').
- Refactor: extract readable computed values
(`shouldShowUnsavedIndicator`, `isActiveWorkflowModified`,
`isActiveWorkflowPersisted`).
- Aligns with workflow tab behavior; also hides while Shift is held
(matches in-app tab logic).

Files touched:
- src/composables/useBrowserTabTitle.ts

Validation:
- Ran `pnpm lint:fix` and `pnpm typecheck` — both passed.

Manual test suggestions:
- With autosave set to 'after delay': modify a workflow → browser tab
should not show `*`.
- With autosave 'off': modify or open non-persisted workflow → browser
tab shows `*`.
- Hold Shift: indicator hidden while held (consistent with workflow
tab).

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6568-Hide-browser-tab-star-when-autosave-is-enabled-refactor-title-logic-2a16d73d365081549906e9d1fed07a42)
by [Unito](https://www.unito.io)
2025-11-07 21:30:34 -07:00
Christian Byrne
535f857330 refactor: move renderer-dependent utils into workbench scope (#6621)
This PR cleans up the base-layer utilities so they no longer pull
renderer or workbench code. The renderer-only `isPrimitiveNode` guard
now lives in `src/renderer/utils/nodeTypeGuards.ts`, and the node
help/model/ordering helpers have moved into `src/workbench/utils`. All
affected services, stores, scripts, and tests were updated to import
from the new locations.

The idea is to reduce the number of Base→Renderer/Base→Workbench edges
(higher scoped base/common utils should not import from
renderer/workbench layers).

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6621-refactor-move-renderer-dependent-utils-into-workbench-scope-2a36d73d36508167aff0fc8a22202d7f)
by [Unito](https://www.unito.io)
2025-11-06 19:32:41 -07:00
Arjan Singh
8849d54e20 fix: use WidgetSelectDropdown for models (#6607)
## Summary

As the commit says, the model loaders were broken in cloud if you
enabled Vue Nodes (not a thing I think user does yet).

This fixes it by configuring the `WidgetSelectDropdown` to load so the
user load models like they would load a input or output asset.

## Review Focus

Probably `useAssetWidgetData` to make sure it's idomatic.

This part of
[assetsStore](https://github.com/Comfy-Org/ComfyUI_frontend/pull/6607/files#diff-18a5914c9f12c16d9c9c3a9f6d0e203a9c00598414d3d1c8637da9ca77339d83R158-R234)
as well.

## Screenshots

<img width="1196" height="1005" alt="Screenshot 2025-11-05 at 5 34
22 PM"
src="https://github.com/user-attachments/assets/804cd3c4-3370-4667-b606-bed52fcd6278"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6607-fix-use-WidgetSelectDropdown-for-models-2a36d73d36508143b185d06d736e4af9)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-06 03:34:17 +00:00
Arjan Singh
35d53c2c75 feat(WidgetSelectDropdown): support mapped display names (#6602)
## Summary

Add the ability for `WidgetSelectDropdown` to leverage `getOptionLabel`
for custom display labels.

## Review Focus

Will note inline.

## Screenshots


https://github.com/user-attachments/assets/0167cc12-e23d-4b6d-8f7f-74fd97a18397

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6602-feat-WidgetSelectDropdown-support-mapped-display-names-2a26d73d365081709c56c846e3455339)
by [Unito](https://www.unito.io)
2025-11-05 13:12:59 -08:00
Christian Byrne
437c3b2da0 set config via feature flags (#6590)
In cloud environment, allow all the config values to be set by the
feature flag endpoint and be updated dynamically (on 30s poll). Retain
origianl behavior for OSS. On cloud, config changes shouldn't be changed
via redeploy and the promoted image should match the staging image.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6590-set-config-via-feature-flags-2a26d73d3650819f8084eb2695c51f22)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <DrJKL0424@gmail.com>
2025-11-05 13:45:21 -07:00
Arjan Singh
a2ef569b9c feat(ComboWidget): add ability to have mapped inputs (#6585)
## Summary

1. Add a `getOptionLabel` option to `ComboWidget` so users of it can map
of custom labels to widget values. (e.g., `"My Photo" ->
"my_photo_1235.png"`).
2. Utilize this ability in Cloud environment to map user uploaded
filenames to their corresponding input asset.
3. Copious unit tests to make sure I didn't (AFAIK) break anything
during the refactoring portion of development.
4. Bonus: Scope model browser to only show in cloud distributions until
it's released elsewhere; should prevent some undesired UI behavior if a
user accidentally enables the assetAPI.

## Review Focus

Widget code: please double check the work there.

## Screenshots (if applicable)



https://github.com/user-attachments/assets/a94b3203-c87f-4285-b692-479996859a5a


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6585-Feat-input-mapping-2a26d73d365081faa667e49892c8d45a)
by [Unito](https://www.unito.io)
2025-11-05 11:33:00 -08:00
Christian Byrne
9cd7a39f09 load template workflow via URL query param (#6546)
## Summary

Adds support for loading templates via URL query parameters. Users can
now share direct links to templates.

To test:

1. checkout this branch
2. start dev server on port 5173
3. go to http://localhost:5173/?template=image_qwen_image_edit_2509

**Examples:**
- `/?template=default` - Loads template with default source
- `/?template=flux_simple&source=custom` - Loads from custom source

Includes error handling with toast notifications for invalid templates
and comprehensive test coverage.

---------

Co-authored-by: Christian Byrne <c.byrne@comfy.org>
2025-11-02 21:23:56 -08:00
Christian Byrne
4810b5728a [feat] Add Partner Nodes virtual category and rename license filter (#6542)
This PR adds a 'Partner Nodes' virtual category that filters templates
where OpenSource === false, and renames the 'License' filter to 'Runs
on' with values 'ComfyUI' and 'Partner API'. The implementation is
backward compatible and works like the existing 'Basics' category - it
filters templates from any category without duplication. The filter
logic now uses the explicit OpenSource field instead of heuristic
detection. This change coordinates with upcoming workflow_templates repo
updates that will move API templates to GENERATION TYPE categories and
add the OpenSource field to all API node templates.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6542-feat-Add-Partner-Nodes-virtual-category-and-rename-license-filter-29f6d73d36508111a85bdf5017f0a100)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-02 20:50:16 -08:00
Christian Byrne
8df0a3885d [feat] Rename license filter to 'Runs On' filter in template selector (#6543)
## Summary

Renamed the templates license filter to better reflect its actual
purpose - showing where a template executes (locally in ComfyUI vs
external/remote API).

The current "License" filter has been causing confusion with model
licensing terms (e.g., Apache vs flux-dev licensing). This PR clarifies
the filter's purpose by renaming it to "Runs On" and updating the
options to be more descriptive of inference location.

<img width="196" height="230" alt="image"
src="https://github.com/user-attachments/assets/8cbea263-f399-4945-82c1-357ec185f5a7"
/>

<img width="861" height="597" alt="image"
src="https://github.com/user-attachments/assets/af116876-d7a5-49c5-b791-1fda637ff3a3"
/>


## Changes

- **Filter name**: "License" → "Runs On"
- **Filter options**: 
  - "Open Source" → "ComfyUI"
  - "Closed Source (API Nodes)" → "External or Remote API"
- **Icon**: Changed from `file-text` to `server` for better visual
representation
- **Variable naming**: Updated all related variables, types, and tests
to use `runsOn` naming convention
- **Telemetry**: Updated metadata to track `selected_runs_on` instead of
`selected_licenses`

## Why "Runs On"?

- **Clear intent**: Users want to know if a template runs locally or
requires an API call
- **Avoids confusion**: Separates the concept from model licensing terms
- **Inclusive wording**: "Remote" is included alongside "API" to help
users who may not be familiar with API terminology
- **Cloud-agnostic**: "Runs On" works whether the app itself is running
locally or in the cloud

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6543-feat-Rename-license-filter-to-Runs-On-filter-in-template-selector-29f6d73d3650811f935bc1f3fce7d7ad)
by [Unito](https://www.unito.io)
2025-11-02 16:35:42 -08:00
Benjamin Lu
feda2d47b0 feat(telemetry): track settings changes (#6504)
Summary
- Add telemetry event for settings changes when the global settings
dialog is open
- Clarify variable names in settings store (`settingParameter`,
`settingType`) for readability
- Introduce `SettingChangedMetadata` and
`TelemetryEvents.SETTING_CHANGED`
- Implement `trackSettingChanged` in Mixpanel provider
- Add focused unit test to verify telemetry triggers when settings
dialog is open vs closed

Quality
- Ran `pnpm lint:fix` and `pnpm typecheck`
- Unit tests pass locally

Notes
- Event fires only when the settings dialog is open (uses
`useDialogStore().isDialogOpen('global-settings')`)
- OSS builds are unaffected (`useTelemetry()` returns null)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6504-feat-telemetry-track-settings-changes-clarify-names-add-unit-test-29e6d73d3650815ea919d832b310cc46)
by [Unito](https://www.unito.io)
2025-11-01 23:52:04 -07:00
AustinMroz
02aaf577ec Fix inability to select image from batch in vue (#6521)
Selecting a new image from a batch sets isLoading to true, but
handleImageLoad is never triggered so the image never displays.

Swapping to a different image from a batch is currently the only place
isLoading is set to true. This change, even if temporary, results in a
good chunk of dead code.

To my understanding, ImagePreviews are always object URLs and should
never need to load, so I don't foresee the loading placeholder being
needed here.

Resolves #6458

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6521-Fix-inability-to-select-image-from-batch-in-vue-29e6d73d36508162abeaeece7c5e0eed)
by [Unito](https://www.unito.io)
2025-11-01 16:56:41 -07:00
AustinMroz
431594a6fc Fix partial execution inside subgraphs (#6487)
`getExecutionIdsForSelectedNodes` is only used for partial execution.
The prior implementation solved the wrong problem. Given a list of
nodes, it would explore into subgraphs and return a list of partial
ExecutionIds for all contained nodes. Because this does not resolve the
partial execution path to the current subgraph, this is incorrect when
the current graph is not the root graph. Woefully, this incorrect
functionality is never useful because the recursive exploration only
applies to subgraph nodes which never satisfy the outputNode filter
applied by the parent function.

An extra function is used to correctly append the parent execution path,
but the existing, probably never useful code for recursively collecting
children is otherwise left in place.

Resolves #6480

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6487-Fix-partial-execution-inside-subgraphs-29d6d73d36508197924bfb3a0fb6699e)
by [Unito](https://www.unito.io)
2025-11-01 16:08:57 -07:00
Benjamin Lu
72389637ed feat(telemetry): track API credit top-up success via audit events (#6500)
Summary
- Add TelemetryEvents.API_CREDIT_TOPUP_SUCCEEDED and provider method
trackApiCreditTopupSucceeded
- Introduce topupTrackerStore to persist pending top-ups per user
(localStorage) and reconcile against recent audit logs
- Hook purchase flow to start tracking before opening Stripe checkout
- Reconcile after fetching audit events (UsageLogsTable) and after
fetchBalance, then emit telemetry, refresh balance, and clear pending
- Minor refactor in customerEventsService to return awaited result

Implementation details
- Matching strategy:
  - Event type: credit_added
  - Time window: createdAt between top-up start time and +24h
  - Amount: if known, e.params.amount must equal expected cents
- Cross-tab/user changes: synchronize via storage event and userId
watcher

Limitations / Follow-up
- Reconciliation fetches only page 1 (limit 10) of events; in
high-volume cases, a recent credit_added could fall outside the first
page
- The window and pagination issue will be "resolved by a followup PR to
core and cloud"

Files touched
- src/stores/topupTrackerStore.ts (new)
- src/components/dialog/content/setting/UsageLogsTable.vue
- src/composables/auth/useFirebaseAuthActions.ts
- src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts
- src/platform/telemetry/types.ts
- src/services/customerEventsService.ts

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6500-feat-telemetry-track-API-credit-top-up-success-via-audit-events-29e6d73d365081169941efae70cf71fe)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Christian Byrne <chrbyrne96@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-01 13:17:41 -07:00
Arjan Singh
de535269ee feat(telemetry): help center and workflow creation (#6505)
## Summary

For Cloud distribution:
1. Track help center usage
2. Track workflow creation

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6505-feat-telemetry-help-center-and-workflow-creation-29e6d73d36508185af8ccbf19d5af9e7)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Christian Byrne <chrbyrne96@gmail.com>
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-01 12:21:50 -07:00
Terry Jia
afa10f7a1e [refactor] refactor load3d (#5765)
Summary

Fully Refactored the Load3D module to improve architecture and
maintainability by consolidating functionality into a
centralized composable pattern and simplifying component structure. and
support VueNodes system

  Changes

- Architecture: Introduced new useLoad3d composable to centralize 3D
loading logic and state
  management
- Component Simplification: Removed redundant components
(Load3DAnimation.vue, Load3DAnimationScene.vue,
  PreviewManager.ts) 
- Support VueNodes
- improve config store
- remove lineart output due Animation doesnot support it, may add it
back later
- remove Preview screen and keep scene in fixed ratio in load3d (not
affect preview3d)
- improve record video feature which will already record video by same
ratio as scene
Need BE change https://github.com/comfyanonymous/ComfyUI/pull/10025


https://github.com/user-attachments/assets/9e038729-84a0-45ad-b0f2-11c57d7e0c9a



┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5765-refactor-refactor-load3d-2796d73d365081728297cc486e2e9052)
by [Unito](https://www.unito.io)
2025-10-31 16:19:35 -04:00
Christian Byrne
1322a56653 Cloud/tracking v2 (#6400)
## 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-6400-Cloud-tracking-v2-29c6d73d365081a1ae32e9337f510a9e)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Arjan Singh <arjan@comfy.org>
2025-10-30 20:46:42 -07:00
AustinMroz
9ddead24d6 On failed subgraph resolution, return undefined (#6460)
Resolving an executionId to a locatorId can fail if the current workflow
does not match the queued one. Rather than throwing an error, the
resolution functions have been changed to return undefined.

Of note, all consumers of these functions already had checks to ensure
the returned value is not undefined.
- Even the test for failure state already specified that it should
return instead of throwing an error.

This PR cleans up a frequent sentry error.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6460-On-failed-subgraph-resolution-return-undefined-29c6d73d365081c5860ed7d24a99414c)
by [Unito](https://www.unito.io)
2025-10-30 12:06:52 -07:00
AustinMroz
ca5729a8e7 Add pricing badge when a subgraph contains partner nodes (#6354)
<img width="596" height="213" alt="image"
src="https://github.com/user-attachments/assets/174c5461-f638-42de-b3ad-0e108dee3983"
/>


![api-badge-subgraph_00003](https://github.com/user-attachments/assets/067d0398-47e9-4e97-9e1d-67fac2935e55)


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6354-Add-pricing-badge-when-a-subgraph-contains-partner-nodes-29b6d73d365081c685bec3e9446970eb)
by [Unito](https://www.unito.io)
2025-10-29 20:41:04 -07:00
Christian Byrne
5e9a9923e4 update subscription panel for new designs (#6378)
## Summary

Refactoring of subscription panel to improve maintainability and match
Figma design exactly. Extracted business logic into
`useSubscriptionCredits` and `useSubscriptionActions` composables, added
comprehensive testing, and enhanced the design system with proper
semantic tokens.

- Extract credit calculations and action handlers into reusable
composables
- Add component and unit tests with proper mocking patterns  
- Update terminology from "API Nodes" to "Partner Nodes"
- Make credit breakdown dynamic using real API data instead of hardcoded
values
- Add semantic design tokens for modal card surfaces with light/dark
theme support
- Reduce component complexity from ~100 lines to ~25 lines of logic
- Improve layout spacing, typography, and responsive behavior to match
Figma specs

<img width="1948" height="1494" alt="Selection_2220"
src="https://github.com/user-attachments/assets/b922582d-7edf-4884-b787-ad783c896b80"
/>

<img width="1948" height="1494" alt="Selection_2219"
src="https://github.com/user-attachments/assets/50a9f263-9adb-439d-8a89-94a498d394e3"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6378-update-subscription-panel-for-new-designs-29b6d73d3650815c9ce2c5977ac7f893)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-29 20:15:30 -07:00
Arjan Singh
f2355a6ad1 feat(historyV2): load workflows for images (#6384)
## Summary

Hooked up the "Load Workflow" action to our `history_v2` API.

Note: Our cloud envs were being stress tested right now so images are
loading at time of recording. Images were loading for me during
development before I had time to create the video.


## Screenshots 📷 



https://github.com/user-attachments/assets/02145504-ceae-497b-9049-553796d698da



┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6384-Feat-history-v2-workflows-29b6d73d365081bcb706fe799b8ce66a)
by [Unito](https://www.unito.io)
2025-10-29 18:35:42 -07:00
Jin Yi
06ba106f59 Media Assets Management Sidebar Tab Implementation (#6112)
## 📋 Overview
Implemented a new Media Assets sidebar tab in ComfyUI for managing
user-uploaded input files and generated output files. This feature
supports both local and cloud environments and is currently enabled only
in development mode.

## 🎯 Key Features

### 1. Media Assets Sidebar Tab
- **Imported** / **Generated** files separated by tabs
- Visual display with file preview cards
- Gallery view support (navigable with arrow keys)

### 2. Environment-Specific Implementation
- **`useInternalMediaAssets`**: For local environment
  - Fetches file list via `/files` API
  - Retrieves generation task execution time via `/history` API
  - Processes history data using the same logic as QueueSidebarTab
- **`useCloudMediaAssets`**: For cloud environment
  - File retrieval through assetService
  - History data processing using TaskItemImpl
- Auto-truncation of long filenames over 20 characters (e.g.,
`very_long_filename_here.png` → `very_long_...here.png`)

### 3. Execution Time Display
- Shows task execution time on generated image cards (e.g., "2.3s")
- Calculated from History API's `execution_start` and
`execution_success` messages
- Displayed at MediaAssetCard's duration chip location

### 4. Gallery Feature
- Full-screen gallery mode on image click
- Navigate between images with keyboard arrows
- Exit gallery with ESC key
- Reuses ResultGallery component from QueueSidebarTab

### 5. Development Mode Only
- Excluded from production builds using `import.meta.env.DEV` condition
- Feature in development, scheduled for official release after
stabilization

## 🛠️ Technical Changes

### New Files Added
- `src/components/sidebar/tabs/AssetsSidebarTab.vue` - Main sidebar tab
component
- `src/composables/sidebarTabs/useAssetsSidebarTab.ts` - Sidebar tab
definition
- `src/composables/useInternalMediaAssets.ts` - Local environment
implementation
- `src/composables/useCloudMediaAssets.ts` - Cloud environment
implementation
- `packages/design-system/src/icons/image-ai-edit.svg` - Icon addition

### Modified Files
- `src/stores/workspace/sidebarTabStore.ts` - Added dev mode only tab
display logic
- `src/platform/assets/components/MediaAssetCard.vue` - Added execution
time display, zoom event
- `src/platform/assets/components/MediaImageTop.vue` - Added image
dimension detection
- `packages/shared-frontend-utils/src/formatUtil.ts` - Added media type
determination utility functions
- `src/locales/en/main.json` - Added translation keys


[media_asset_OSS_cloud.webm](https://github.com/user-attachments/assets/a6ee3b49-19ed-4735-baad-c2ac2da868ef)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions <github-actions@github.com>
2025-10-29 03:39:16 +00:00
Arjan Singh
32a803c31e feat(historyV2): reconcile completed workflows (#6340)
## Summary

Running + Finished + History tasks now all work and reconcile correctly
in the queue.

## Changes

1. Reconcile complete workflows so they show up in history.
2. Do the above in a way that minimizes recreation of `TaskItemImpls`
3. Address some CR feedback on #6336 

## Review Focus

I tried to optimize `TaskItemImpls` so we aren't recreating ones for
history items tat already exist. Please give me feedback on if I did
this correctly, or if it was even necessary.

## Screenshots 🎃 



https://github.com/user-attachments/assets/afc08f31-cc09-4082-8e9d-cee977bc1e22

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6340-feat-historyV2-reconcile-completed-workflows-29a6d73d36508145a56aeb99cfa0e6ba)
by [Unito](https://www.unito.io)
2025-10-28 17:40:55 -07:00
Terry Jia
e7f640b436 subscription improve (#6339)
## Summary

Run keyboard shortcut bypasses paywall
Top Up button visible before paywall (confusing - hide until subscribed)
Question mark icon next to commercial models has no tooltip (hide until
added)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6339-subscription-improve-29a6d73d3650818e92c7f60eda01646a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: bymyself <cbyrne@comfy.org>
2025-10-28 13:00:27 -07:00
AustinMroz
6e4471ad62 Fix node sizing in vue mode (#6289)
Before

![broken-resize](https://github.com/user-attachments/assets/1d3651f7-8589-439c-99d1-fa67c5970945)
After

![vue-resize](https://github.com/user-attachments/assets/ef97ea8f-b601-4a5c-9c6a-34d3f4b776d2)

Also add ~~content~~
[contain](https://developer.mozilla.org/en-US/docs/Web/CSS/contain)
styling for improved render performance.

Future:
- Update size scaling for WidgetLayoutField widgets.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6289-Fix-node-sizing-in-vue-mode-2986d73d365081ac8fa0da35a635b226)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-10-28 12:18:57 -07:00
Johnpaul Chiwetelu
b3da6cf1b4 Contextmenu extension migration (#5993)
This pull request refactors how context menu items are contributed by
extensions in the LiteGraph-based canvas. The legacy monkey-patching
approach for adding context menu options is replaced by a new, explicit
API (`getCanvasMenuItems` and `getNodeMenuItems`) for extensions. A
compatibility layer is added to support legacy extensions and warn
developers about deprecated usage. The changes improve maintainability,
extension interoperability, and migration to the new context menu
system.

### Context Menu System Refactor

* Introduced a new API for extensions to contribute context menu items
via `getCanvasMenuItems` and `getNodeMenuItems` methods, replacing
legacy monkey-patching of `LGraphCanvas.prototype.getCanvasMenuOptions`.
Major extension files (`groupNode.ts`, `groupOptions.ts`,
`nodeTemplates.ts`) now use this new API.
[[1]](diffhunk://#diff-b29f141b89433027e7bb7cde57fad84f9e97ffbe5c58040d3e0fdb7905022917L1779-R1771)
[[2]](diffhunk://#diff-91169f3a27ff8974d5c8fc3346bd99c07bdfb5399984484630125fdd647ff02fL232-R239)
[[3]](diffhunk://#diff-04c18583d2dbfc013888e4c02fd432c250acbcecdef82bf7f6d9fd888e632a6eL447-R458)
* Added a compatibility layer (`legacyMenuCompat` in
`contextMenuCompat.ts`) to detect and warn when legacy monkey-patching
is used, and to extract legacy-added menu items for backward
compatibility.
[[1]](diffhunk://#diff-2b724cb107c04e290369fb927e2ae9fad03be9e617a7d4de2487deab89d0d018R2-R45)
[[2]](diffhunk://#diff-d3a8284ec16ae3f9512e33abe44ae653ed1aa45c9926485ef6270cc8d2b94ae6R1-R115)

### Extension Migration

* Refactored core extensions (`groupNode`, `groupOptions`, and
`nodeTemplates`) to implement the new context menu API, moving menu item
logic out of monkey-patched methods and into explicit extension methods.
[[1]](diffhunk://#diff-b29f141b89433027e7bb7cde57fad84f9e97ffbe5c58040d3e0fdb7905022917L1633-L1683)
[[2]](diffhunk://#diff-91169f3a27ff8974d5c8fc3346bd99c07bdfb5399984484630125fdd647ff02fL19-R77)
[[3]](diffhunk://#diff-04c18583d2dbfc013888e4c02fd432c250acbcecdef82bf7f6d9fd888e632a6eL366-R373)

### Type and Import Cleanup

* Updated imports for context menu types (`IContextMenuValue`) across
affected files for consistency with the new API.
[[1]](diffhunk://#diff-b29f141b89433027e7bb7cde57fad84f9e97ffbe5c58040d3e0fdb7905022917R4-L7)
[[2]](diffhunk://#diff-91169f3a27ff8974d5c8fc3346bd99c07bdfb5399984484630125fdd647ff02fL1-R11)
[[3]](diffhunk://#diff-04c18583d2dbfc013888e4c02fd432c250acbcecdef82bf7f6d9fd888e632a6eL2-R6)
[[4]](diffhunk://#diff-bde0dce9fe2403685d27b0e94a938c3d72824d02d01d1fd6167a0dddc6e585ddR10)

### Backward Compatibility and Migration Guidance

* The compatibility layer logs a deprecation warning to the console when
legacy monkey-patching is detected, helping developers migrate to the
new API.

---

These changes collectively modernize the context menu extension
mechanism, improve code clarity, and provide a migration path for legacy
extensions.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5993-Contextmenu-extension-migration-2876d73d3650813fae07c1141679637a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-10-28 04:02:28 +01:00
Alexander Brown
6afdb9529d Fix: Vue-Litegraph conversion bug with Reroutes (#6330)
## Summary

The private fields triggered an error in intitializing the
linkLayoutSync. Turns out that wasn't necessary anymore.

> [!NOTE]
> Edit: Doing some more investigation, it looks like the slot sync can
also be removed?

## Changes

- **What**: Converts JS private fields to typescript private, adds some
readonly declarations
- **What**: Removes the useLinkLayoutSync usage in useVueNodeLifecycle
- **What**: Removes the useSlotLayoutSync usage in useVueNodeLifecycle

## Review Focus

Was the sync doing something that wouldn't be caught in normal
usage/testing?

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6330-Fix-Vue-Litegraph-conversion-bug-with-Reroutes-2996d73d3650819ebb24e4aa2fc51c65)
by [Unito](https://www.unito.io)
2025-10-27 19:36:19 -07:00
Arjan Singh
d26309c7ab feat(historyV2): create sythetic queue priority (#6336)
## Summary

Create display priority based on execution success timestamps.

Next up is displaying in progress prompts in the queue.

## Review Focus

@DrJKL and I discussed logic and decided for history, execution success
(when the prompt finishes) is the best way to assign priority.

This does differ from existing cloud logic which uses execution start
time.

For prompt progress I intend to create a priority for them based on
start time.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6336-feat-historyV2-create-sythetic-queue-priority-2996d73d365081ffa3a0f8071c178066)
by [Unito](https://www.unito.io)
2025-10-27 23:08:33 +00:00
Christian Byrne
234fc3433c use prompt id rather than queue index for history reconciliation (#6327)
## Summary

Changed history reconciliation to use `promptId` instead of `queueIndex`
to support cloud environments that don't have queue indices.

Refactored into pure functions with expressive naming.

## Changes

- Use `promptId` (unique UUID) for reconciliation instead of
`queueIndex` (not available in cloud)
- Extract `reconcileHistoryWithServer` with helpers: `extractPromptIds`,
`isAddedAfter`, `sortNewestFirst`
- Added 34 tests covering reconciliation edge cases, sorting, and limits

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6327-use-prompt-id-rather-than-queue-index-for-history-reconciliation-2996d73d3650818e9471dbeb53cc23bb)
by [Unito](https://www.unito.io)
2025-10-26 23:58:29 -07:00
Terry Jia
9f5245dc80 [refactor] Split mask editor into smaller files (#6308)
## Summary

Split mask editor structure into smaller files

## Changes

This PR is a prerequisite step for [the issue - refactoring the mask
editor using
Vue](https://github.com/Comfy-Org/ComfyUI_frontend/issues/5956). It
splits the current monolithic maskeditor.ts (about 5700 lines) into
separate files; otherwise, the original single file would be very
difficult to analyze or maintain.

This PR itself does not introduce any Vue, nor should it have any
functional changes or modifications. It's purely a code-level split,
with all related files placed in the maskeditor folder.

The original maskeditor.ts has been renamed to maskeditor.ts.backup for
future reference.

## Review Focus

Since this PR is only for splitting purposes, all logic remains
consistent with the original. Therefore, for any reviewer: any code
logic improvements should happen in the subsequent Vue-based
refactoring, not in this PR.

Following this PR, I will perform a Vue-based refactoring of the mask
editor to align with the frontend's overall Vue architecture and provide
better cloud-related support.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6308-refactor-Split-mask-editor-into-smaller-files-2986d73d36508131937dd43e465a47bd)
by [Unito](https://www.unito.io)
2025-10-26 17:34:36 -07:00
Alexander Piskun
fca0ea72f7 feat(api-nodes): add pricing for new LTXV-2 models (#6307)
## Summary

For the upcoming LTXV API nodes.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6307-feat-api-nodes-add-pricing-for-new-LTXV-2-models-2986d73d365081db9994deffc219c6c4)
by [Unito](https://www.unito.io)
2025-10-26 11:45:55 -07:00
Christian Byrne
cd50c54e61 add session cookie auth on cloud dist (#6295)
## Summary

Implemented cookie-based session authentication for cloud distribution,
replacing service worker approach with extension-based lifecycle hooks.

## Changes

- **What**: Added session cookie management via [extension
hooks](https://docs.comfy.org/comfyui/extensions) for login, token
refresh, and logout events
- **Architecture**: DDD-compliant structure with platform layer
(`src/platform/auth/session/`) and cloud-gated extension
- **New Extension Hooks**: `onAuthTokenRefreshed()` and
`onAuthUserLogout()` in [ComfyExtension
interface](src/types/comfy.ts:220-232)

```mermaid
sequenceDiagram
    participant User
    participant Firebase
    participant Extension
    participant Backend

    User->>Firebase: Login
    Firebase->>Extension: onAuthUserResolved
    Extension->>Backend: POST /auth/session (with JWT)
    Backend-->>Extension: Set-Cookie

    Firebase->>Firebase: Token Refresh
    Firebase->>Extension: onAuthTokenRefreshed
    Extension->>Backend: POST /auth/session (with new JWT)
    Backend-->>Extension: Update Cookie

    User->>Firebase: Logout
    Firebase->>Extension: onAuthUserLogout (user null)
    Extension->>Backend: DELETE /auth/session
    Backend-->>Extension: Clear Cookie
```

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6295-add-session-cookie-auth-on-cloud-dist-2986d73d365081868c56e5be1ad0d0d4)
by [Unito](https://www.unito.io)
2025-10-26 00:04:30 -07:00
Arjan Singh
c67c93ff4b feat(api): add history_v2 for cloud outputs (#6288)
## Summary

Backport outputs from new cloud history endpoint

Does:
1. Show history in the Queue
2. Show outputs from prompt execution

Does not:
1. Handle appending latest images generated to queue history
2. Making sure that workflow data from images is available from load
(requires additional API call to fetch)

Most of this PR is:
1. Test fixtures (truncated workflow to test).
2. The service worker so I could verify my changes locally.

## Changes

- Add `history_v2` to `history` adapter
- Add tests for mapping
- Do branded validation for promptIds (suggestion from @DrJKL)
- Create a dev environment service worker so we can view cloud hosted
images in development.

## Review Focus

1. Is the dev-only service work the right way to do it? It was the
easiest I could think of.
4. Are the validation changes too heavy? I can rip them out if needed.

## Screenshots 🎃 


https://github.com/user-attachments/assets/1787485a-8d27-4abe-abc8-cf133c1a52aa

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6288-Feat-history-v2-outputs-2976d73d365081a99864c40343449dcd)
by [Unito](https://www.unito.io)

---------

Co-authored-by: bymyself <cbyrne@comfy.org>
2025-10-25 22:16:38 -07:00
Christian Byrne
2ea6c92030 sort template workflows by required vram (#6285)
## Summary

Resolves https://github.com/Comfy-Org/ComfyUI_frontend/issues/6281 by
implementing the stubbed out vram sorting. Previously was waiting for it
to be added to the templates data and it now has
(https://github.com/Comfy-Org/workflow_templates/blob/main/templates/index.json)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6285-sort-template-workflows-by-required-vram-2976d73d36508164a8f9fab438f53b21)
by [Unito](https://www.unito.io)
2025-10-25 15:52:24 -07:00
AustinMroz
5897e00793 Fix disconnection of subgraphInput links (#6258)
`LLink.disconnect` is intended to cleanup only the link itself. #4800
mistakenly assumed that it would perform all required steps for
disconnection. Later, #5015 would partially resolve this by adding some
of the missing functionality into `LLink.disconnect`, but this still
left output cleanup unhandled and failed to call
`node.onConnectionsChanged`.

This PR instead moves the disconnection code to call the function that
already has robust handling for these items and removes the
no-longer-needed and potentially misleading workaround.

Resolves #6247

Also un-skipped several SubgraphIO tests. They appear to function fine.
I'm assuming the reasons for them being skipped have been resolved.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6258-Fix-disconnection-of-subgraphInput-links-2966d73d36508112ad1fe602cdcf461b)
by [Unito](https://www.unito.io)
2025-10-24 13:37:14 -07:00
Arjan Singh
8ed9be20a9 feat(useRemoteWidget): add cloud firebase auth (#6249)
## Summary

Add Firebase authentication for `useRemoteWidget` Cloud API calls.

## Changes

- Incorporate changes from
c27edb7e94
- Add tests

## Screenshots


<img width="849" height="552" alt="Screenshot 2025-10-23 at 8 41 00 PM"
src="https://github.com/user-attachments/assets/23e07aac-22ea-4222-a90c-00335937a011"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6249-feat-useRemoteWidget-add-cloud-firebase-auth-2966d73d36508121935efc9ed07c47d2)
by [Unito](https://www.unito.io)
2025-10-23 22:54:45 -07:00
Christian Byrne
d7a58a7a9b change cloud feature flags to be loaded dynamically at runtime rather than set in build (#6246)
## Summary

Implements server-side remote configuration to decouple runtime behavior
from build artifacts, enabling dynamic configuration updates without
redeployment.

## Technical Changes

- **Replaced** build-time constants (`__MIXPANEL_TOKEN__`,
`__BUILD_FLAGS__`) with runtime configuration loaded from
`/api/features`
- Configuration now sourced from `window.__CONFIG__` (hydrated from
`/api/features` endpoint)
- **Added** `src/platform/remoteConfig/` service that polls server
configuration every 30 seconds
- **Modified** application bootstrap sequence in `main.ts` to load
remote config before module initialization (required for cloud builds)
- **Removed** global constants: `__BUILD_FLAGS__`, `__MIXPANEL_TOKEN__`.
Runtime subscription enforcement toggle via `subscription_required` flag
- Server health alerts with variant-based severity rendering
(info/warning/error) via topbar badges

## Rationale

- **Build-once-deploy-anywhere**: Single immutable artifact promoted
through environments (staging → production)
- **Zero-downtime configuration**: Update behavior without rebuilding or
redeploying the application
- **Incident response**: Disable features or display alerts dynamically
in response to outages or degraded service
- **Instant rollback**: Revert configuration changes server-side without
artifact redeployment
- **Progressive delivery**: Enable A/B testing, canary releases, and
user/region-based configuration
- **Environment parity**: Eliminate configuration drift between staging
and production builds
- Decouples deployment cadence from configuration changes
- Enables GitOps workflows for configuration management separate from
code deployments
- Supports real-time operational control of client behavior
- Reduces build matrix complexity (no per-environment builds)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6246-change-cloud-feature-flags-to-be-loaded-dynamically-at-runtime-rather-than-set-in-build-2966d73d3650811cbb41c9093961037a)
by [Unito](https://www.unito.io)
2025-10-23 20:16:18 -07:00
Arjan Singh
a3bfc2e91a fix(TopMenuSection): show current user if logged in (#6239)
## Summary

`CurrentUserButton` was not showing at all. Now it shows when the user
is logged in.

## Changes

- Fix template logic
- Add test for `CurrentUserButton` and `LoginButton` display logic.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6239-fix-TopMenuSection-show-current-user-if-logged-in-2956d73d3650812bb9f8fcf5a3c01db5)
by [Unito](https://www.unito.io)
2025-10-23 20:10:06 -07:00
Christian Byrne
89ff8255bd open markdown links in new window/tab (#6229)
## Summary

Changes links in markdown snippets (What's New popup, node info sidebar)
to open the link in a new tab/window rather than directly navigating and
potentially losing unsaved work.



https://github.com/user-attachments/assets/24331bba-e31a-484c-bc11-12cf61805c98



Fixes https://github.com/Comfy-Org/ComfyUI_frontend/issues/6223.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6229-open-markdown-links-in-new-window-tab-2956d73d365081edbb1efb21cd0e2ab2)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
2025-10-23 13:33:38 -07:00
Christian Byrne
f14a6beda5 allow Vue nodes to be resized from all 4 corners (#6187)
## Summary

Enables Vue nodes to resize from all four corners and consolidated the
interaction pipeline.

## Changes

- **What**: Added four-corner handles to `LGraphNode`, wired them
through the refactored `useNodeResize` composable, and centralized the
math/preset helpers under `interactions/resize/` with cleaner pure
functions and lint-compliant markup.

## Review Focus

Corner-to-corner resizing accuracy (position + size), pinned-node guard
preventing resize start, and snap-to-grid behavior at varied zoom
levels.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6187-allow-Vue-nodes-to-be-resized-from-all-4-corners-2936d73d365081c8bf14e944ab24c27f)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
2025-10-23 13:24:28 -07:00
Christian Byrne
4e5eba6c54 refactor: centralize all download utils across app and apply special cloud-specific behavior (#6188)
## Summary

Centralized all download functionalities across app. Then changed
downloadFile on the cloud distribution to stream assets via blob fetches
while desktop/local retains direct anchor downloads. This fixes issue
where trying to download cross-origin resources opens them in the
window, potentially losing the user's unsaved changes.

## Changes

- **What**: Moved `downloadBlob` into `downloadUtil`, routed all callers
(3D exporter, recording manager, node template export, workflow/palette
export, Litegraph save, ~~`useDownload` consumers~~) through shared
helpers, and changed `downloadFile` to `fetch` first when `isCloud` so
cross-origin URLs download reliably
- `useDownload` is the exception since we simply cannot do model
downloads through blob (forcing user to transfer the entire model data
twice is bad). Fortunately on cloud, the user doesn't need to download
models locally anyway.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6188-refactor-centralize-all-download-utils-across-app-and-apply-special-cloud-specific-behav-2946d73d365081de9f27f0994950511d)
by [Unito](https://www.unito.io)
2025-10-23 12:08:30 -07:00
AustinMroz
f63d0f3289 Fix type on LoadClip being marked as asset (#6207)
Previously, asset conversion was performed on any combo widget on a
valid node. As the `type` widget on LoadClip was also a combo widget, it
was being incorrectly converted.

This PR changes the isAssetBrowserEligible check to also verify the
widget name is correct.
<img width="694" height="174" alt="image"
src="https://github.com/user-attachments/assets/a8523ade-7f59-4480-b5e6-8782fd680106"
/>


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6207-Fix-type-on-LoadClip-being-marked-as-asset-2946d73d3650811690f8d3a221a5b76d)
by [Unito](https://www.unito.io)
2025-10-22 19:37:40 -07:00
Arjan Singh
8b7b580ed4 Cloud Auth Backport (#6195)
## Summary

Backports Firebase authentication with cloud environments.

Changes only work when developing for cloud environment locally.

## Changes

- Router guards to force unauthenticated users to sign in.
- Configure auth headers for REST and Websocket connections.
- Code implemented in a way that enables build tree-shaking based on
distribution
- Updates to build process to build cloud distribution and simplify
development workflow

## Review Focus

1. Idomatic Vue/codebase patterns.
2. Build logic (please double check that I integrated correctly with:
https://github.com/Comfy-Org/ComfyUI_frontend/blob/rh-test/vite.config.mts)

## Screenshots (if applicable)




https://github.com/user-attachments/assets/ee4ea3f7-afa6-4da0-ba43-d62ed8ba4e18





┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6195-Feat-cloud-auth-backport-2946d73d365081f395f5f2a89fb7d800)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
2025-10-23 00:06:37 +00:00
sno
69d37e8949 feat: Add @prettier/plugin-oxc for faster formatting (#6088)
Note for reviewers: the code changes in src/* is because I've upgraded
prettier to latest.

the @prettier/plugin-oxc it self only improve performance and doesnt
affect format rules

## Summary

Integrates `@prettier/plugin-oxc` to improve Prettier performance by
~20%.

The oxc plugin provides a faster parser written in Rust, significantly
speeding up formatting operations across the codebase.

## Changes

- Added `@prettier/plugin-oxc` as dev dependency
- Updated `.prettierrc` to use oxc plugin alongside existing
sort-imports plugin
- Added `scripts/benchmark-prettier.js` to measure performance
improvements
- Updated `knip.config.ts` to ignore the oxc plugin
- Updated `eslint.config.ts` to ignore the benchmark script

## Benchmark Results

Ran 3 benchmarks comparing formatting performance on the entire
codebase:

**Without oxc:**
- Median: 32.76s
- Average: 32.89s
- Min: 32.49s
- Max: 33.43s

**With oxc:**
- Median: 26.13s
- Average: 26.35s
- Min: 25.24s
- Max: 27.69s

**Improvement: 20.26% faster (6.64s saved)**

## Testing

The benchmark script can be run with:
```bash
node scripts/benchmark-prettier.js
```

This will:
1. Test formatting performance without oxc plugin
2. Test formatting performance with oxc plugin
3. Display comparison results
4. Restore original configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6088-feat-Add-prettier-plugin-oxc-for-faster-formatting-28e6d73d365081aabb24d3af98c11bb0)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <DrJKL0424@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
2025-10-22 14:49:47 -07:00