* add node header component test
* [refactor] use separate const declarations instead of mutable variable in test - addresses @DrJKL's code style suggestion
Replace mutable `let icon` with descriptive `const expandedIcon` and `const collapsedIcon`
variables for better code clarity and immutability in the chevron icon test.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [config] remove unnecessary vitest exclude patterns - addresses @DrJKL's configuration review
Remove redundant exclude patterns from vitest config as they are already covered by
vitest's default exclusions. Simplifies configuration while maintaining functionality.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [config] remove unnecessary vitest exclude patterns - addresses @DrJKL's configuration review
Remove redundant exclude patterns from vitest config as they are already covered by
vitest's default exclusions. Simplifies configuration while maintaining functionality.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: Initial shadcn configuration
* component: Add Slider component from shadcn-vue
* deps: Add tw-animate-css
* component: Align slider with Figma styles
* component: Set the step value for the slider, update styles
* fix: update component tests to work with Array of values
* vite: Don't reload dev server for test changes
* component: Swap text for a number input kept in sync with the slider
* cleanup: Don't need the override if the input isn't type="number"
* test: add step size tests
* cleanup: Don't need cn for these
* css: Update token names to match new Figma Variables
* lint: Fix camelCase vs train-case in passthrough
* feat: If the value is deleted, revert to the slider state cc: @PabloWiedemann
* feat: Improve cursor styles, grabbable thumb, clickable track
* lint: temporarily disable some warnings
* feat: Grabbing while sliding (most of the time)
* Feat: Change the Run button / ActionBar to dock by default
@PabloWiedemann
* Update test expectations [skip ci]
---------
Co-authored-by: github-actions <github-actions@github.com>
- Add 'none' direction to path renderer
- Map CENTER/NONE to 'none' in adapter
- Keep start-end offset intentional; end follows cursor exactly
- Preserve spline behavior and arrow rendering
Verified with typecheck; no visual changes outside dragging behavior.
* feat: enhance dragging functionality to support multiple selected nodes
* feat: enhance node selection handling to support drag state detection
* feat: enhance node selection handling to support drag state detection
* fix: update event trigger from pointer down to pointer up in LGraphNode tests
* Fix connection of primitives to subgraphNodes
* Fix loading and nested subgraphs with primitives
Medium hackyness, but this saves ~100 lines.
* Use improved type check
* Remove requirement for type assertion
* Add warning comment
---------
Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com>
* fix(canvas): make graph canvas block-level to eliminate baseline gap
- Change <canvas id=graph-canvas> to display:block via Tailwind class
- Removes 1–5 px baseline offset between canvas and container
- Aligns canvas and TransformPane origins; fixes link/slot endpoint drift
No behavioral changes beyond layout origin alignment; no dependent CSS relies on inline/baseline.
* switch block to align-top
* Update test expectations [skip ci]
* Revert "Update test expectations [skip ci]"
This reverts commit ee0dfd4e0a.
* empty commit for ci
* Update test expectations [skip ci]
---------
Co-authored-by: github-actions <github-actions@github.com>
Previously, when toggling the mode of multiple nodes, each node would
have its state individually toggled. Now it enables mode if any node is
not currently set to that mode and only disables if all already match.
* feat: Auto-close LoadWorkflowWarning dialog when all missing nodes are installed
- Add computed property to check if all missing nodes are installed
- Watch for completion and automatically close dialog with 500ms delay
- Show success toast notification when installation completes
- Add translation key for success message
This improves UX by automatically dismissing the warning dialog once the user has successfully installed all missing nodes through the manager.
* fix: settimeout to nexttick
* [auto-fix] Apply ESLint and Prettier fixes
---------
Co-authored-by: GitHub Action <action@github.com>
* fix: Forward the scrolling events to the litegraph canvas.
* prior-art: Use the existing event forwarding logic from useCanvasInteractions (h/t Ben)
* fix: Get proper scaling from properties in the original event, fix browser zoom
* tests: Fix missing property on mock
* types: Cleanup type annotations in the test
* cleanup: Initialize the mocks in place.
* tests: extract createMockPointerEvent
* tests: extract createMockWheelEvent
* tests: extract createMockLGraphCanvas
* tests: Add additional assertion for stopPropagation
* tests: Comment pruning, test rename suggested by @arjansingh
* [feat] Improve UX for disabled node packs in Manager dialog
- Hide "Update All" button when only disabled packs have updates
- Add tooltip on "Update All" hover to indicate disabled nodes won't be updated
- Disable version selector and show tooltip for disabled node packs
- Filter updates to only show enabled packs in the update queue
- Add visual indicators (opacity, cursor) for disabled pack cards
- Add comprehensive test coverage for new functionality
This improves the user experience by clearly indicating which packs
can be updated and preventing confusion about disabled packs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: missing nodes description added
* test: test code modified
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [ci] ignore local browser tests files
this is where i have claude put its one off playwright scripts
* [feat] carve out path to call asset browser in combo widget
* [feat] use buttons on Model Loaders when Asset API setting is on
* tailwind: Migrate out of the js/ts config part 1
* tailwind: Migrate custom variant and utility
* Update test expectations [skip ci]
* tailwind: Use relative colors for alpha variants
* fix: Use the new numbered color tokens
---------
Co-authored-by: github-actions <github-actions@github.com>
* add component tests for slots
* use `for of` for better error report
* add runtime type check to make assertions valid
* add runtime type check to make assertions valid
* fix z-index on selection for vue nodes
* fix unused export
* refactor to DDD
* Use Tailwind utility for pointer events instead of inline style
Move pointer-events: auto from inline style to Tailwind class
pointer-events-auto as suggested in PR review.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Rename defaultSource to layoutSource parameter
Rename parameter in useNodeZIndex options interface for better
clarity as suggested in PR review.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Improve test mocking pattern with vi.mocked approach
Replace global mock object with per-test vi.mocked pattern
and proper Partial typing instead of as any, as suggested
in PR review.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [auto-fix] Apply ESLint and Prettier fixes
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
* feat: add dynamic icon support for NavItem components
- Created NavIcon component with switch-case based icon rendering
- Added iconName prop to NavItem and NavItemData interface
- Updated LeftSidePanel to pass icon names to nav items
- Added sample icons to SampleModelSelector navigation (download, tag, layers, grid)
- Uses i-lucide syntax without imports for better tree-shaking
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add Storybook stories for navigation components
- Add NavIcon.stories.ts with interactive icon selector and all icons gallery
- Add NavItem.stories.ts with text customization and interactive list examples
- Add LeftSidePanel.stories.ts with various navigation configurations
- Remove old Navigation.stories.ts (replaced with component-specific stories)
- Configure slot visibility and hide update:modelValue event in controls
* refactor: simplify NavIcon component and improve type definitions
* fix: add icon size specification for Lucide icons in Storybook
* feature: NavItem story modified
* fix: disable knip unresolved imports rule for virtual icon modules
Add unresolved: 'off' to knip configuration to ignore virtual module imports
from unplugin-icons (~icons/*). These are generated at build time and cannot
be resolved statically.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: v-if condition added
* chore: knip ignoreUnresolved added based on knip issue PR
* refactor: navItem types added & deleting any type on storybook files
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [feat] Refactor overlay compatibility into reusable composable
- Create useTransformCompatOverlayProps composable for centralized overlay prop management
- Update Select, MultiSelect, TreeSelect, and FileUpload components to use composable
- Provides appendTo='self' for transform inheritance in CSS-transformed parents
- Enables easy future additions of other transform compatibility props
- Fix duplicate v-bind attributes by combining props into single computed object
* fix: Keep the canvas container from being scrolled by children
* types: Align the appendTo type with primevue internals
* Update test expectations [skip ci]
---------
Co-authored-by: bymyself <cbyrne@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
* Remove COMFY_VUE_NODE_DIMENSIONS
* [refactor] Use getSlotPosition for Vue nodes in link rendering
Replace direct node position calls with getSlotPosition utility when Vue nodes mode is enabled. This ensures consistent slot positioning across the canvas rendering system.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix getSlotPosition readonly return value (#5433)
* Update accordingly to new type
* Fix canvas/screen conversion formulas in useTransformState (#5406)
* Fix conversion formulas
* update test expectations
* Remove unused type import
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com>
* switch to schema interface and remove assertions at callsites
* [refactor] improve type safety and code organization - addresses @DrJKL's review feedback
- Remove unnecessary type assertions from REROUTE_DEFAULTS
- Use safer Omit<RerouteData, 'id' < /dev/null | 'parentId'> pattern for defaults to prevent hardcoded ID bugs
- Extract asRerouteId and asLinkId utility functions to module scope as pure functions
- Update getRerouteField to handle partial defaults safely
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [fix] revert to clean defaults pattern - removes any type usage
Reverted the overcomplicated Omit pattern back to the simple, working approach.
The original pattern was cleaner and didn't introduce unnecessary complexity.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [feat] add Comfy.Assets.UseAssetAPI to CORE_SETTINGS
* [feat] create AssetService
1. Add service for accessing new Asset API
2. Add fallback model paths logic so empty model directories appear for
the user.
3. Copious tests for them all.
Co-Authored-By: Claude <noreply@anthropic.com>
* [feat] switch between assets and file paths for model data
* [feat] ignore assets with "missing" tag
* [fix] formatting and style
* [fix] call assets API with the correct filters
* [feat] elminate unused modelPath code
* [fix] remove stray comment
* [fix] model manager api was not parsed correctly
---------
Co-authored-by: Claude <noreply@anthropic.com>
* let canvas continue to own selection state management
* fix merge error
* refactor: use computed instead of watcher for selectedNodeIds
Replace watcher pattern with computed for better Vue idioms:
- More reactive and efficient
- Automatically recomputes when dependencies change
- Simpler, more declarative code
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: improve injection error handling for selectedNodeIds
Replace silent fallback with explicit error when SelectedNodeIds
is not provided:
- Fail fast instead of silently using empty Set
- Clear error message for debugging
- Prevents nodes appearing unselected due to missing provider
Addresses DrJKL's concern about injection default behavior.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: improve mocking patterns using vi.mockObject
Replace manual mock interfaces with vi.mockObject for better type safety:
- Use Vitest's built-in mocking utilities instead of manual interfaces
- Properly configure mock return values
- Remove unnecessary type assertions
Addresses DrJKL's feedback on test mocking patterns.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: extract repeated nodeData for clarity
Extract common test nodeData object to reduce duplication:
- Move repeated VueNodeData object to describe scope
- Replace 6 instances of identical nodeData declarations
- Maintain different nodeData for specific test cases
Addresses DrJKL's suggestion to extract repeated test data.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* add type safety to mocks
---------
Co-authored-by: Claude <noreply@anthropic.com>
* knip: Don't ignore exports that are only used within a given file
* knip: More pruning after rebase
* knip: Vite plugin config fix
* knip: vitest plugin config
* knip: Playwright config, remove unnecessary ignores.
* knip: Simplify project file enumeration.
* knip: simplify the config file patterns ?(.optional_segment)
* knip: tailwind v4 fix
* knip: A little more, explain some of the deps.
Should be good for this PR.
* knip: remove unused disabling of classMembers.
It's opt-in, which we should probably do.
* knip: floating comments
We should probably delete _one_ of these parallell trees, right?
* knip: Add additional entrypoints
* knip: Restore UserData that's exposed via the types for now.
* knip: Add as an entry file even though knip says it's not necessary.
* knip: re-export functions used by nodes (h/t @christian-byrne)
* fix: normalize pack IDs to fix version detection for disabled packs
When a pack is disabled, ComfyUI-Manager returns it with a version suffix
(e.g., "ComfyUI-GGUF@1_1_4") while enabled packs don't have this suffix.
This inconsistency caused disabled packs to incorrectly show as having
updates available even when they were on the latest version.
Changes:
- Add normalizePackId utility to consistently remove version suffixes
- Apply normalization in refreshInstalledList and WebSocket updates
- Use the utility across conflict detection and node help modules
- Ensure pack version info is preserved in the object's ver field
This fixes the "Update Available" indicator incorrectly showing for
disabled packs that are already on the latest version.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feature: test code added
* test: packUtils test code added
* test: address PR review feedback for test
improvements
- Remove unnecessary .not.toThrow() assertion
in useManagerQueue test
- Add clarifying comments for version
normalization test logic
- Replace 'as any' with vi.mocked() for better
type safety
---------
Co-authored-by: Claude <noreply@anthropic.com>
* add component tests for vue widgets
* [refactor] improve widget test readability and type safety - addresses @DrJKL's review feedback
- Add mountComponent utility function for consistent test setup
- Add setInputValueAndTrigger helper to batch common test operations
- Replace type assertions with proper instanceof checks for type safety
- Remove duplicate test setup code to improve test readability
- Fix TypeScript errors in WidgetSlider tests
These changes address all review comments by making tests easier to read
and understand while ensuring proper type checking.
* [refactor] apply consistent test patterns to WidgetSelect.test.ts
- Add mountComponent utility function for consistent test setup
- Add setSelectValueAndEmit helper to batch select operations
- Remove repetitive mount boilerplate code throughout tests
- Maintain existing test coverage while improving readability
This ensures all widget component tests follow the same patterns
established in WidgetInputText and WidgetSlider tests.
* Implement subgraph publishing
* Add missing null check
* Fix subgraph blueprint display in workflows tab
* Fix demotion of subgraph blueprints on reload
* Update locales [skip ci]
* Update blueprint def on save, cleanup
* Fix skipped tracking on subgraph publish
When a subgraph is first published, it previously was not added to the
subgraphCache. This would cause deletion to fail until a reload occurred.
* Fix failing vite tests
A couple of tests that were mocking classes broke SubgraphBlueprint
inheritance. Since they aren't testing anythign related to subgraph
blueprints, the subgraph store is mocked as well.
* Make blueprint breadcrumb badge clickable
* Add confirmation for overwrite on publish
* Simplify blueprint badge naming
* Swap to promise.allSettled when fetching subgraphs
* Navigate into subgraph on blueprint edit
* Revert mission of value in blueprint breadcrumb
This was causing the blueprint badge to always display
* Misc code quality fixes
* Set subgraphNode title on blueprint add.
When a subgraph blueprint is added to the graph, the title of the
subgraphNode is now set to be the title of the blueprint.
NOTE: The name of the subgraph node when a blueprint is edited is left
unchanged. This may cause minor user confusion.
* Add "Delete Blueprint" option to breadcrumb
When editing a blueprint, the options provided for the root graph of the
breadcrumb included a Delete Workflow option. This still functioned for
deleting the current blueprint when selected, but didn't make sense. It
has been updated to instead describe that it deletes the current
blueprint
* Extract subgraph load code as function
* Fix subgraphs appearing in library after refresh
Subgraph nodes were hidden from the node library and context menu by
setting skip_list to true. Unfortunately, this causes them to be
mistakenly be caught and registered as vue nodes when a refresh is
performed. This is fixed by adding a check for skip_list.
* Add delete button and confirmation for deletion
* Use more specific warning for blueprint deletion
* At success toast on subgraph publish
Will return later to potentially add a node library link to the toast
* Don't apply subgraph context menu to normal nodes
Subgraph blueprints have a right click -> delete option in the node
library. This was incorrectly being dislplayed on non blueprint nodes.
* Remove hardcoded subgraphs path
Rather happy with this change. Rather than trying to introduce a
recursive import to pass a magic string, this solution is both
sufficient AND allows potential future extensions with less breakage.
* Fix nodeDef update on save
Wait to update the node def cache until after a blueprint has been
saved. Before, changes to links weren't actually being made visisble.
* Fix SaveAs with subgraph blueprints
* Remove ugly serialize/deserialize
Thought I had already tested this, and found that the mere existence of
proxies was causing issues, but simply adding a correct annotation is
sufficient now.
* Improve error specificity
* Framework for user defined blueprint descriptions
BlueprintDescription can be added to a workflows extra field to provide
more useful information about a blueprint's purpose
Actually hooking this up in a way that is user accessible is out of
scope for right now, but this will simplify future implementation.
* Cleanup breadcrumb dropdown options
Removes Dupliate for blueprints, adds a publish subgraph option.
The publish subgraph button currently routes through the save as logic.
Unforunately, this results in the prompt for name referencing workflows.
The cleanest way to resolve this is still being considered
* Move blueprint renaming into blueprint load
Blueprints should automatically set the name of the added node to the
filename when added. This mostly worked, but created uglier edgecases:
The subgraph itself wasn't renamed, and it would need to be
reimplemented to apply when editing a blueprint.
Instead, this is now applied when a subgraphBlueprint is first loaded.
This keeps all the logic routed through a single point
* Move saveAs prompt into workflow class
Ensures that the correct publish text is displayed when editing
blueprints without making an awful mess of imports
* Fix tests by making subgraphBlueprint internal
This has the added benefit of forcing better organization.
Reverts the useWorkflowThumbnail patch as it is no longer required.
* Add tests for subgraph blueprints
* Rewrite confirmation dialog
* Fix overwrite on publish new subgraph
1 is used as a placeholder size as -1 indicates the baking userFile is
temporary, not persisted, and therefore, not able to overwrite when
saved.
* When editing blueprint, tint background blue
* Fix blueprint tint at low LOD
* Set node source for blueprints to Blueprint
* Fix publish test
Making subgraph blueprints non temporary on publish made it so the
following load actually occurs. A mock has been added for this load.
* Fix multiple nits
* Further cleanup: error handling, and comments
* Fixing failing test cases
This also moves the bg tinting to a property of the workflow,
which makes things more extensible in the future.
* Fix temporary marking on publish.
The prior fix to allow overwrite of an existing blueprint on publish was
misguided. By marking a not-yet-loaded file as non-temporary, the load
performed prior to saving was actually fetching the file off disk and
discarding the existing changes. This additionally entirely prevented
publishing when a blueprint did not already exist with the current name.
To fix this, the blueprint is not marked as non-temporary until after
the load occurs. Note that this load is still required as it initializes
the change tracker state required for saving.
* Block unloading subgraph blueprints
Will need to be revisited if lazy loading is implemented, but this
requires solving some ugly sync/async issues.
---------
Co-authored-by: github-actions <github-actions@github.com>