Commit Graph

6523 Commits

Author SHA1 Message Date
Christian Byrne
f1cf8073d6 fix: garbage collect subgraph definitions when SubgraphNode is removed (#8187)
## Summary

When removing a SubgraphNode via `LGraph.remove()`:
- Fire `onRemoved` for all nodes inside the subgraph
- Fire `onNodeRemoved` callback on the subgraph for each inner node
- Remove subgraph definition from `rootGraph.subgraphs` when no other
nodes reference it (checks both root graph nodes and nodes inside other
subgraphs)

This ensures proper cleanup of subgraph definitions and lifecycle
callbacks for nested nodes when subgraph nodes are deleted.

## Changes

### LGraph.ts
Added SubgraphNode-specific cleanup in `remove()` method that:
1. Iterates inner nodes and fires their `onRemoved` callbacks
2. Fires `onNodeRemoved` on the subgraph for downstream listeners (e.g.,
minimap)
3. Garbage collects the subgraph definition when no other nodes
reference it

### SubgraphNode.ts
Fixed `graph` property to match `LGraphNode` lifecycle contract.
Previously it was declared as `override readonly graph` via constructor
parameter promotion, which prevented `LGraph.remove()` from setting
`node.graph = null`. Changed to a regular mutable property with null
guard in `rootGraph` getter.

### LGraph.test.ts
Added 4 tests:
- `removing SubgraphNode fires onRemoved for inner nodes`
- `removing SubgraphNode fires onNodeRemoved callback`
- `subgraph definition is removed when last referencing node is removed`
- `subgraph definition is retained when other nodes still reference it`

## Related

- Fixes #8145
- Part of the subgraph lifecycle cleanup plan (Slice 2: Definition
garbage collection)
2026-01-29 16:19:25 -08:00
Jin Yi
d7654baebf [feat] Show context-appropriate empty state messages in Manager tabs (#8415)
## Summary
Shows tab-specific empty state messages in Node Manager instead of
generic "No search results found" message.

## Changes
- Added computed properties to determine empty state messages based on
current tab and search state
- Display tab-specific messages when a tab is empty without active
search (e.g., "No Missing Nodes" for Missing tab)
- Fall back to search-related messages only when there's an active
search query
- Added Korean translations for empty state messages

| Tab | Empty State Title |
|-----|-------------------|
| All Installed | No Extensions Installed |
| Update Available | All Up to Date |
| Conflicting | No Conflicts Detected |
| Workflow | No Extensions in Workflow |
| Missing | No Missing Nodes |

## Review Focus
- Verify i18n key structure matches existing patterns

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8415-feat-Show-context-appropriate-empty-state-messages-in-Manager-tabs-2f76d73d3650817ab8a0d41b45df3411)
by [Unito](https://www.unito.io)
2026-01-29 16:16:28 -08:00
Comfy Org PR Bot
a032e50721 1.39.2 (#8447)
Patch version increment to 1.39.2

**Base branch:** `main`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8447-1-39-2-2f86d73d3650819e8daccc9c5fbc3a3b)
by [Unito](https://www.unito.io)

Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com>
v1.39.2
2026-01-29 16:12:49 -08:00
Christian Byrne
d9ea36a1d0 refactor: change asset cache from nodeType-keyed to category-keyed (#8433)
## Summary

Refactors the model assets cache in `assetsStore.ts` to be keyed by
category (e.g., 'checkpoints', 'loras') instead of nodeType (e.g.,
'CheckpointLoaderSimple').

## Changes

- Rename `modelStateByKey` to `modelStateByCategory`
- Add `resolveCategory()` helper to translate nodeType to category for
cache lookup
- Multiple node types sharing the same category now share one cache
entry
- Add `invalidateCategory()` method for cache invalidation
- Maintain backwards-compatible public API accepting nodeType
- Update tests for new category-keyed behavior

## Benefits

1. **Deduplication**: Same category = same cache entry = single API call
2. **Simple invalidation**: Delete asset with tag 'checkpoints' then
invalidate cache
3. **Cleaner mental model**: Store to View reactive flow works naturally

## Testing

- All existing tests pass with updates
- Added new tests for category-keyed cache sharing, invalidateCategory,
and unknown node type handling

## Part of Stack

This is **PR 1 of 2** in a stacked PR series:
1. **This PR**: Refactor asset cache to category-keyed (architectural
improvement)
2. **[PR 2
#8434](https://github.com/Comfy-Org/ComfyUI_frontend/pull/8434)**: Fix
deletion invalidation

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8433-refactor-change-asset-cache-from-nodeType-keyed-to-category-keyed-2f76d73d365081999b7fda12c9706ab5)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
2026-01-29 16:03:29 -08:00
AustinMroz
eceed972f5 Fix Help Center display in linear mode (#8438)
The Help Center popover wasn't working in linear mode because the
`#graph-canvas-container` is hidden. This is fixed by instead setting
the target to body. This matches the [default behaviour used by portals
in
rekai-ui](https://github.com/unovue/reka-ui/blob/v2/packages/core/src/Teleport/Teleport.vue)
<img width="476" height="677" alt="image"
src="https://github.com/user-attachments/assets/cca46648-3bce-4b72-a5be-3727e2358217"
/>

I've got a working branch for moving the Help Center to our reka-ui
Popover component, but that'll require a much larger surface area of
code changes.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8438-Fix-Help-Center-display-in-linear-mode-2f76d73d36508112abedf1160f7c3a90)
by [Unito](https://www.unito.io)
2026-01-29 16:01:38 -08:00
Christian Byrne
72a6af4b9e make new queue panel disabled by default (#8444)
## Summary

Was enabled by default for 1.38 during nightly, but should be reverted
back now.

In the future we can now just use `isNightly` flag for this (ref:
https://github.com/Comfy-Org/ComfyUI_frontend/pull/8149)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8444-make-new-queue-panel-disabled-by-default-2f76d73d365081139b54f76d9325101d)
by [Unito](https://www.unito.io)
2026-01-29 23:56:54 +00:00
Rizumu Ayaka
fc38f16543 fix: default image input for the template is displayed as empty on dropdown selection (#8276)
The image input for nodes loaded from templates appears empty in the
Properties Panel.

When the widget's current value (saved in the template) is not in the
available file list returned by the server, the selectedSet is empty,
causing a placeholder to be displayed instead of the actual value.

Added a missingValueItem computed property in WidgetSelectDropdown.vue.
When the current value is not in inputItems or outputItems, it creates a
fallback item and adds it to dropdownItems.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8276-fix-default-image-input-for-the-template-is-displayed-as-empty-on-dropdown-selection-2f16d73d3650817eaad5e4e33637fb74)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
2026-01-29 14:19:52 -08:00
Christian Byrne
faad2c03de feat: increase allowed batch count (on Run button) on cloud (from 4 to 32) (#8436)
## Summary

cloud.comfy.org now suports up to 100 queued jobs at a time
([details](https://x.com/ComfyUI/status/2016622139722572032?s=20)). We
can increase the batch count limit to 32. Possible downside is cloud
having to reject larger number of jobs over the 100 limit if someone go
to 32 and clicks 4+ times. This setting was configurable anyway before,
so this is mostly a QoL change.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8436-feat-increase-allowed-batch-count-on-Run-button-on-cloud-from-4-to-32-2f76d73d365081728650fabefc394046)
by [Unito](https://www.unito.io)
2026-01-29 13:54:52 -08:00
Christian Byrne
d4cec49db5 fix: use merge-multiple for snapshot artifact download (#8432)
## Summary

Fixes the snapshot merge failure introduced by PR #8377
(actions/download-artifact v4→v7 upgrade).

## Root Cause

The v5+ release of `download-artifact` changed behavior: when a
`pattern` matches only a **single artifact**, files are extracted
directly to `path/` without the artifact name subdirectory. When only
one shard had changes, the merge loop couldn't find the expected
`snapshots-shard-*/` directories.

## Fix

Use `merge-multiple: true` — the documented pattern for combining
sharded artifacts. This merges all matched artifacts directly into the
target path, eliminating directory structure assumptions.

## Testing

This fix can be validated by re-running the workflow on [PR
#8276](https://github.com/Comfy-Org/ComfyUI_frontend/pull/8276) after
merge.

---
- Fixes snapshot update workflow regression from #8377

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8432-fix-use-merge-multiple-for-snapshot-artifact-download-2f76d73d3650810b97fdfe28cd3c7694)
by [Unito](https://www.unito.io)

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
2026-01-29 12:58:22 -08:00
AustinMroz
af8433fb3d Support widget specific contextmenu options in vue (#8431)
<img width="614" height="485" alt="image"
src="https://github.com/user-attachments/assets/2a635dec-8bed-4fab-9881-5e6057d482e1"
/>

These options were defined in `litegraphService`. While the existing
code for defining options is reused (to ensure there's no implementation
drift) these extra widget options use the litegraph format for context
menu options and do not belong in `useSelectionMenuOptions`. They have
been moved out of `useLitegraphService` (good), but left in
`litegraphService` (not great)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8431-Support-widget-specific-contextmenu-options-in-vue-2f76d73d3650814fb20fca352dc81e3b)
by [Unito](https://www.unito.io)
2026-01-29 11:38:41 -08:00
Johnpaul Chiwetelu
cabd08f0ec Road to No explicit any: Group 8 (part 6) test files (#8344)
## Summary

This PR removes unsafe type assertions ("as unknown as Type") from test
files and improves type safety across the codebase.

### Key Changes

#### Type Safety Improvements
- Removed all instances of "as unknown as" patterns from test files
- Used proper factory functions from litegraphTestUtils instead of
custom mocks
- Made incomplete mocks explicit using Partial<T> types
- Fixed DialogStore mocking with proper interface exports
- Improved type safety with satisfies operator where applicable

#### App Parameter Removal
- **Removed the unused `app` parameter from all ComfyExtension interface
methods**
- The app parameter was always undefined at runtime as it was never
passed from invokeExtensions
- Affected methods: init, setup, addCustomNodeDefs,
beforeRegisterNodeDef, beforeRegisterVueAppNodeDefs,
registerCustomNodes, loadedGraphNode, nodeCreated, beforeConfigureGraph,
afterConfigureGraph

##### Breaking Change Analysis
Verified via Sourcegraph that this is NOT a breaking change:
- Searched all 10 affected methods across GitHub repositories
- Only one external repository
([drawthingsai/draw-things-comfyui](https://github.com/drawthingsai/draw-things-comfyui))
declares the app parameter in their extension methods
- That repository never actually uses the app parameter (just declares
it in the function signature)
- All other repositories already omit the app parameter
- Search queries used:
- [init method
search](https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/.*+lang:typescript+%22init%28app%22+-repo:Comfy-Org/ComfyUI_frontend&patternType=standard)
- [setup method
search](https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/.*+lang:typescript+%22setup%28app%22+-repo:Comfy-Org/ComfyUI_frontend&patternType=standard)
  - Similar searches for all 10 methods confirmed no usage

### Files Changed

Test files:
-
src/components/settings/widgets/__tests__/WidgetInputNumberInput.test.ts
- src/services/keybindingService.escape.test.ts  
- src/services/keybindingService.forwarding.test.ts
- src/utils/__tests__/newUserService.test.ts →
src/utils/__tests__/useNewUserService.test.ts
- src/services/jobOutputCache.test.ts
-
src/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts
-
src/renderer/extensions/vueNodes/widgets/composables/useIntWidget.test.ts
-
src/renderer/extensions/vueNodes/widgets/composables/useFloatWidget.test.ts

Source files:
- src/types/comfy.ts - Removed app parameter from ComfyExtension
interface
- src/services/extensionService.ts - Improved type safety with
FunctionPropertyNames helper
- src/scripts/metadata/isobmff.ts - Fixed extractJson return type per
review
- src/extensions/core/*.ts - Updated extension implementations
- src/scripts/app.ts - Updated app initialization

### Testing
- All existing tests pass
- Type checking passes  
- ESLint/oxlint checks pass
- No breaking changes for external repositories

Part of the "Road to No Explicit Any" initiative.

### Previous PRs in this series:
- Part 2: #7401
- Part 3: #7935
- Part 4: #7970
- Part 5: #8064
- Part 6: #8083
- Part 7: #8092
- Part 8 Group 1: #8253
- Part 8 Group 2: #8258
- Part 8 Group 3: #8304
- Part 8 Group 4: #8314
- Part 8 Group 5: #8329
- Part 8 Group 6: #8344 (this PR)
2026-01-29 11:03:17 -08:00
AustinMroz
868180eb28 Disable logs button in sidebar on cloud (#8429)
Since cloud doesn't currently provide logs, this button was just causing
confusion.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8429-Disable-logs-button-in-sidebar-on-cloud-2f76d73d365081a4b909dd9a105e381e)
by [Unito](https://www.unito.io)
2026-01-29 09:58:25 -08:00
Alexander Brown
c51916d103 Chore: Add workflow dispatch to E2E (#8422)
Also remove old branches from the ignore

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8422-Chore-Add-workflow-dispatch-to-E2E-2f76d73d365081d0940dceaa37231ca7)
by [Unito](https://www.unito.io)
2026-01-29 08:47:18 -08:00
Comfy Org PR Bot
d2ff7d518a 1.39.1 (#8382)
Patch version increment to 1.39.1

**Base branch:** `main`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8382-1-39-1-2f76d73d36508126840cdc74593952e5)
by [Unito](https://www.unito.io)

---------

Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Austin Mroz <austin@comfy.org>
v1.39.1
2026-01-29 00:31:49 -08:00
AustinMroz
44baadd7ca Implement clickable badges (#8401)
Adds an `onClick` handler to LGraphBadge

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8401-Implement-clickable-badges-2f76d73d365081b3b23fc1eaa3bc65b8)
by [Unito](https://www.unito.io)
2026-01-29 00:04:28 -08:00
AustinMroz
3866fe7eaa Fix flake hidream test (#8406)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8406-Fix-flake-hidream-test-2f76d73d3650814daae8fb7775fa3073)
by [Unito](https://www.unito.io)
2026-01-29 00:02:30 -08:00
Jin Yi
4debbf8268 [bugfix] Disable install button when already installed version is selected (#8412)
## Summary
Prevent re-installing an already installed version by disabling the
Install button and the version option in the selector.

## Changes
- Add `isVersionInstalled()` function to check if a version is already
installed
- Add `isInstallDisabled` computed to disable Install button when
selected version is installed
- Add `option-disabled="isInstalled"` to Listbox to prevent selecting
installed versions

Fixes the issue where users could trigger duplicate install operations
by selecting the currently installed version.

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

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8412-bugfix-Disable-install-button-when-already-installed-version-is-selected-2f76d73d365081cb859ff98a3d1c64e6)
by [Unito](https://www.unito.io)
2026-01-28 23:58:12 -08:00
Christian Byrne
23a5baef43 feat: add category support for blueprints and protect global blueprints (#8378)
## Summary

This PR adds two related features for subgraph blueprints:

### 1. Protect Global Blueprints from Deletion
- Added `isGlobalBlueprint()` helper that distinguishes blueprints by
`python_module` field
- User blueprints have `python_module: 'blueprint'`
- Global (installed) blueprints have `python_module` set to the node
pack name
- Guarded `deleteBlueprint()` to show a warning toast for global
blueprints
- Hidden delete menu in node library for global blueprints

### 2. Category Support for Blueprints
- User blueprints now use category `Subgraph Blueprints/User`
- Global blueprints use `Subgraph Blueprints/{category}` if category is
provided, otherwise `Subgraph Blueprints`
- Extended `GlobalSubgraphData.info` type with optional `category` field
- Added `category` to `zSubgraphDefinition` schema

## Files Changed
- `src/stores/subgraphStore.ts` - Core logic for both features
- `src/stores/subgraphStore.test.ts` - Tests for `isGlobalBlueprint`
- `src/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue` - Hide
delete menu for global blueprints
- `src/scripts/api.ts` - Extended `GlobalSubgraphData` type
- `src/platform/workflow/validation/schemas/workflowSchema.ts` - Added
category to schema
- `src/locales/en/main.json` - Added translation key

## Testing
-  `pnpm typecheck` passed
-  `pnpm lint` passed

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8378-feat-add-category-support-for-blueprints-and-protect-global-blueprints-2f66d73d36508137aa67c2d88c358b69)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: AustinMroz <austin@comfy.org>
2026-01-28 23:30:48 -08:00
Christian Byrne
0faf2220b8 fix: dragging (e.g., when selecting text) in Markdown note causes node to drag (#8413)
## Summary

When attempting to select text inside Vue node Markdown widget's
textarea (edit mode), the node would drag instead of text being
selected.

Root cause: WidgetMarkdown.vue's Textarea only had @click.stop and
@keydown.stop, but was missing pointer event modifiers. The pointerdown
event bubbled up to LGraphNode.vue which initiated node drag.

*Fix*: Add @pointerdown.capture.stop, @pointermove.capture.stop, and
@pointerup.capture.stop to match the pattern used in WidgetTextarea.vue.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8413-fix-dragging-e-g-when-selecting-text-in-Markdown-note-causes-node-to-drag-2f76d73d3650816dbf9bdf893775c3d4)
by [Unito](https://www.unito.io)

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 23:18:23 -08:00
Jin Yi
65ff23c5af [bugfix] Fix manager missing node tab with shared composable (#8409) 2026-01-29 06:23:47 +00:00
Alexander Brown
6ce60a11a4 test: use createTestingPinia instead of createPinia (#8376)
Replace \createPinia\ with \createTestingPinia({ stubActions: false })\
from \@pinia/testing\ across 45 test files for proper test isolation.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8376-test-use-createTestingPinia-instead-of-createPinia-2f66d73d36508137a9f0daffcddc86f7)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 22:21:38 -08:00
Christian Byrne
3b5d124029 fix: use getAuthHeader in createCustomer to support API key auth (#8408)
## Summary

Fixes authentication failure when using API key authentication on
staging server after frontend update to 1.33.10.

<img width="1160" height="709" alt="image"
src="https://github.com/user-attachments/assets/fe56866d-1819-419e-9f53-35a123d764c3"
/>


## Changes

- **What**: Changed `createCustomer()` to use `getAuthHeader()` instead
of `getFirebaseAuthHeader()`, allowing API key users to authenticate
successfully

## Review Focus

- Verify `getAuthHeader()` correctly falls back to API key when no
Firebase token exists
- Backend `/customers` endpoint supports `X-API-KEY` header (per cloud
PR #1766)

Fixes COM-12398

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8408-fix-use-getAuthHeader-in-createCustomer-to-support-API-key-auth-2f76d73d3650819994e3e6d3ed9f3dfa)
by [Unito](https://www.unito.io)

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 22:12:28 -08:00
Alexander Brown
bd4920febc Chore: Actions updates and cleanup (#8377)
## Summary

...

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8377-WIP-Chore-Actions-updates-and-cleanup-2f66d73d3650818483a8dffa32a6f245)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 21:22:39 -08:00
Jin Yi
bd916096ac fix: add null check in getCanvasCenter to prevent crash on asset insert (#8399)
## Summary
Adds null check in `getCanvasCenter()` to prevent crash when inserting
asset as node before canvas is fully initialized.

## Changes
- **What**: Added optional chaining for `app.canvas?.ds?.visible_area`
with fallback to `[0, 0]`

## Review Focus
- Simple defensive fix - returns origin position if canvas not ready

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

Co-Authored-By: Claude <noreply@anthropic.com>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8399-fix-add-null-check-in-getCanvasCenter-to-prevent-crash-on-asset-insert-2f76d73d365081e88c08ef40ea9e7b78)
by [Unito](https://www.unito.io)
2026-01-29 13:19:51 +09:00
guill
9be853f6b5 feat: support dev-only nodes (#8359)
## Summary

Support `dev_only` property to node definitions that hides nodes from
search and menus unless dev mode is enabled. Dev-only nodes display a
"DEV" badge when visible.

This functionality is primarily intended to support unit-testing nodes
on Comfy Cloud, but also has other uses.

## Changes

- **What**: Nodes flagged as dev_only in the node schema will only
appear in search and menus if Dev Mode is on.

## Screenshots (if applicable)

With Dev Mode off:
<img width="2189" height="1003" alt="image"
src="https://github.com/user-attachments/assets/a08e1fd7-dca9-4ce1-9964-5f4f3b7b95ac"
/>

With Dev Mode on:
<img width="2201" height="1066" alt="image"
src="https://github.com/user-attachments/assets/7fe6cd1f-f774-4f48-b604-a528e286b584"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8359-feat-support-dev-only-nodes-2f66d73d36508102839ee7cd66a26129)
by [Unito](https://www.unito.io)
2026-01-28 19:41:45 -08:00
Christian Byrne
2103dcc788 fix: increase Vue node resize handle size for better usability (#8391)
## Summary

Increases the resize handle size on Vue nodes to improve usability,
especially when nodes are selected.

## Changes

- **What**: Increased resize handle from 12px to 20px and offset it
slightly outside the node boundary to avoid overlap with selection
outline

## Review Focus

The resize handle was too small and became harder to grab when the node
was selected (the 2px outline rendered outside the box, visually
obscuring the corner). This fix increases the hit area and positions it
to extend beyond the node edge.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8391-fix-increase-Vue-node-resize-handle-size-for-better-usability-2f76d73d36508136b2aac51bc0d53551)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
2026-01-28 19:15:40 -08:00
Simula_r
fe7d89d1b1 fix: move WorkspaceAuthGate to LayoutDefault for proper re-login hand… (#8381)
## Summary

- Move WorkspaceAuthGate from App.vue to LayoutDefault.vue so it only
wraps authenticated routes
- Change initialize() to run in onMounted() for proper Vue lifecycle
- Restore immediate: true in cloudRemoteConfig watcher as backup
- Gate now mounts fresh after login, fixing re-login feature flag issue

The root cause was a race condition: after logout + page reload, the
cloudRemoteConfig watcher could be set up after the user already logged
in, missing the isLoggedIn change and never calling /features endpoint.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8381-fix-move-WorkspaceAuthGate-to-LayoutDefault-for-proper-re-login-hand-2f66d73d36508182a3dec09a49214a00)
by [Unito](https://www.unito.io)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 18:33:44 -08:00
pythongosssss
e4f43d5cc4 Add color picker widget using native HTML5 input element (#8384)
## Summary

Adds support for the color picker widget when using Litegraph nodes, it
is already supported in Nodes 2.0

## Changes

- **What**: Add custom drawing of color picker widget using HTML 5
native color input element
- This enables us to add a core node using the COLOR type that works on
both legacy and Nodes 2.0

## Screenshots (if applicable)
Chrome Windows:
<img width="743" height="493" alt="image"
src="https://github.com/user-attachments/assets/b2e421e0-3a1e-4b72-8856-ae5e40ac0661"
/>

Firefox Windows:
<img width="606" height="447" alt="image"
src="https://github.com/user-attachments/assets/27db5552-6ba2-4de0-af26-ea1727808b4b"
/>

Nodes 2.0 (unchanged):
<img width="597" height="258" alt="image"
src="https://github.com/user-attachments/assets/8bfcf408-e11b-481e-b78f-208b4db80f05"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8384-Add-color-picker-widget-using-native-HTML5-input-element-2f76d73d365081c69fe2f39f01fff539)
by [Unito](https://www.unito.io)
2026-01-28 17:55:12 -08:00
AustinMroz
d5e9be6a64 Additional linear tweaks (#8375)
- Textareas have a fixed (larger) height. This was requested by design
and I thought I fixed it while back.
  | Before | After |
  | ------ | ----- |
| <img width="360" alt="before"
src="https://github.com/user-attachments/assets/35ecfa42-4812-43b3-9844-4ef1f757ae40"
/> | <img width="360" alt="after"
src="https://github.com/user-attachments/assets/8d13e114-6524-4f3e-ae61-0d31d754466c"
/>|
- Since the typeform survey popover doesn't work well on mobile, the
button will instead open the survey in a new tab for mobile users.
- Workaround for the first linear output on local not being
automatically selected for display
- Add the linear mode toggle to the bottom left of mobile layout
<img width="634" height="90" alt="image"
src="https://github.com/user-attachments/assets/571c672c-5913-4dc9-84f9-d16c49b4a587"
/>
- Adds a hamburger menu to the mobile layout providing buttons for
opening workflows, templates, and an additional exit linear option.
- Button takes up a full line of space, so it doesn't provide much space
savings currently. May need some design iteration.
<img width="635" height="225" alt="image"
src="https://github.com/user-attachments/assets/a305e795-db0d-4265-b64b-04326a69216d"
/>

And an unrelated tweak requested by Comfy: when opening templates, the
searchbar is autofocused.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8375-Additional-linear-tweaks-2f66d73d36508172a5e7e716d0cba873)
by [Unito](https://www.unito.io)
2026-01-28 15:22:41 -08:00
Alexander Brown
8aca2ed197 feat: Change the card description to the filename (#8348)
## Summary

No longer duplicates the badge info for the Model type.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8348-feat-Change-the-card-description-to-the-filename-2f66d73d3650818d99e1de479d1f8486)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 14:25:07 -08:00
Benjamin Lu
cbd073f89d Add inline queue progress bar and text summary (#8271)
Add inline queue progress bar and summary per the new designs.

This adds an inline 3px progress bar in the actionbar container (docked
or floating) and a compact summary line below the top menu that follows
when floating, both gated by the QPO V2 flag and hidden while the
overlay is expanded.


https://github.com/user-attachments/assets/da8ec7b7-35f4-4d52-a83b-15c21b484eba

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8271-Add-inline-queue-progress-bar-and-summary-for-QPO-V2-2f16d73d36508132a6dff247f71e11e4)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
2026-01-28 12:20:13 -08:00
Alexander Brown
e44b411ff6 test: simplify test file mocking patterns (#8320)
Simplifies test mocking patterns across multiple test files.

- Removes redundant `vi.hoisted()` calls
- Cleans up mock implementations
- Removes unused imports and variables

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8320-test-simplify-test-file-mocking-patterns-2f46d73d36508150981bd8ecb99a6a11)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
2026-01-28 12:17:16 -08:00
Terry Jia
3e2352423b fix: remove redundant forceRender call and add ResizeObserver guard (#8372)
## Summary
- Remove duplicate forceRender() in ResizeObserver callback since
handleResize() already calls it
- Add guard for environments without ResizeObserver support
- Disconnect existing observer before reassigning to prevent leaks

requested by @DrJKL in
https://github.com/Comfy-Org/ComfyUI_frontend/pull/8351

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8372-fix-remove-redundant-forceRender-call-and-add-ResizeObserver-guard-2f66d73d3650811bb3a6de5c59b3c1fb)
by [Unito](https://www.unito.io)
2026-01-28 11:51:40 -08:00
Christian Byrne
3720b3e794 feat: make invalid URL error message more actionable (#8368)
## Summary

Updates the error message shown when users enter an unsupported URL in
the BYOM (Bring Your Own Model) upload dialog.

**Before:** "Only URLs from Civitai, Hugging Face are supported"
**After:** "Please check the link format. Only URLs from Civitai,
Hugging Face are supported."

This provides more actionable guidance by suggesting users verify their
link format before listing the supported sources.

## Changes

- Updated `unsupportedUrlSource` i18n key in `src/locales/en/main.json`

## Testing

- `pnpm typecheck` 
- `pnpm lint` 
- Manual: Enter invalid URL (e.g.,
`https://example.com/model.safetensors`) in model upload dialog

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8368-feat-make-invalid-URL-error-message-more-actionable-2f66d73d3650810bbcc1e9fa3d1cd962)
by [Unito](https://www.unito.io)

Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
2026-01-28 02:15:09 -08:00
Terry Jia
26eb3eff4d fix: add ResizeObserver to fix Preview3D initial render stretch (#8351)
## Summary

When Preview3D node was added to canvas, the Three.js scene would
stretch outside the node bounds until mouse hover. This happened because
the container size was not stable during initialization.

Add ResizeObserver to Load3d class to automatically refresh viewport
when container size changes, ensuring correct render dimensions.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8351-fix-add-ResizeObserver-to-fix-Preview3D-initial-render-stretch-2f66d73d3650810cbd1fc64dde9ddc17)
by [Unito](https://www.unito.io)
2026-01-28 05:11:54 -05:00
Rizumu Ayaka
dd3e4d3edc fix: hide label of textarea in right side panel + align switch to the left (#8279)
<img width="350" alt="image"
src="https://github.com/user-attachments/assets/3ff3f83c-163b-44df-8b68-7fe18c3266c4"
/>
 | 
<img width="350" alt="CleanShot 2026-01-23 at 21 25 04@2x"
src="https://github.com/user-attachments/assets/c2c630f3-6990-4a55-aa8f-a19297ffee52"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8279-fix-hide-label-of-textarea-in-right-side-panel-align-switch-to-the-left-2f16d73d365081e9b932fb2be873b660)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-01-27 23:21:03 -08:00
Alexander Brown
8b514463b3 CI: Add formatting after generating locales. (#8360)
## Summary

Hopefully prevent thrashing from formatting disagreements.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8360-CI-Add-formatting-after-generating-locales-2f66d73d36508143a2f6d5ba90056110)
by [Unito](https://www.unito.io)
2026-01-27 22:31:54 -08:00
Comfy Org PR Bot
608ad1d74c 1.39.0 (#8336)
Minor version increment to 1.39.0

**Base branch:** `main`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8336-1-39-0-2f56d73d365081c3a03bd0381a1a7ddc)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <448862+DrJKL@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Austin Mroz <austin@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
v1.39.0
2026-01-27 21:56:40 -08:00
Christian Byrne
5c99f89e9d test: improve refreshRemoteConfig test quality (#8356)
Addresses review feedback from #8266:

- Use vi.stubGlobal for global fetch mock
- Extract mockSuccessResponse and mockErrorResponse helpers to reduce
duplication
- Add test verifying 500 responses preserve existing config (only
401/403 clear config)

Related: #8266

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8356-test-improve-refreshRemoteConfig-test-quality-2f66d73d365081f7b207c2fd2b8a8179)
by [Unito](https://www.unito.io)
2026-01-27 22:18:34 -07:00
Jin Yi
4cf55a7215 [refactor] Manager dialog design improvements (#8247)
## Summary
Refactored Manager dialog components for cleaner button rendering logic
and improved visibility.

## Changes
- **InfoPanelHeader**: Centralized button rendering logic (try update,
uninstall, install) instead of using slot overrides
- **PackTryUpdateButton**: Changed variant from `textonly` to `inverted`
for better visibility
- **InfoPanel**: Removed slot override and unused imports, simplified
component
- **ManagerDialog**: Design modifications for improved UX
- **PackCard/PackBanner**: Component refinements
- **useManagerDisplayPacks**: New composable for display pack management

## Review Focus
- Button visibility and styling with `inverted` variant
- Centralized button logic in InfoPanelHeader

## Before

[manager-before.webm](https://github.com/user-attachments/assets/4cef5f10-9cb2-4a31-a095-b170643e481d)

## After

[manager-after.webm](https://github.com/user-attachments/assets/9b693b32-59ca-4c88-b7e7-9a78aba19df7)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8247-refactor-Manager-dialog-design-improvements-2f06d73d365081bf9f07efa043caa378)
by [Unito](https://www.unito.io)
2026-01-28 14:11:46 +09:00
Christian Byrne
e8b088ce50 feat: add composable to determine if user is eligible for nightly survey(s) (#8189)
## Summary

Adds `useSurveyEligibility` composable that determines whether a user
should see a survey based on multiple criteria: nightly localhost build
only (`isNightly && !isCloud && !isDesktop`), configurable usage
threshold (default 3), 14-day global cooldown between any surveys,
once-per-feature-ever display, optional percentage-based sampling, and
user opt-out support. All state persists to localStorage. Includes
extensive unit tests covering all eligibility conditions.

See:

- https://github.com/Comfy-Org/ComfyUI_frontend/pull/8149
- https://github.com/Comfy-Org/ComfyUI_frontend/pull/8175

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8189-feat-add-composable-to-determine-if-user-is-eligible-for-nightly-survey-s-2ee6d73d365081f088f2fd76032cc60a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-01-27 21:31:00 -07:00
Simula_r
34fc28a39d Feat/workspaces 5 auth gate check (#8350)
## Summary

- Fix auth related race conditions with a new WorkspaceAuthGate in
App.vue
- De dup initialization calls 
- Add state machine to track state of refreshRemoteConfig
- Fix websocket not using new workspace jwt
- Misc improvments

## Changes

- **What**: Mainly WorkspaceAuthGate.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-8350-Feat-workspaces-5-auth-gate-check-2f66d73d365081b1a49afcd418fab3e7)
by [Unito](https://www.unito.io)
2026-01-27 20:28:44 -08:00
pythongosssss
d890e7568a Add asset deletion progress indicator (#7906)
## Summary

Currently the delay between user action and visual response is too long
and it looks like it hasn't worked.
This adds a visual indicator that the action is processing.

## Changes

- add loading indicator while asset is deleting

## Screenshots (if applicable)
(Artifically delayed deletion)


https://github.com/user-attachments/assets/a9a8b9fe-896d-4666-b643-ec8b990f6444

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7906-Add-asset-deletion-progress-indicator-2e26d73d365081ed82b8e770ba3d0615)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Jin Yi <jin12cc@gmail.com>
2026-01-27 21:21:50 -07:00
Benjamin Lu
2c54b0dab0 Revert/undo-788f5083-ef8657bb (#8353)
This reverts the addition of GTM for 1.38, as it was still present in
the built files.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8353-Revert-undo-788f5083-ef8657bb-2f66d73d365081818d43fcaab220a4ef)
by [Unito](https://www.unito.io)
2026-01-28 03:48:31 +00:00
Jin Yi
17bd5f527a feat: Add cancel button to active job card in grid view (#8264)
## Summary
Add a cancel (x) button overlay to active job cards in grid view,
matching the existing list view behavior.

## Changes
- **What**: Added hover-triggered cancel button to `ActiveJobCard.vue`
using the existing `useJobActions` composable
- Button appears on hover for jobs in cancellable states (pending,
initialization, running)

<img width="1710" height="1107" alt="스크린샷 2026-01-23 오후 5 11 04"
src="https://github.com/user-attachments/assets/31a6b6d1-46e7-49c4-a253-92260cb28514"
/>
<img width="1710" height="1107" alt="스크린샷 2026-01-23 오후 5 10 59"
src="https://github.com/user-attachments/assets/b559a81e-8e62-4858-b8e7-92de9caa2919"
/>


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8264-feat-Add-cancel-button-to-active-job-card-in-grid-view-2f16d73d3650817d83f0dd3b955759cb)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-01-28 12:25:57 +09:00
AustinMroz
89571c7a64 Prevent configuring a node to a placeholder nodeId (#8342)
Litegraph uses `-1 ` as a placeholder node id to indicate that a node
should be assigned a new node id when added to the graph. Under some
unknown circumstances it's possible for a node to have this placeholder
id saved in a workflow file.

When this occurs, the node is loaded and assigned a new id, but then
configured back to the placeholder id. This PR makes it so the newly
assigned id is kept instead.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8342-Prevent-configuring-a-node-to-a-placehodler-nodeId-2f56d73d365081ed8217e989187b15c8)
by [Unito](https://www.unito.io)
2026-01-27 19:01:06 -08:00
Alexander Brown
a7862fc4b7 feat: Asset Browser Placeholder update (#8349)
## Summary

Remind Creators that they can add models that they don't have available
yet

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8349-feat-Asset-Browser-Placeholder-update-2f66d73d3650815f83b4e7ce3587740c)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-01-27 18:58:50 -08:00
AustinMroz
803062bccd Prevent partial copy of custom widgets when performing linked promotion on subgraphs (#6079)
The `toConcrete` call creates a restricted view of a widget that extends
from `BaseWidget`. A copy of the widget created by `createCopyForNode`
will also inherit this restricted view. This creates two problems
- Some widget properties (like `displayValue`) have been judged unsafe
and are explicitly blacklisted from being copied
- The widget now extends from `BaseWidget`. This results in the widget
being processed differently in some logic, such as `#processWidgetClick`
- Because `LegacyWidget` provides an implementation for `onClick`, the
presence of click handlers can not be used to determine which should be
used.

As a proposed, minimal workaround. Widgets which do not already extend
from BaseWidget are no longer cloned through `createCopyForNode`.

Because this PR involves side-stepping properties which have been
explicitly blacklisted. I'd recommend waiting to merge/backport until
after the release of 1.28.7

Resolves Kosinkadink/ComfyUI-VideoHelperSuite#569

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6079-Prevent-partial-copy-of-custom-widgets-when-performing-linked-promotion-on-subgraphs-28d6d73d36508198950efd401186ddef)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
2026-01-27 18:45:48 -08:00
Jin Yi
e3bad033ed [refactor] SearchBox and MultiSelect style improvements (#8328) 2026-01-28 02:11:45 +00:00
Johnpaul Chiwetelu
3b5d285fe2 Fix: Implement scope-aware filtering for template modal (#8335)
## Summary
- Fixes template filtering to be scope-aware, preventing empty results
when switching categories
- Filters now only show as selected when they exist in the current
category scope
- User selections are still persisted in localStorage for convenience

## Problem
When users selected filters (e.g., Image-specific filters) and switched
to a different category (e.g., Video), the persisted filters would cause
empty results because those filter values didn't exist in the new scope.

## Solution
- Modified `useTemplateFiltering` composable to track which filters are
"active" (applicable to current scope)
- Only active filters are shown as selected in the UI
- Only active filters are applied to the filtering logic
- All user selections are still persisted in localStorage
- When returning to a category, previously selected filters
automatically reactivate if applicable

## Test Plan
Tested manually in browser:
1. Navigate to Image category
2. Select filters like "Image" and "Image Edit" from Tasks dropdown
3. Switch to Video category - filters show as "0 selected" (Image/Image
Edit don't exist in Video)
4. Return to Image category - filters are automatically reselected (2
selected)
5. No empty results when switching between categories

## Changes
- `useTemplateFiltering.ts`: Added scope-aware filtering logic with
active/inactive filter distinction
- `WorkflowTemplateSelectorDialog.vue`: Pass navigation context and use
active filters for UI
- `useTemplateFiltering.test.ts`: Added comprehensive tests for
scope-aware behavior



https://github.com/user-attachments/assets/706ddabf-abad-4ff9-a378-6603d275d15a
2026-01-28 03:03:30 +01:00