## Summary
- Enable `verbatimModuleSyntax` compiler option in TypeScript
configuration
- Update all type imports to use explicit `import type` syntax
- This change will Improve tree-shaking and bundler compatibility
## Motivation
The `verbatimModuleSyntax` option ensures that type-only imports are
explicitly marked with the `type` keyword. This:
- Makes import/export intentions clearer
- Improves tree-shaking by helping bundlers identify what can be safely
removed
- Ensures better compatibility with modern bundlers
- Follows TypeScript best practices for module syntax
## Changes
- Added `"verbatimModuleSyntax": true` to `tsconfig.json`
- Updated another 48+ files to use explicit `import type` syntax for
type-only imports
- No functional changes, only import/export syntax improvements
## Test Plan
- [x] TypeScript compilation passes
- [x] Build completes successfully
- [x] Tests pass
- [ ] No runtime behavior changes
🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5533-feat-enable-verbatimModuleSyntax-in-TypeScript-config-26d6d73d36508190b424ef9b379b5130)
by [Unito](https://www.unito.io)
## Summary
- Added complete Turkish language translation for ComfyUI Frontend
- Integrated Turkish locale into the i18n system
- Added Turkish as a selectable language option in settings
## Implementation Details
- Added Turkish translation files provided by @naxci1:
- `src/locales/tr/main.json` - Main UI translations
- `src/locales/tr/commands.json` - Command translations
- `src/locales/tr/nodeDefs.json` - Node definitions translations
- `src/locales/tr/settings.json` - Settings translations
- Updated `src/i18n.ts` to import and register Turkish locale
- Added Turkish option to language selector in
`src/constants/coreSettings.ts`
## Test Plan
- [ ] Verify Turkish translations load correctly
- [ ] Test language switching to/from Turkish
- [ ] Check all UI elements display properly in Turkish
- [ ] Verify node descriptions and tooltips in Turkish
- [ ] Test command palette in Turkish
Fixes#5437🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5438-feat-Add-Turkish-language-support-2686d73d36508184bbf2dc1e0cd15350)
by [Unito](https://www.unito.io)
Implementing subgraph blueprints (#5139) included changes to saving to
ensure that SaveAs generates a new workflow of the correct type. However
this code failed to utilize the pre-prepared state when performing the
actual save. This produced a couple of problems with both failing to
detach the workflow and failing to apply the correct state
This error is only encountered when using Save As from a non temporary
workflow (one loaded from the workflows sidebar tab).
As this state calculation code is only used in this code path, it has
been moved into the saveAs function of the workflowStore.
Resolves#5592
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5643-Fix-SaveAs-2726d73d3650818faa7af449d1f13c26)
by [Unito](https://www.unito.io)
#5024 added support for connecting primitive nodes to subgraph inputs.
To accomplish this, it pulls WidgetLocator information from the node
owning the widget.
This `node` property does not exist on all IBaseWidget. `toConcrete` was
used to instead have a BaseWidget which is guaranteed to have a node
property. The issue that was missed, is that a widget which lacks this
information (such as most implemented by custom nodes) sets the node
value to the argument which was passed. Here that is the reference to
the subgraph node. Sometimes, this `#setWidget` call is made multiple
times, and when this occurs, the `input.widget` has itself set as the
protoyep, throwing an error.
This is resolved by instead taking an additional input which is
unambiguous.
For reference, this is a near minimal workflow using comfy_mtb that
replicates the issue
[cyclic.json](https://github.com/user-attachments/files/22412187/cyclic.json)
Special thanks to @melMass for assistance discovering this issue.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5637-Fix-cyclic-prototype-errors-with-subgraphNodes-2726d73d365081fea356f5197e4c2b42)
by [Unito](https://www.unito.io)
## Summary
Integrated Vue node components with canvas panning mode to prevent UI
interference during navigation.
## Changes
- **What**: Added
[canCapturePointerEvents](https://docs.comfy.org/guide/vue-nodes)
computed property to `useCanvasInteractions` composable that checks
canvas read-only state
- **What**: Modified Vue node components (LGraphNode, NodeWidgets) to
conditionally handle pointer events based on canvas navigation mode
- **What**: Updated node event handlers to respect panning mode and
forward events to canvas when appropriate
## Review Focus
Event forwarding logic in panning mode and pointer event capture state
management across Vue node hierarchy.
```mermaid
graph TD
A[User Interaction] --> B{Canvas in Panning Mode?}
B -->|Yes| C[Forward to Canvas]
B -->|No| D[Handle in Vue Component]
C --> E[Canvas Navigation]
D --> F[Node Selection/Widget Interaction]
G[canCapturePointerEvents] --> H{read_only === false}
H -->|Yes| I[Allow Vue Events]
H -->|No| J[Block Vue Events]
style A fill:#f9f9f9,stroke:#333,color:#000
style E fill:#f9f9f9,stroke:#333,color:#000
style F fill:#f9f9f9,stroke:#333,color:#000
style I fill:#e1f5fe,stroke:#01579b,color:#000
style J fill:#ffebee,stroke:#c62828,color:#000
```
## Screenshots
https://github.com/user-attachments/assets/00dc5e4a-2b56-43be-b92e-eaf511e52542
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5574-Make-Vue-nodes-read-only-when-in-panning-mode-26f6d73d3650818c951cd82c8fe58972)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
## Summary
Some users were authenticating successfully but their email addresses
weren't being extracted from the Firebase token. This happened because
we weren't explicitly requesting the email scope during OAuth
authentication.
While Firebase's default configuration includes basic profile info, it
doesn't guarantee email access for all account types - particularly
Google Workspace accounts with restrictive policies or users with
privacy-conscious settings.
[Github
Scopes](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)
## Changes
Adding email scope for Google + Github social OAuth.
## Review Focus
N/A
## Screenshots (if applicable)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5638-Explicitly-add-email-scope-for-social-auth-login-2726d73d3650817ab356fc9c04f8641b)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Alexander Brown <drjkl@comfy.org>
## Summary
Added comprehensive component test suite for WidgetImageCompare widget
with 410 test assertions covering display, edge cases, and integration
scenarios.
## Changes
- **What**: Created [Vue Test Utils](https://vue-test-utils.vuejs.org/)
test suite for [WidgetImageCompare
component](src/renderer/extensions/vueNodes/widgets/components/WidgetImageCompare.vue)
using [Vitest](https://vitest.dev/) testing framework
## Review Focus
Test coverage completeness for string vs object value handling,
accessibility attribute propagation, and edge case robustness including
malformed URLs and empty states.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5549-test-Add-component-test-for-image-compare-widget-26e6d73d365081189fe0d010f87d1eec)
by [Unito](https://www.unito.io)
---------
Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
## Summary
- Updated frontend to align with backend changes in ComfyUI core PR
#7555
- Changed manager startup argument from `--disable-manager` (opt-out) to
`--enable-manager` (opt-in)
- Manager is now disabled by default unless explicitly enabled
## Changes
- Modified `useManagerState.ts` to check for `--enable-manager` flag
presence
- Inverted logic: manager is disabled when the flag is NOT present
- Updated all related tests to reflect the new opt-in behavior
- Fixed edge case where `systemStats` is null
## Related
- Backend PR: https://github.com/comfyanonymous/ComfyUI/pull/7555
## Test Plan
- [x] All unit tests pass
- [x] Verified manager state logic with different flag combinations
- [x] TypeScript type checking passes
- [x] Linting passes
🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5635-refactor-Change-manager-flag-from-disable-manager-to-enable-manager-2726d73d36508153a88bd9f152132b2a)
by [Unito](https://www.unito.io)
This pull request improves the lazy loading behavior and caching
strategy for images in the `LazyImage.vue` component. The most
significant changes are focused on optimizing image rendering and
resource management, as well as improving code clarity.
**Lazy loading behavior improvements:**
* Changed the `<img>` element to render only when `cachedSrc` is
available, ensuring that images are not displayed before they are ready.
* Updated watchers in `LazyImage.vue` to use clearer variable names
(`shouldLoadVal` instead of `shouldLoad`) for better readability and
maintainability.
[[1]](diffhunk://#diff-3a1bfa7eb8cb26b04bea73f7b4b4e3c01e9d20a7eba6c3738fb47f96da1a7c95L80-R81)
[[2]](diffhunk://#diff-3a1bfa7eb8cb26b04bea73f7b4b4e3c01e9d20a7eba6c3738fb47f96da1a7c95L96-R96)
**Caching strategy enhancement:**
* Modified the `fetch` call in `mediaCacheService.ts` to use `{ cache:
'force-cache' }`, which leverages the browser's cache more aggressively
when loading media, potentially improving performance and reducing
network requests.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5626-LazyImage-on-Safari-2716d73d365081eeb1d3c2a96be4d408)
by [Unito](https://www.unito.io)
This pull request improves the selection toolbox behavior during node
dragging by ensuring that it correctly responds to both LiteGraph and
Vue node drag events. The main changes introduce a reactive drag state
for Vue nodes in the layout store and update the selection toolbox
composable and Vue node component to use this state.
**Selection toolbox behavior improvements:**
* Added a helper function and separate watchers in
`useSelectionToolboxPosition.ts` to hide the selection toolbox when
either LiteGraph or Vue nodes are being dragged. This ensures consistent
UI feedback regardless of node type.
[[1]](diffhunk://#diff-57a51ac5e656e64ae7fd276d71b115058631621755de33b1eb8e8a4731d48713L171-R172)
[[2]](diffhunk://#diff-57a51ac5e656e64ae7fd276d71b115058631621755de33b1eb8e8a4731d48713R212-R224)
**Vue node drag state management:**
* Added a reactive `isDraggingVueNodes` property to the
`LayoutStoreImpl` class, along with getter and setter methods to manage
Vue node drag state. This allows other components to reactively track
when Vue nodes are being dragged.
[[1]](diffhunk://#diff-80d32fe0fb72730c16cf7259adef8b20732ff214df240b1d39ae516737beaf3bR133-R135)
[[2]](diffhunk://#diff-80d32fe0fb72730c16cf7259adef8b20732ff214df240b1d39ae516737beaf3bR354-R367)
* Updated `LGraphNode.vue` to set and clear the Vue node dragging state
in the layout store during pointer down and up events, ensuring the
selection toolbox is hidden while dragging Vue nodes.
[[1]](diffhunk://#diff-a7744614cf842e54416047326db79ad81f7c7ab7bfb66ae2b46f5c73ac7d47f2R357-R360)
[[2]](diffhunk://#diff-a7744614cf842e54416047326db79ad81f7c7ab7bfb66ae2b46f5c73ac7d47f2R376-R378)
**Dependency updates:**
* Imported the `layoutStore` in `LGraphNode.vue` to access the new drag
state management methods.
* Added missing `ref` import in `layoutStore.ts` to support the new
reactive property.
https://github.com/user-attachments/assets/d6e9c15e-63b5-4de2-9688-ebbc6a3be545
---------
Co-authored-by: GitHub Action <action@github.com>
* new design for left click and wheel
* update snap
* fix import
* fix test
* default value
* fix test
* Update test expectations [skip ci]
---------
Co-authored-by: github-actions <github-actions@github.com>
* refactor: simplify preview state provider
- Remove unnecessary event listeners and manual syncing
- Use computed() to directly reference app.nodePreviewImages
- Eliminate data duplication and any types
- Rely on Vue's reactivity for automatic updates
- Follow established patterns from execution state provider
* feat: optimize Vue node preview image display with reactive store
- Move preview display logic from inline ternaries to computed properties
- Add useNodePreviewState composable for preview state management
- Implement reactive store approach using Pinia storeToRefs
- Use VueUse useTimeoutFn for modern timeout management instead of window.setTimeout
- Add v-memo optimization for preview image template rendering
- Maintain proper sync between app.nodePreviewImages and reactive store state
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: update props usage for Vue 3.5 destructured props syntax
* [refactor] improve code style and architecture based on review feedback
- Replace inject pattern with direct store access in useNodePreviewState
- Use optional chaining for more concise conditional checks
- Use modern Array.at(-1) for accessing last element
- Remove provide/inject for nodePreviewImages in favor of direct store refs
- Update preview image styling: remove rounded borders, use flexible height
- Simplify scheduleRevoke function with optional chaining
Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
* [cleanup] remove unused NodePreviewImagesKey injection key
Addresses knip unused export warning after switching from provide/inject
to direct store access pattern.
* [test] add mock for useNodePreviewState in LGraphNode test
Fixes test failure after adding preview functionality to LGraphNode component.
* [fix] update workflowStore import path after rebase
Updates import to new location: @/platform/workflow/management/stores/workflowStore
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
* add markdown widget test
* [fix] correct test comments from 'is exposed' to 'is not exposed' - addresses review feedback
The TypeScript suppression comments incorrectly stated that properties
were exposed when they should indicate they are not exposed, since
@ts-expect-error is used to access private properties.
Co-authored-by: christian-byrne <christian-byrne@users.noreply.github.com>
---------
Co-authored-by: christian-byrne <christian-byrne@users.noreply.github.com>
* Add ABC ROM fonts from Comfy.org
* Import ABC ROM fonts CSS in main.ts
* Move font import to style.css
* Add ABC ROM fonts as CSS variables in @theme
* Add Inter font .woff2 files
* Replace ABC ROM with Inter font declarations
* Update CSS variables to use Inter font
* Remove unused ABC ROM font files
* Autoformat style.css
* Remove redundant font declarations
* Add copyTerminal translation key
* Add copy terminal button with select all functionality
* Remove copy button from error view button group
* Add hover-based copy button overlay to terminal
* Fix clipboard copy implementation in BaseTerminal
* Add 'Copy all' tooltip to terminal copy button
* Fix copy button to be away from right hand side
* Update copy button to respect existing selection
- Copy only selected text if any exists
- Copy all text and clear selection if nothing selected
- Update tooltip to reflect new behavior
* Add dynamic tooltip showing actual copy action
- Show 'Copy selection' when text is selected
- Show 'Copy all' when no text is selected
* Remove redundant i18n
* Fix aria-label to use dynamic tooltip text
* Remove debug console.error statements from useTerminal
Clean up debug logging added during development:
- Remove selection change debug logging
- Remove focus state debug logging
- Remove keyboard event debug logging
- Remove copy/paste debug logging
* Remove redundant keyboard handling from useTerminal
The rebase commit already fixed basic copy/paste.
Removed only the complex keyboard event handling that
duplicates the rebase fix. Kept the valuable UI features:
- Hover copy button overlay
- Right-click context menu
* Use Tailwind transition classes instead of custom CSS
Replace custom .animate-fade-in with standard Tailwind
transition-opacity duration-200 classes
* Use VueUse useElementHover for robust hover handling
Replace manual mouseenter/mouseleave events with VueUse
useElementHover composable which properly handles all
edge cases including mouseout and interrupted events
* Move tooltip to left of button
Relieves squished tooltip
* Simplify code
* Fix listener lifecycle management
Consolidate setup into single onMounted block instead
of creating unnecessary duplicate lifecycle hooks
* Replace any type with proper IDisposable type
* Refactor copy logic for clarity
* Use v-show for proper opacity transitions
* Prefer optional chaining
* Use useEventListener for context menu
* Remove redundant opacity classes
* Add BaseTerminal component tests
* Use pointer-events for button interactivity
* Update tests for pointer-events button behavior
* Fix clipboard mock in tests
* Fix test expectations for opacity classes
* Simplify hover tests for button state
* Remove low-value 'renders terminal container' test
* Remove non-functional 'button responds to hover' test
* Remove implementation detail test for dispose listener
* Remove redundant 'tracks selection changes' test
* Remove obvious comments from test file
* Use cn() utility for conditional classes
* Update tests-ui/tests/components/bottomPanel/tabs/terminal/BaseTerminal.spec.ts
Co-authored-by: Alexander Brown <drjkl@comfy.org>
* [auto-fix] Apply ESLint and Prettier fixes
* Remove 'any' types from wrapper and terminalMock variables
Add assertion to verify onSelectionChange was called
* Move mountBaseTerminal factory to module scope
* Rename test file
- Current consensus is .test.ts for component files
* Update src/components/bottomPanel/tabs/terminal/BaseTerminal.vue
* nit
---------
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
* Fix context menu creating nodes in wrong position
When nodes are created from the context menu, they previously had there
position set immediately after the node itself was created. Under some
circumstances, this new position would be overwritten by the layout
store.
This is solved by setting the position before node initialization.
* nit: Move size fix to named variable
Also remove ternary. The elements are always numberic, so checking if a
number is truthy before multiplying by 0 is a little silly.
* nit: Further variable extraction
* [refactor] create src/platform/assets
Per @christian-byrne's feedback. Just bringing this into the repo sooner to clean up from my feature branch
* [fix] code review feedback
* [refactor] Move update-related functionality to platform/updates domain
Reorganizes release management, version compatibility, and notification functionality
following Domain-Driven Design principles, mirroring VSCode's architecture pattern.
- Move releaseService.ts to platform/updates/common/
- Move releaseStore.ts to platform/updates/common/
- Move versionCompatibilityStore.ts to platform/updates/common/
- Move useFrontendVersionMismatchWarning.ts to platform/updates/common/
- Move toastStore.ts to platform/updates/common/
- Move ReleaseNotificationToast.vue to platform/updates/components/
- Move WhatsNewPopup.vue to platform/updates/components/
- Update 25+ import paths across codebase and tests
This creates a cohesive "updates" domain containing all functionality related to
software updates, version checking, release notifications, and user communication
about application state changes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix imports
---------
Co-authored-by: Claude <noreply@anthropic.com>
* refactor: move settingStore to platform/settings
Move src/stores/settingStore.ts to src/platform/settings/settingStore.ts
to separate platform infrastructure from domain logic following DDD principles.
Updates all import references across ~70 files to maintain compatibility.
* fix: update remaining settingStore imports after rebase
* fix: complete remaining settingStore import updates
* fix: update vi.mock paths for settingStore in tests
Update all test files to mock the new settingStore location at
@/platform/settings/settingStore instead of @/stores/settingStore
* fix: resolve remaining settingStore imports and unused imports after rebase
* fix: update settingStore mock path in SelectionToolbox test
Fix vi.mock path from @/stores/settingStore to @/platform/settings/settingStore
to resolve failing Load3D viewer button test.
* refactor: complete comprehensive settings migration to platform layer
This commit completes the migration of all settings-related code to the platform layer
as part of the Domain-Driven Design (DDD) architecture refactoring.
- constants/coreSettings.ts → platform/settings/constants/coreSettings.ts
- types/settingTypes.ts → platform/settings/types.ts
- stores/settingStore.ts → platform/settings/settingStore.ts (already moved)
- composables/setting/useSettingUI.ts → platform/settings/composables/useSettingUI.ts
- composables/setting/useSettingSearch.ts → platform/settings/composables/useSettingSearch.ts
- composables/useLitegraphSettings.ts → platform/settings/composables/useLitegraphSettings.ts
- components/dialog/content/SettingDialogContent.vue → platform/settings/components/SettingDialogContent.vue
- components/dialog/content/setting/SettingItem.vue → platform/settings/components/SettingItem.vue
- components/dialog/content/setting/SettingGroup.vue → platform/settings/components/SettingGroup.vue
- components/dialog/content/setting/SettingsPanel.vue → platform/settings/components/SettingsPanel.vue
- components/dialog/content/setting/ColorPaletteMessage.vue → platform/settings/components/ColorPaletteMessage.vue
- components/dialog/content/setting/ExtensionPanel.vue → platform/settings/components/ExtensionPanel.vue
- components/dialog/content/setting/ServerConfigPanel.vue → platform/settings/components/ServerConfigPanel.vue
- ~100+ import statements updated across the codebase
- Test file imports corrected
- Component imports fixed in dialog service and command menubar
- Composable imports updated in GraphCanvas.vue
```
src/platform/settings/
├── components/ # All settings UI components
├── composables/ # Settings-related composables
├── constants/ # Core settings definitions
├── types.ts # Settings type definitions
└── settingStore.ts # Central settings state management
```
✅ TypeScript compilation successful
✅ All tests passing (settings store, search functionality, UI components)
✅ Production build successful
✅ Domain boundaries properly established
This migration consolidates all settings functionality into a cohesive platform domain,
improving maintainability and following DDD principles for better code organization.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format and lint after rebase conflict resolution
* fix: update remaining import paths to platform settings
- Fix browser test import: extensionAPI.spec.ts
- Fix script import: collect-i18n-general.ts
- Complete settings migration import path updates
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Move thumbnail functionality from src/renderer/thumbnail/ to src/renderer/core/thumbnail/
to align with domain-driven design architecture. Thumbnail generation is core rendering
infrastructure and belongs alongside other core renderer utilities.
Changes:
- Move useWorkflowThumbnail.ts and graphThumbnailRenderer.ts to renderer/core/thumbnail/
- Update all import paths in consuming files
- Fix relative imports within moved files
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
* [refactor] move workflow domain to its own folder
* [refactor] Fix workflow platform architecture organization
- Move workflow rendering functionality to renderer/thumbnail domain
- Rename ui folder to management for better semantic clarity
- Update all import paths to reflect proper domain boundaries
- Fix test imports to use new structure
Architecture improvements:
- rendering → renderer/thumbnail (belongs with other rendering logic)
- ui → management (better name for state management and UI integration)
This ensures proper separation of concerns and domain boundaries.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [fix] Resolve circular dependency between nodeDefStore and subgraphStore
* [fix] Update browser test imports to use new workflow platform paths
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add text context menu to terminal on right-click
Enable single right-click context menu in BaseTerminal for desktop app users. Previously required two right clicks.
* Use useEventListener for context menu
* Fix overzealous tab-complete
* nit
* [refactor] Improve renderer architecture organization
Building on PR #5388, this refines the renderer domain structure:
**Key improvements:**
- Group all transform utilities in `transform/` subdirectory for better cohesion
- Move canvas state to dedicated `renderer/core/canvas/` domain
- Consolidate coordinate system logic (TransformPane, useTransformState, sync utilities)
**File organization:**
- `renderer/core/canvas/canvasStore.ts` (was `stores/graphStore.ts`)
- `renderer/core/layout/transform/` contains all coordinate system utilities
- Transform sync utilities co-located with core transform logic
This creates clearer domain boundaries and groups related functionality
while building on the foundation established in PR #5388.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: Clean up linter-modified files
* Fix import paths and clean up unused imports after rebase
- Update all remaining @/stores/graphStore references to @/renderer/core/canvas/canvasStore
- Remove unused imports from selection toolbox components
- All tests pass, only reka-ui upstream issue remains in typecheck
🤖 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>
* fix: Vue nodes now respect deserialized width from LiteGraph
* fix: Set Vue node initial size in layout store instead of CSS
Vue nodes now properly set their initial size in the layout store using
the resize() function from useNodeLayout on component mount. This ensures
the layout store is the single source of truth for sizing, preventing
conflicts with the ResizeObserver that was overriding CSS-based sizing.
This resolves the issue where Vue nodes would shrink to minimal size
after user interaction due to ResizeObserver feedback loops.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: Remove duplicate onMounted call in LGraphNode.vue
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Fix light_theme changes default node background
This is an issue where the background of nodes which have no background set were being lightened by this switch, when they should be skipped.
Went unnoticed because the only theme using this was the built-in light theme, which used white for node backgrounds anyway.
* Fix bypassed nodes
* nit
* Revert "nit"
This reverts commit e22f03a0e9.
* Revert "Fix bypassed nodes"
This reverts commit 6121634c09.
* Revert "Fix light_theme changes default node background"
This reverts commit 3206973e5a.
* Fix opacity not rendered to default nodes
Also causes bypassed nodes in light mode to once again render in light pink (again).
Not sure when this regression occurred.
* Revert "Fix opacity not rendered to default nodes"
This reverts commit da65a1dbaf.
* Fix backgrounds not adjusting for light mode
* add missing node error border
* update vue node data after configure
* provide locatorId of execution error node to vue nodes
* [refactor] use execution store directly instead of provide/inject pattern
- Add lastExecutionErrorNodeId computed property to execution store
- Replace inject() with useExecutionStore() in LGraphNode component
- Remove useExecutionErrorProvider composable and provider call
- Clean up unused ExecutionErrorNodeIdKey injection key
- Add explicit return type annotation to hasAnyError computed
Addresses @DrJKL's architecture feedback and type safety suggestions.
* simplify error styling to match main branch conventions
Remove redundant dark-theme prefixes from border-error and outline-error
classes since these CSS custom properties handle both themes automatically.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* address review feedback on hasAnyError computed function
- Add explicit boolean return type
- Destructure props with defaults for cleaner code
- Use \!\! for proper boolean conversion to satisfy TypeScript
Addresses @DrJKL review comment on error state computation.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* destructure props at top level as suggested in review
Replace `props.nodeData` and `props.error` references with destructured
variables for cleaner code and proper defaults.
Addresses @DrJKL review comment about props destructuring.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix rebase issues: correct node ID comparison and border colors
- Use lastExecutionErrorNodeId instead of lastExecutionErrorNodeLocatorId
for proper comparison with nodeData.id (both are local node IDs)
- Restore border-blue-100 colors that were incorrectly changed during rebase
- These were unrelated changes that snuck in during conflict resolution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* remove unused lastExecutionErrorNodeLocatorId from exports
The computed property is defined but not used by any external modules.
Only lastExecutionErrorNodeId is actually consumed by components.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Replace duplicated download implementation in saveImage function with
the existing downloadFile utility from downloadUtil. This removes 18
lines of duplicate code while maintaining identical functionality.
Changes:
- Import downloadFile from @/base/common/downloadUtil
- Replace manual anchor element creation with downloadFile call
- Maintain same URL preprocessing (removing preview parameter)
- Keep existing error handling
The downloadFile utility already includes comprehensive test coverage
and handles filename extraction, DOM manipulation, and cleanup.
* fix gallery widget navigators binding
* [refactor] improve test structure and type organization - addresses @DrJKL's review feedback
- Move types comment to reference component file (types already exist there)
- Extract helper functions outside describe blocks as pure functions
- Convert to function declarations for better clarity
- Fix 0-indexed vs 1-indexed consistency in test data generation
- Add placeholder for future test constants organization
* [test] Add WidgetTextarea component test with improved structure - addresses @DrJKL's review feedback
- Move helper functions outside describe blocks as pure function declarations
- Fix options type in createMockWidget to use SimplifiedWidget['options'] instead of Partial<TextareaProps>
- Replace emitted\![0] with safer emitted?.[0] optional chaining pattern
- Add comprehensive test coverage for textarea value binding, events, readonly mode, and edge cases
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update src/renderer/extensions/vueNodes/widgets/components/WidgetGalleria.vue
Co-authored-by: Alexander Brown <drjkl@comfy.org>
* [refactor] export types from component and use 0-indexed numbering - addresses @DrJKL's review feedback
- Export GalleryImage and GalleryValue types from WidgetGalleria.vue component
- Import types in test file instead of redefining them locally
- Change image alt text from 1-indexed to 0-indexed (Image 0, Image 1, etc.)
- Move helper functions outside describe blocks using function declarations
- Add readonly test data constants for better test isolation
- Fix type compatibility issues with readonly arrays
This addresses DrJKL's review comments about:
1. Types being defined in test suite instead of component
2. Helper functions placement and clarity
3. 1-indexed numbering preference
4. Better test organization with readonly constants
* [refactor] implement remaining review feedback - addresses accessibility and factory pattern suggestions
- Fix accessibility: Add descriptive alt text with position context for screen readers
instead of repetitive "Gallery image" (e.g., "Gallery image 2 of 5")
- Implement factory pattern: Add createGalleriaWrapper() function that takes images,
creates widget internally, and returns wrapper for cleaner test code
- Update tests to use factory pattern for readonly constant test cases
- Add proper i18n translations for galleryImage and galleryThumbnail
- Use more descriptive alt text following WebAIM accessibility guidelines
Addresses review comments about screen reader accessibility and test factory pattern
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
* add component test for select button
* [refactor] improve test structure and typing - addresses @DrJKL review comments
- Use proper SimplifiedWidget['options'] type instead of loose object type
- Extract helper functions as module-level function declarations for better organization
- Remove type assertion violation by using proper union type for null/undefined values
- Format code with prettier to maintain consistency
* [refactor] use safer optional chaining in test assertions - addresses @DrJKL's safety preference
Replace emitted\![0] with emitted?.[0] for safer array access in test expectations.
This follows the same pattern as applied to the textarea widget tests for consistency.
* fix file upload widget disabled prop
* [test] extract createMockWidget to shared test utility - addresses @DrJKL's code replication concern
Creates testUtils.ts with shared createMockWidget and createMockFile functions
to reduce duplication across widget component tests. This ensures consistency
and maintainability of test setup code.
* [test] replace type assertions with type narrowing - addresses @DrJKL's type safety suggestion
Replaces unsafe `as HTMLInputElement` casts with proper instanceof checks
and error throwing. Also refactors File Type Detection tests to use it.for
instead of conditionals to eliminate anti-pattern.
* [feat] use destructuring with default value for readonly prop - addresses @DrJKL's Vue best practice suggestion
Replace manual fallback expressions like `readonly || false` with modern Vue 3
destructuring pattern: `const { readonly = false } = defineProps()`.
This is cleaner than withDefaults() and follows current Vue best practices.
* [test] improve test utilities usage - addresses @DrJKL's additional suggestions
- Replace findComponent with getComponent for better error handling
- Use optional chaining (?.()) instead of conditional checks for cleaner syntax
- Remove unnecessary existence checks since getComponent throws on failure
* track execution progress in vue nodes
* add test
* remove pointless execution state test
The test was mocking everything including the provide/inject mechanism,
so it wasn't testing real behavior. The execution progress feature
works correctly as verified through manual testing.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* remove accidentally committed PR_TEMPLATE.md
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [refactor] address PR review feedback from @DrJKL
- Replace hardcoded #0B8CE9 color with blue-100 class for consistency
- Replace magic number 56px with top-14 class for progress bar positioning
- Use storeToRefs() for better Pinia reactivity
- Reduce heavy commenting per maintainer preference
* fix: update LGraphNode test to mock useNodeExecutionState properly
The test was failing because it passed executing as a prop, but the component
uses the useNodeExecutionState composable. Added proper mock for the composable
to test the animate-pulse class application during execution.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>