Skip to content

Conversation

@LittleSound
Copy link
Collaborator

@LittleSound LittleSound commented Dec 31, 2025

Most of the features in this pull request are completed and can be reviewed and merged.

TODO

  • no selection panel
  • group selected panel
  • tabs
    • favorites tab
    • global settings tab
    • nodes tab
  • widget actions menu
    • [Bug]: style bugs
  • button zoom to the node on canvas.
  • rename widgets on widget actions
    • [Bug]: the canvas has not been updated after renaming.
  • global settings
    • setting item: "show advanced parameters"
      • blocked by other things. skip for now.
    • setting item: show toolbox on selection
    • setting item: nodes 2.0
    • setting item: "background color"
      • blocked by other things. skip for now.
    • setting item: grid spacing
    • setting item: snap nodes to grid
    • setting item: link shape
    • setting item: show connected links
    • form style reuses the form style of node widgets
  • group node cases
    • group node settings
    • show all nodes in group
    • show frame name on nodes when multiple selections are made
    • group multiple selections
    • [Bug]: nodes without widgets cannot display the location and their group
    • [Bug]: labels layout
  • favorites
    • the indicator on widgets
    • favorite and unfavorite buttons on widgets
    • [Bug]: show node name in favorite widgets + improve labels layout
    • [Bug]: After canceling the like, the like list will not be updated immediately.
    • [Bug]: The favorite function does not work for the project on Subgraph.
  • subgraph
    • add the node name from where this parameter comes from when node is subgraph
    • show and hide directly on Inputs
      • some bugs need to be fixed.
  • advanced widgets
    • button: show advanced inputs
      • Clicking button expands the "Advanced Inputs" section on the right side panel, regardless of whether the panel is open or not
      • [Bug]: style bugs
    • advanced inputs section when node is subgraph
  • inputs tab rearranging
    • favorited inputs rearranging
    • subgraph inputs rearranging
  • review and reconstruction to improve complexity and architecture

┆Issue is synchronized with this Notion page by Unito

@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Dec 31, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

📝 Walkthrough

Walkthrough

Refactors the right-side panel to use a flattened mixed-selection model, adds favorited-widget management (store + UI with drag-reorder), splits/extends parameter tabs (nodes, global, normal/subgraph), introduces widget item/actions and shared utilities, plus multiple new settings/layout components, tests, and localization entries.

Changes

Cohort / File(s) Summary
Right-Side Panel Core
src/components/rightSidePanel/RightSidePanel.vue
Rewrote selection handling to use flatAndCategorizeSelectedItems, added flat refs (flattedItems, selectedNodes, selectedGroups, nodeToParentGroup), rootLevelNodes, allowTitleEdit, dynamic tab generation including 'nodes', updated title editing and header/content rendering.
Tab Components – New/Changed
src/components/rightSidePanel/parameters/TabGlobalParameters.vue, src/components/rightSidePanel/parameters/TabNodes.vue, src/components/rightSidePanel/parameters/TabNormalInputs.vue, src/components/rightSidePanel/parameters/TabSubgraphInputs.vue, src/components/rightSidePanel/settings/TabGlobalSettings.vue
Added global favorites tab with drag-reorder, node-centric tab, normal inputs tab, subgraph inputs tab (proxy & advanced inputs), and global settings tab; each includes search and draggable behaviors as appropriate.
Widget Management – Actions & Items
src/components/rightSidePanel/parameters/WidgetActions.vue, src/components/rightSidePanel/parameters/WidgetItem.vue
New per-widget action menu and widget item component: rename, favorite/unfavorite, hide/show on subgraph, editable labels, proxy/source handling, favorite indicator, event emissions.
Section & Widget UI
src/components/rightSidePanel/parameters/SectionWidgets.vue, src/components/rightSidePanel/parameters/WidgetItem.vue
Expanded SectionWidgets props (node, parents, locate button, defaultCollapse, empty-state, tooltips), exposes widgetsContainer, renders WidgetItem list inside TransitionGroup, shows parent-group titles and locate/pan action.
Settings Components
src/components/rightSidePanel/settings/NodeSettings.vue, src/components/rightSidePanel/settings/SetNodeColor.vue, src/components/rightSidePanel/settings/SetNodeState.vue, src/components/rightSidePanel/settings/SetPinned.vue, src/components/rightSidePanel/settings/TabSettings.vue
Added NodeSettings and controls: multi-node color picker, execution mode select, pin toggle; TabSettings refactored to use NodeSettings and derive nodes/groups.
Layout & UI Components
src/components/rightSidePanel/layout/PropertiesAccordionItem.vue, src/components/rightSidePanel/layout/TransitionCollapse.vue, src/components/button/MoreButton.vue
PropertiesAccordionItem: defaultCollapse, empty-state slot, tooltip/chevron changes and style update; TransitionCollapse: JS-driven enter/leave animations; MoreButton: new buttonClass prop.
Shared Utilities & Tests
src/components/rightSidePanel/shared.ts, src/components/rightSidePanel/shared.test.ts
Added GetNodeParentGroupKey InjectionKey, searchWidgets/searchWidgetsAndNodes, MixedSelectionItem type, flatAndCategorizeSelectedItems with parent mapping, and renameWidget (proxy-aware); unit tests for search and flatten behavior.
Stores
src/stores/workspace/rightSidePanelStore.ts, src/stores/workspace/favoritedWidgetsStore.ts
rightSidePanelStore: added 'nodes' tab, focusedSection, focusSection/clearFocusedSection, and searchQuery; favoritedWidgetsStore: per-workflow persisted favorites with add/remove/toggle/reorder and runtime resolution.
Graph & Widget Utilities
src/composables/graph/useGraphNodeManager.ts, src/core/graph/subgraph/proxyWidgetUtils.ts, src/core/graph/subgraph/proxyWidget.test.ts
Exported getSharedWidgetEnhancements and SharedWidgetEnhancements type; updated promoteWidget to avoid duplicate proxy entries; added idempotent promotion test.
Form & Search Components
src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue, .../FormDropdownMenuActions.vue, FormDropdown.vue, FormDropdownMenu.vue
FormSearchInput: autofocus and class props, clear button, debounce tweaks; dropdown/menu components now accept searcher callback and removed isQuerying flag.
Subgraph & Node UI
src/components/rightSidePanel/subgraph/SubgraphEditor.vue, src/renderer/extensions/vueNodes/components/LGraphNode.vue
SubgraphEditor: wired searchQuery to rightSidePanelStore; LGraphNode: adds "Show Advanced Inputs" button that focuses the panel's advanced-inputs section for SubgraphNode.
Localization & Configuration
src/locales/en/main.json, src/platform/settings/constants/coreSettings.ts, src/schemas/apiSchema.ts
Added numerous right-side panel i18n keys (favorites, global settings, fallback titles, none-state descriptions); registered Comfy.RightSidePanel.IsOpen in core settings and API schema.
Services & Integration
src/services/litegraphService.ts, src/assets/css/style.css
litegraphService: context menu adds Favorite/Unfavorite widget action using favoritedWidgetsStore; style.css: list-scale transition rules for animated lists.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RightSidePanel
    participant Shared as shared.ts
    participant TabRouter
    participant TabComponent
    participant SearchUtil as searchWidgetsAndNodes

    User->>RightSidePanel: select nodes/groups
    RightSidePanel->>Shared: flatAndCategorizeSelectedItems(selection)
    Shared-->>RightSidePanel: { all, nodes, groups, nodeToParentGroup }
    RightSidePanel->>TabRouter: choose active tab (parameters/nodes/...)
    TabRouter->>TabComponent: pass nodes/selection context
    User->>TabComponent: enter search query
    TabComponent->>SearchUtil: searchWidgetsAndNodes(items, query)
    SearchUtil-->>TabComponent: filtered results
    TabComponent->>TabComponent: render filtered sections/widgets
Loading
sequenceDiagram
    participant User
    participant WidgetActions
    participant FavStore as favoritedWidgetsStore
    participant Workflow

    User->>WidgetActions: click favorite/unfavorite
    WidgetActions->>FavStore: toggleFavorite(node, widgetName)
    FavStore->>FavStore: update favoritedIds & resolve labels
    FavStore->>Workflow: saveToWorkflow(workflow.extra.favoritedWidgets)
    Workflow-->>FavStore: persist success
    WidgetActions->>WidgetItem: emit widgetUpdate (favorite/unfavorite)
Loading

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 924d956 and f7be62a.

📒 Files selected for processing (3)
  • src/locales/en/main.json
  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Leverage VueUse functions for performance-enhancing utilities

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Use separate import type statements; do not mix inline type imports in the same statement
Sort and group imports by plugin; run pnpm format before committing
Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Code should be well-designed with clear names for everything; write code that is expressive and self-documenting
Avoid redundant comments and clean up code as you go; comments should explain why, not what
Ask if there is a simpler way to implement functionality; refactor complex code to simplify it
Minimize nesting depth (e.g., if () { ... } or for () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never use any type; use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Indent with 2 spaces; use single quotes; no trailing semicolons; max line width 80 (per .prettierrc)
Complex type definitions used in multiple related places should be extracted and named for reuse
Implement proper error handling

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional; use function declarations instead of function expressions when possible
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
🧠 Learnings (7)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/locales/en/main.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (5)
src/schemas/apiSchema.ts (1)

555-556: LGTM! Clean schema addition for right side panel state.

The new boolean property follows the existing naming convention and correctly uses Zod v3-compatible syntax. The property ID matches the corresponding core setting in coreSettings.ts.

src/platform/settings/constants/coreSettings.ts (1)

1143-1149: LGTM! Well-formed core setting for panel state.

The setting definition correctly uses type 'hidden' for internal UI state that shouldn't appear in the user-facing settings dialog. The ID matches the corresponding schema property in apiSchema.ts, and the default value of false is appropriate.

src/locales/en/main.json (3)

438-439: LGTM! Context menu entries for widget favoriting.

The new context menu keys follow the existing PascalCase naming convention and are appropriately placed next to the existing widget action entries.


2486-2486: LGTM! Correct pluralization pattern for item selection.

The updated title key correctly uses vue-i18n's pipe-separated pluralization format (zero | one | many) with the {count} interpolation parameter. The change from "node(s)" to "item(s)" appropriately reflects the broader scope of the mixed-selection model mentioned in the PR objectives.


2488-2534: LGTM! Comprehensive and well-organized locale keys for right side panel.

The new locale entries are well-structured with:

  • Consistent camelCase naming throughout
  • Proper nesting for the globalSettings object (lines 2511-2527)
  • Clear descriptive keys for empty states (favoritesNoneDesc, noneSearchDesc, nodesNoneDesc)
  • Intuitive action verbs (addFavorite, removeFavorite, hideInput, showInput, locateNode)
  • Fallback titles for dynamic UI elements

The organization aligns well with the right-side panel enhancements described in the PR objectives.

Based on learnings, only English locale entries need to be added; other languages are auto-generated on release.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 28

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14528aa and 4f95f0d.

📒 Files selected for processing (18)
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/locales/en/main.json
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
🧰 Additional context used
📓 Path-based instructions (17)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/locales/en/main.json
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
src/**/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not use barrel files (e.g., /some/package/index.ts) to re-export within /src

Files:

  • src/components/rightSidePanel/layout/index.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
**/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores using the pattern *Store.ts

Files:

  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
🧠 Learnings (47)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/index.ts
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/rightSidePanel/layout/index.ts
  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/settings/GroupSettings.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/settings/NodeSettings.vue
  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use Tailwind CSS for styling

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/parameters/TabParameters.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/components/rightSidePanel/settings/TabGlobalSettings.vue
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*Store.ts : Name Pinia stores using the pattern `*Store.ts`

Applied to files:

  • src/stores/workspace/favoritedWidgetsStore.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use vue 3.5 style of default prop declaration

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement proper props and emits definitions

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Destructure props using Vue 3.5 style in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use defineExpose only for imperative operations (such as form.validate(), modal.open())

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-11T03:55:51.755Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:51.755Z
Learning: In Vue components under src/renderer/extensions/vueNodes (e.g., ImagePreview.vue and LGraphNode.vue), implement image gallery keyboard navigation so that it responds to the node's focus state rather than requiring focus inside the image preview wrapper. Achieve this by wiring keyEvent handling at the node focus level and injecting or propagating key events (arrow keys) to the gallery when the node is focused/selected. This improves accessibility and aligns navigation with node-level focus behavior.

Applied to files:

  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : When writing tests for subgraph-related code, always import from the barrel export at `@/lib/litegraph/src/litegraph` to avoid circular dependency issues

Applied to files:

  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : The `size` and `pos` properties of `Rectangle` share the same array buffer (`subarray`); they may be used to set the rectangle's size and position

Applied to files:

  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
🧬 Code graph analysis (2)
src/components/rightSidePanel/layout/index.ts (1)
src/lib/litegraph/src/types/widgets.ts (1)
  • IBaseWidget (271-429)
src/stores/workspace/favoritedWidgetsStore.ts (3)
src/lib/litegraph/src/types/widgets.ts (1)
  • IBaseWidget (271-429)
src/platform/workflow/management/stores/workflowStore.ts (1)
  • useWorkflowStore (209-840)
src/scripts/app.ts (1)
  • app (1765-1765)

Comment on lines 8 to 29
export function searchWidgets<T extends { widget: IBaseWidget }[]>(
list: T,
query: string
): T {
if (query.trim() === '') {
return list
}
const words = query.trim().toLowerCase().split(' ')
return list.filter(({ widget }) => {
const label = widget.label?.toLowerCase()
const name = widget.name.toLowerCase()
const type = widget.type.toLowerCase()
const value = widget.value?.toString().toLowerCase()
return words.every(
(word) =>
name.includes(word) ||
label?.includes(word) ||
type?.includes(word) ||
value?.includes(word)
)
}) as T
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Unsafe type assertion loses type safety.

The as T cast on line 28 is incorrect. The filter() method always returns T[number][] (the element type in an array), not the original tuple or specialized array type T. If T is a tuple type or has additional type constraints beyond { widget: IBaseWidget }[], this assertion will silently break type safety.

🔎 Proposed fix: Simplify the generic constraint
-export function searchWidgets<T extends { widget: IBaseWidget }[]>(
-  list: T,
-  query: string
-): T {
+export function searchWidgets<T extends { widget: IBaseWidget }>(
+  list: T[],
+  query: string
+): T[] {
   if (query.trim() === '') {
     return list
   }
   const words = query.trim().toLowerCase().split(' ')
   return list.filter(({ widget }) => {
     const label = widget.label?.toLowerCase()
     const name = widget.name.toLowerCase()
     const type = widget.type.toLowerCase()
     const value = widget.value?.toString().toLowerCase()
     return words.every(
       (word) =>
         name.includes(word) ||
         label?.includes(word) ||
         type?.includes(word) ||
         value?.includes(word)
     )
-  }) as T
+  })
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function searchWidgets<T extends { widget: IBaseWidget }[]>(
list: T,
query: string
): T {
if (query.trim() === '') {
return list
}
const words = query.trim().toLowerCase().split(' ')
return list.filter(({ widget }) => {
const label = widget.label?.toLowerCase()
const name = widget.name.toLowerCase()
const type = widget.type.toLowerCase()
const value = widget.value?.toString().toLowerCase()
return words.every(
(word) =>
name.includes(word) ||
label?.includes(word) ||
type?.includes(word) ||
value?.includes(word)
)
}) as T
}
export function searchWidgets<T extends { widget: IBaseWidget }>(
list: T[],
query: string
): T[] {
if (query.trim() === '') {
return list
}
const words = query.trim().toLowerCase().split(' ')
return list.filter(({ widget }) => {
const label = widget.label?.toLowerCase()
const name = widget.name.toLowerCase()
const type = widget.type.toLowerCase()
const value = widget.value?.toString().toLowerCase()
return words.every(
(word) =>
name.includes(word) ||
label?.includes(word) ||
type?.includes(word) ||
value?.includes(word)
)
})
}
🤖 Prompt for AI Agents
In src/components/rightSidePanel/layout/index.ts around lines 8 to 29, the
function uses an unsafe "as T" cast on the filtered result which loses type
safety; change the generic to represent the element type rather than the array
type (e.g. use a generic U extends { widget: IBaseWidget } and accept list:
U[]), have the function return U[] and let TypeScript infer the filter result as
U[] (remove the "as T" cast), and update the function signature and any call
sites accordingly so the return type correctly matches the element type of the
input array.

Comment on lines 31 to 36
const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>([])
async function searcher(query: string) {
searchQuery.value = query
searchedFavoritedWidgets.value = searchWidgets(favoritedWidgets.value, query)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

searchedFavoritedWidgets is never initialized, may cause empty initial render.

Similar to TabNodes.vue, this shallowRef starts empty and is only populated when searcher() is called. Consider initializing it with the full favorites list.

🔎 Proposed fix
-const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>([])
+const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>(
+  favoritedWidgets.value
+)

-async function searcher(query: string) {
+function searcher(query: string) {
   searchQuery.value = query
   searchedFavoritedWidgets.value = searchWidgets(favoritedWidgets.value, query)
 }

Also add a watcher to update when favorites change:

watch(favoritedWidgets, (newVal) => {
  if (!searchQuery.value) {
    searchedFavoritedWidgets.value = newVal
  }
}, { immediate: true })

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/rightSidePanel/parameters/TabGlobalParameters.vue around lines
31 to 36, searchedFavoritedWidgets is initialized empty which leads to an empty
initial render; initialize it to the full favorites list and add a watcher so it
updates when favorites change: set searchedFavoritedWidgets.value =
favoritedWidgets.value initially (or via shallowRef(favoritedWidgets.value)) and
add a watcher on favoritedWidgets that, when searchQuery is empty, replaces
searchedFavoritedWidgets with the new favorites (and when searchQuery is
non-empty re-run the searcher or call searchWidgets to keep filtered results
accurate); ensure the watcher uses immediate: true.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/rightSidePanel/parameters/TabNodes.vue (1)

51-51: Add update-key prop to reset search when nodes change.

SidePanelSearch watches both the search query and updateKey prop. Without the update key, changing the nodes prop while a search is active won't refresh results because the search query hasn't changed.

-    <SidePanelSearch :searcher :update-key="widgetsSectionDataList" />
+    <SidePanelSearch :searcher :update-key="nodes" />

This ensures the search resets when the nodes prop changes, matching the pattern used elsewhere.

♻️ Duplicate comments (5)
src/components/rightSidePanel/parameters/TabNodes.vue (2)

34-46: Initialize search results to prevent empty initial render.

searchedWidgetsSectionDataList starts as an empty array and is only populated when searcher() is called, causing nothing to render on mount. Additionally, the async keyword is unnecessary since no await is used.

🔎 Proposed fix
-const searchedWidgetsSectionDataList = shallowRef<NodeWidgetsListList>([])
+const searchedWidgetsSectionDataList = shallowRef<NodeWidgetsListList>(
+  widgetsSectionDataList.value
+)

-async function searcher(query: string) {
+function searcher(query: string) {
   const list = widgetsSectionDataList.value
   const target = searchedWidgetsSectionDataList
   if (query.trim() === '') {
     target.value = list
     return
   }
   target.value = list
     .map((item) => ({ ...item, widgets: searchWidgets(item.widgets, query) }))
     .filter((item) => item.widgets.length > 0)
 }

Also add a watcher to re-initialize when widgetsSectionDataList changes:

watch(widgetsSectionDataList, (newVal) => {
  if (!searchQuery.value) {
    searchedWidgetsSectionDataList.value = newVal
  }
}, { immediate: true })

58-61: Reference comparison will always fail—use search state instead.

widgetsSectionDataList is a computed that returns a new array on each access. Comparing it with === to searchedWidgetsSectionDataList (a shallowRef) will always be false. Track search state explicitly instead.

🔎 Proposed fix

Add a search query tracker:

+const searchQuery = ref('')
+
 function searcher(query: string) {
+  searchQuery.value = query
   const list = widgetsSectionDataList.value
   // ... rest of function
 }

Then in the template:

     :default-collapse="
-      widgetsSectionDataList.length > 1 &&
-      widgetsSectionDataList === searchedWidgetsSectionDataList
+      widgetsSectionDataList.length > 1 && !searchQuery
     "
src/components/rightSidePanel/parameters/TabGlobalParameters.vue (2)

31-36: Initialize search results to prevent empty initial render.

Similar to TabNodes.vue, searchedFavoritedWidgets starts empty and is only populated when searcher() is called. The async keyword is also unnecessary.

🔎 Proposed fix
-const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>([])
+const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>(
+  favoritedWidgets.value
+)

-async function searcher(query: string) {
+function searcher(query: string) {
   searchQuery.value = query
   searchedFavoritedWidgets.value = searchWidgets(favoritedWidgets.value, query)
 }

Add a watcher to update when favorites change:

watch(favoritedWidgets, (newVal) => {
  if (!searchQuery.value) {
    searchedFavoritedWidgets.value = newVal
  } else {
    searchedFavoritedWidgets.value = searchWidgets(newVal, searchQuery.value)
  }
}, { immediate: true })

99-99: Add update-key prop to reset search when favorites change.

Without the update-key prop, adding or removing favorites while a search is active won't refresh results because the search query hasn't changed.

-    <SidePanelSearch :searcher />
+    <SidePanelSearch :searcher :update-key="favoritedWidgets" />

This matches the pattern used in TabNodes.vue.

src/components/rightSidePanel/RightSidePanel.vue (1)

69-71: Use public nodes accessor instead of private _nodes.

Accessing the private _nodes property violates encapsulation and the type assertion as LGraphNode[] is unsafe since the array may contain SubgraphNode instances. Use the public graph.nodes getter with proper type filtering.

🔎 Proposed fix
-const rootLevelNodes = computed((): LGraphNode[] => {
-  return (canvasStore.canvas?.graph?._nodes ?? []) as LGraphNode[]
-})
+const rootLevelNodes = computed((): LGraphNode[] => {
+  const nodes = canvasStore.canvas?.graph?.nodes ?? []
+  return nodes.filter((node): node is LGraphNode => !(node instanceof SubgraphNode))
+})
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbe4d59 and 8597e06.

📒 Files selected for processing (7)
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/shared.ts
  • src/locales/en/main.json
🧰 Additional context used
📓 Path-based instructions (14)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/locales/en/main.json
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/components/rightSidePanel/shared.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/components/rightSidePanel/shared.ts
🧠 Learnings (38)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Prefer single line `if` syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting and follow the arrow anti-pattern

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/settings/TabSettings.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : When writing methods, prefer returning idiomatic JavaScript `undefined` over `null`

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : When writing tests for subgraph-related code, always import from the barrel export at `@/lib/litegraph/src/litegraph` to avoid circular dependency issues

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-30T22:22:38.162Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:38.162Z
Learning: In Pinia setup stores, when accessing reactive properties directly via `useStore().property` pattern (e.g., `useQueueUIStore().isOverlayExpanded`), Pinia automatically unwraps refs and returns the primitive value. The `.value` accessor is only needed when destructuring store properties or using `storeToRefs()`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
🧬 Code graph analysis (1)
src/components/rightSidePanel/shared.ts (4)
src/lib/litegraph/src/types/widgets.ts (1)
  • IBaseWidget (271-429)
src/lib/litegraph/src/LGraph.ts (1)
  • groups (391-393)
src/utils/litegraphUtil.ts (2)
  • isLGraphGroup (58-60)
  • isLGraphNode (54-56)
src/lib/litegraph/src/LGraphGroup.ts (1)
  • children (121-123)
🔇 Additional comments (10)
src/locales/en/main.json (1)

2409-2454: LGTM! Locale additions support the new right-side panel features.

The new translation keys are well-organized and follow existing naming conventions. The wording change from "node(s)" to "item(s)" in the title properly reflects the expanded selection support (nodes + groups).

As per learnings, only English locale entries are needed in PRs—other locales are auto-generated on release.

src/components/rightSidePanel/settings/TabSettings.vue (2)

1-21: LGTM! Clean conditional rendering based on selection type.

The template correctly handles three cases:

  1. Only nodes: renders directly without accordion
  2. Multiple types: wraps each in PropertiesAccordionItem

This provides a cleaner UX when only one type is present.


47-53: LGTM! Type guards correctly narrow selection types.

The computed properties correctly use isLGraphNode and isLGraphGroup type predicates to filter and narrow types without unnecessary casts.

src/components/rightSidePanel/shared.ts (2)

12-33: LGTM! Well-designed search function with multi-word support.

The search correctly:

  • Handles empty queries
  • Tokenizes the query by spaces for multi-word AND search
  • Searches across name, label, type, and value
  • Preserves the generic type of the input list

107-116: LGTM! Efficient deduplication preserving order.

The repeatItems function correctly deduplicates by using a Set to track seen items while preserving first-occurrence order in the result array.

src/components/rightSidePanel/parameters/TabNormalInputs.vue (2)

15-17: Props destructuring follows Vue 3.5+ best practices.

The reactive props destructuring pattern is correctly used and maintains reactivity through compiler transformation.


69-69: No changes needed — computedDisabled is the correct property to use.

The computedDisabled property is a valid, readonly computed property on IBaseWidget that reflects the actual disabled state used for rendering. It accounts for both the widget's disabled flag and whether the widget has an incoming connection. This is the correct property to filter widgets, and the implementation aligns with the pattern used consistently throughout the codebase.

Likely an incorrect or invalid review comment.

src/components/rightSidePanel/RightSidePanel.vue (3)

99-135: Dynamic tab logic is well-structured.

The computed tabs list correctly adapts to selection state, showing appropriate tabs and labels for different contexts (no selection, single node, multiple items). The i18n integration is proper.


149-170: Title editing logic is correctly implemented.

The allowTitleEdit computed correctly restricts editing to single item selections, and handleTitleEdit properly updates the node/group title, marks the canvas dirty, and triggers reactivity updates.


248-267: Content rendering branches handle all states correctly.

The three-branch structure properly handles: no selection (global tabs), subgraph editing, and normal selection (per-node tabs). Props are correctly passed to each tab component.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/rightSidePanel/RightSidePanel.vue (1)

258-266: Consider prop naming consistency.

TabParameters receives :nodes="selectedNodes" (typed as LGraphNode[]) while TabSettings receives :nodes="flattedItems" (typed as MixedSelectionItem[]). Using the same prop name nodes for different types may be confusing. If TabSettings accepts mixed items (groups and nodes), consider renaming its prop to items or selection for clarity.

♻️ Duplicate comments (1)
src/components/rightSidePanel/RightSidePanel.vue (1)

69-71: Replace _nodes access with the public nodes getter.

This issue was already identified in a previous review. Use graph.nodes instead of the private _nodes property and apply proper type narrowing to filter out SubgraphNode instances.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8597e06 and 5b9a279.

📒 Files selected for processing (1)
  • src/components/rightSidePanel/RightSidePanel.vue
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
🧠 Learnings (27)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : When writing methods, prefer returning idiomatic JavaScript `undefined` over `null`

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting and follow the arrow anti-pattern

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
🔇 Additional comments (1)
src/components/rightSidePanel/RightSidePanel.vue (1)

254-256: Verify type safety for SubgraphEditor node prop.

The selectedSingleNode computed returns LGraphNode | null, but the v-else-if condition ensures it's a SubgraphNode at runtime. TypeScript cannot infer this narrowing from the template condition. Verify that SubgraphEditor properly handles the nullable type or consider creating a dedicated computed that returns SubgraphNode | undefined with proper type guards.

Alternative with type-safe computed
const selectedSubgraphNode = computed((): SubgraphNode | undefined => {
  return selectedSingleNode.value instanceof SubgraphNode 
    ? selectedSingleNode.value 
    : undefined
})

Then use :node="selectedSubgraphNode" in the template.

Comment on lines +162 to 163
const node = selectedGroups.value[0] || selectedNodes.value[0]
if (!node) return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Rename variable for clarity.

The variable node can hold either a LGraphGroup or LGraphNode. Consider renaming to target or selectedItem to better reflect that it represents either type.

Suggested refactor
- const node = selectedGroups.value[0] || selectedNodes.value[0]
- if (!node) return
+ const target = selectedGroups.value[0] || selectedNodes.value[0]
+ if (!target) return

- if (trimmedTitle === node.title) return
+ if (trimmedTitle === target.title) return

- node.title = trimmedTitle
+ target.title = trimmedTitle

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/rightSidePanel/RightSidePanel.vue around lines 162 to 163, the
local variable named `node` can be either a LGraphGroup or LGraphNode; rename it
to a clearer name such as `target` or `selectedItem` everywhere it is declared
and referenced in this scope to reflect that it may be either type, update any
related comments and usages in the function so they remain consistent, and
ensure TypeScript types (if present) and linting are adjusted accordingly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @src/locales/en/main.json:
- Line 2492: The "nodesNoneDesc" localization value uses all-caps; change the
string for nodesNoneDesc to match the sentence-case style used by other
*NoneDesc keys (e.g., favoritesNoneDesc) — e.g., replace "NO NODES" with "No
nodes" (or a similarly descriptive sentence-case phrasing) so the empty-state
messaging is consistent.
- Line 2470: The localization key "favoritesNoneTooltip" uses the phrase "Star
widgets" which is inconsistent with the rest of the UI that uses "Favorite"
terminology (see keys "addFavorite" and "removeFavorite"); update the string for
"favoritesNoneTooltip" to use the same wording (e.g., "Mark widgets as favorites
to quickly access them without selecting nodes" or "Favorite widgets to quickly
access them without selecting nodes") and ensure any other locale files use the
same phrasing for consistency.
- Line 2446: Replace the awkward "(s)" pluralization in the "title" locale entry
by updating the value for the "title" key to use explicit plural forms: change
"No item(s) selected | 1 item selected | {count} items selected" to "No items
selected | 1 item selected | {count} items selected" so the first form reads
naturally without parentheses.
- Line 2478: Update the "showAdvancedTooltip" value to improve clarity and
consistency by replacing the all-caps "TRUE" and awkward phrasing; change the
string for showAdvancedTooltip to use "enabled" and the clearer structure "This
is an important setting that, when enabled, reveals all advanced parameters for
nodes" so the tooltip reads naturally and follows UI text conventions.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebf8731 and 61ba51e.

📒 Files selected for processing (2)
  • src/locales/en/main.json
  • src/services/litegraphService.ts
🧰 Additional context used
📓 Path-based instructions (8)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/services/litegraphService.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/services/litegraphService.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/services/litegraphService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/services/litegraphService.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/services/litegraphService.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/services/litegraphService.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/services/litegraphService.ts
  • src/locales/en/main.json
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/services/litegraphService.ts
🧠 Learnings (6)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/services/litegraphService.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/services/litegraphService.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/services/litegraphService.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/services/litegraphService.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/services/litegraphService.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (4)
src/locales/en/main.json (1)

431-432: LGTM! Context menu items are clear and consistent.

The new favorite/unfavorite widget context menu entries follow the established naming conventions and are clear to users.

src/services/litegraphService.ts (3)

53-53: LGTM! Store import added for widget favoriting feature.

The import of useFavoritedWidgetsStore is correctly placed and follows the project's import organization pattern.


679-695: LGTM! Improved code structure with explicit braces.

The addition of braces around the if (input) block improves code clarity and explicitly delineates the scope of the rename widget logic.


697-709: Translation keys are present; favoriting widgets without inputs appears intentional.

The translation keys contextMenu.FavoriteWidget and contextMenu.UnfavoriteWidget exist in src/locales/en/main.json. The placement of the favorite/unfavorite logic outside the if (input) block is intentional design—the feature allows favoriting any widget independently of whether it has an associated input, in contrast to renaming which is restricted to widgets with inputs (inside the if (input) block). The store implementation appears robust and does not require error handling in the context menu callback.

"noSelection": "Select a node to see its properties and info.",
"title": "No node(s) selected | 1 node selected | {count} nodes selected",
"workflowOverview": "Workflow Overview",
"title": "No item(s) selected | 1 item selected | {count} items selected",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Simplify pluralization text.

The "(s)" notation in "No item(s) selected" is awkward in user-facing text. Consider using "No items selected" without parentheses for cleaner, more natural language.

📝 Suggested improvement
-    "title": "No item(s) selected | 1 item selected | {count} items selected",
+    "title": "No items selected | 1 item selected | {count} items selected",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"title": "No item(s) selected | 1 item selected | {count} items selected",
"title": "No items selected | 1 item selected | {count} items selected",
🤖 Prompt for AI Agents
In @src/locales/en/main.json at line 2446, Replace the awkward "(s)"
pluralization in the "title" locale entry by updating the value for the "title"
key to use explicit plural forms: change "No item(s) selected | 1 item selected
| {count} items selected" to "No items selected | 1 item selected | {count}
items selected" so the first form reads naturally without parentheses.

"locateNode": "Locate node on canvas",
"favorites": "FAVORITED INPUTS",
"favoritesNone": "NO FAVORITED INPUTS",
"favoritesNoneTooltip": "Star widgets to quickly access them without selecting nodes",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix terminology inconsistency.

The tooltip mentions "Star widgets" but the UI uses "Favorite" terminology (lines 2463-2464: "addFavorite", "removeFavorite"). Use consistent terminology throughout.

📝 Proposed fix
-    "favoritesNoneTooltip": "Star widgets to quickly access them without selecting nodes",
+    "favoritesNoneTooltip": "Favorite widgets to quickly access them without selecting nodes",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"favoritesNoneTooltip": "Star widgets to quickly access them without selecting nodes",
"favoritesNoneTooltip": "Favorite widgets to quickly access them without selecting nodes",
🤖 Prompt for AI Agents
In @src/locales/en/main.json at line 2470, The localization key
"favoritesNoneTooltip" uses the phrase "Star widgets" which is inconsistent with
the rest of the UI that uses "Favorite" terminology (see keys "addFavorite" and
"removeFavorite"); update the string for "favoritesNoneTooltip" to use the same
wording (e.g., "Mark widgets as favorites to quickly access them without
selecting nodes" or "Favorite widgets to quickly access them without selecting
nodes") and ensure any other locale files use the same phrasing for consistency.

"canvas": "CANVAS",
"connectionLinks": "CONNECTION LINKS",
"showAdvanced": "Show advanced parameters",
"showAdvancedTooltip": "This is an important setting that when set to TRUE, reveals all advanced parameters for nodes",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Improve tooltip text clarity and consistency.

The tooltip has two issues:

  1. "TRUE" in all-caps is inconsistent with typical UI patterns (should be "enabled" or lowercase "true")
  2. Awkward sentence structure: "that when set to TRUE" → "that, when enabled,"
📝 Proposed fix
-      "showAdvancedTooltip": "This is an important setting that when set to TRUE, reveals all advanced parameters for nodes",
+      "showAdvancedTooltip": "This is an important setting that, when enabled, reveals all advanced parameters for nodes",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"showAdvancedTooltip": "This is an important setting that when set to TRUE, reveals all advanced parameters for nodes",
"showAdvancedTooltip": "This is an important setting that, when enabled, reveals all advanced parameters for nodes",
🤖 Prompt for AI Agents
In @src/locales/en/main.json at line 2478, Update the "showAdvancedTooltip"
value to improve clarity and consistency by replacing the all-caps "TRUE" and
awkward phrasing; change the string for showAdvancedTooltip to use "enabled" and
the clearer structure "This is an important setting that, when enabled, reveals
all advanced parameters for nodes" so the tooltip reads naturally and follows UI
text conventions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Line 69: The hasParents computed uses unnecessary optional chaining; update
the computed for hasParents (defined as const hasParents = computed(...)) to
directly check the array length since parents defaults to [] — e.g., replace the
expression with a simple parents.length > 0 (or Boolean(parents.length)) so the
optional chaining is removed.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 61ba51e and 55d4e02.

📒 Files selected for processing (2)
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/composables/graph/useGraphNodeManager.ts
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/composables/graph/useGraphNodeManager.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧠 Learnings (17)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧬 Code graph analysis (1)
src/composables/graph/useGraphNodeManager.ts (2)
src/lib/litegraph/src/types/widgets.ts (1)
  • IBaseWidget (271-430)
src/types/simplifiedWidget.ts (1)
  • SafeControlWidget (35-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (6)
src/composables/graph/useGraphNodeManager.ts (2)

106-110: No issues identified. The useReactiveWidgetValue function is only used internally within this module (lines 106 and 190), so removing its export does not introduce a breaking change. The function scope change is correct.


112-124: Add JSDoc documentation for the public API function, or reconsider the export if only used internally.

The function is exported but currently has no documentation. Additionally, a search found no external imports of getControlWidget—it's only used internally within this file at line ~193.

Either:

  1. Add JSDoc documentation describing the function's purpose, parameters, and return value (consistent with the normalizeWidgetValue documentation pattern in this file), or
  2. Remove the export keyword if this function is not intended for external use
src/components/rightSidePanel/parameters/WidgetItem.vue (4)

1-37: LGTM: Clean imports and proper Vue 3.5 props definition.

The imports are well-organized and the props use the correct Vue 3.5 destructuring style with TypeScript types and default values.


132-142: LGTM: Appropriate use of PrimeIcons for filled star.

The use of pi pi-star-fill from PrimeIcons is acceptable here since Lucide lacks filled icon variants. The favorite indicator is properly conditionally rendered and styled.


86-91: Extract complex class conditionals to computed properties.

Multiple class bindings contain complex conditional logic that should be extracted to computed properties for better readability and maintainability.

Based on learnings, complex conditionals in templates should be extracted to computed properties.

♻️ Suggested refactor
+const containerClasses = computed(() =>
+  cn(
+    'widget-item col-span-full grid grid-cols-subgrid rounded-lg group',
+    isDraggable &&
+      'draggable-item drag-handle cursor-grab bg-comfy-menu-bg [&.is-draggable]:cursor-grabbing outline-comfy-menu-bg [&.is-draggable]:outline-4 [&.is-draggable]:outline-offset-0 [&.is-draggable]:opacity-70'
+  )
+)
+
+const headerClasses = computed(() =>
+  cn(
+    'min-h-8 flex items-center justify-between gap-1 mb-1.5 min-w-0',
+    isDraggable && 'pointer-events-none'
+  )
+)
+
+const widgetNameClasses = computed(() =>
+  cn(
+    'text-sm leading-8 p-0 m-0 truncate',
+    isDraggable && 'pointer-events-none'
+  )
+)
+
+const dragHandleClasses = computed(() =>
+  cn(
+    'pointer-events-none mt-1.5 mx-auto max-w-40 w-1/2 h-1 rounded-lg bg-transparent transition-colors duration-150',
+    'group-hover:bg-interface-stroke group-[.is-draggable]:bg-component-node-widget-background-highlighted',
+    !isDraggable && '!opacity-0'
+  )
+)

Then use in template:

-    :class="
-      cn(
-        'widget-item col-span-full grid grid-cols-subgrid rounded-lg group',
-        isDraggable &&
-          'draggable-item drag-handle cursor-grab bg-comfy-menu-bg [&.is-draggable]:cursor-grabbing outline-comfy-menu-bg [&.is-draggable]:outline-4 [&.is-draggable]:outline-offset-0 [&.is-draggable]:opacity-70'
-      )
-    "
+    :class="containerClasses"

...

-      :class="
-        cn(
-          'min-h-8 flex items-center justify-between gap-1 mb-1.5 min-w-0',
-          isDraggable && 'pointer-events-none'
-        )
-      "
+      :class="headerClasses"

...

-        :class="
-          cn(
-            'text-sm leading-8 p-0 m-0 truncate',
-            isDraggable && 'pointer-events-none'
-          )
-        "
+        :class="widgetNameClasses"

...

-      :class="
-        cn(
-          'pointer-events-none mt-1.5 mx-auto max-w-40 w-1/2 h-1 rounded-lg bg-transparent transition-colors duration-150',
-          'group-hover:bg-interface-stroke group-[.is-draggable]:bg-component-node-widget-background-highlighted',
-          !isDraggable && '!opacity-0'
-        )
-      "
+      :class="dragHandleClasses"

Also applies to: 96-101, 105-109, 155-160

⛔ Skipped due to learnings
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:19.792Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, inline Tailwind CSS class strings, even when long, are acceptable and preferred over extracting them to computed properties when the classes are static. This is a common Tailwind pattern and doesn't need to be flagged as a readability issue.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In Comfy-Org/ComfyUI_frontend, the `cn` utility function from `@/utils/tailwindUtil` uses `tailwind-merge`, which intelligently resolves conflicting Tailwind classes by keeping the last one. When a component uses `cn('base-classes bg-default', propClass)`, if `propClass` contains a conflicting background class, `tailwind-merge` will correctly override `bg-default` with the value from `propClass`. This additive pattern is correct and intentional, following the shadcn-ui convention.
</learning]
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use `!important` or the `!` important prefix for Tailwind classes; find and correct interfering `!important` classes instead
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:16.031Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, avoid creating single-use variants for the Button component (and other UI components). Variants should be reusable across multiple use cases. It's acceptable to use a mix of variant props and manual Tailwind classes temporarily when a specific styling need exists in only one place, with consolidation deferred to a later phase when patterns emerge.

39-40: This pattern is necessary for LiteGraph widget integration and correctly handles externally mutable objects.

The shallowRef + watchEffect + triggerRef pattern is not an architectural flaw but a necessary solution. Widgets are mutated directly by child components (WidgetActions.vue explicitly mutates widget.label with an eslint-disable comment, and SectionWidgets.vue mutates widget.value). Since these widgets come from LiteGraph—an external library designed for mutation—the current approach is appropriate:

  • shallowRef is correct because only shallow reactivity is needed
  • watchEffect ensures sync when the prop updates from the parent
  • triggerRef is required because shallowRef cannot auto-detect mutations to nested properties

Immutability cannot be applied to externally mutable objects without breaking integration with the LiteGraph library.

Likely an incorrect or invalid review comment.

return sourceNode ? sourceNode.title || sourceNode.type : null
})
const hasParents = computed(() => parents?.length > 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider simplifying the hasParents computed.

Since parents has a default value of [], the optional chaining is unnecessary.

♻️ Simplification
-const hasParents = computed(() => parents?.length > 0)
+const hasParents = computed(() => parents.length > 0)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const hasParents = computed(() => parents?.length > 0)
const hasParents = computed(() => parents.length > 0)
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue at line 69, The
hasParents computed uses unnecessary optional chaining; update the computed for
hasParents (defined as const hasParents = computed(...)) to directly check the
array length since parents defaults to [] — e.g., replace the expression with a
simple parents.length > 0 (or Boolean(parents.length)) so the optional chaining
is removed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Around line 56-68: The enhancement merging in computed enhancedWidget is
overly defensive—replace the temporary enhancements object and length check by
directly returning a spread of theWidget with conditional spreads for
controlWidget and spec: compute theWidget via widget.value, call
getControlWidget(theWidget) and nodeDefStore.getInputSpecForWidget(node,
theWidget.name), then return { ...theWidget, ...(controlWidget && {
controlWidget }), ...(spec && { spec }) } so empty values aren’t added without
needing Object.keys/enhancements.length checks; update enhancedWidget
accordingly.
- Around line 164-172: Remove the Tailwind important prefix by replacing the
conditional string "!opacity-0" inside the cn(...) call in WidgetItem.vue with a
normal "opacity-0" class (e.g., change !isDraggable && '!opacity-0' to
!isDraggable && 'opacity-0'); if the opacity is being overridden elsewhere, fix
that source or increase selector specificity using existing group/variant
selectors rather than using the ! prefix, and optionally add transition-opacity
to preserve smooth transitions.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55d4e02 and 59b75ce.

📒 Files selected for processing (1)
  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧠 Learnings (13)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (13)
src/components/rightSidePanel/parameters/WidgetItem.vue (13)

1-20: LGTM: Imports are well-organized.

The imports follow the sorted and grouped pattern, bringing in Vue composition API utilities, stores, types, components, and utility functions appropriately.


22-38: LGTM: Props follow Vue 3.5 best practices.

The destructured props with inline defaults align with the Vue 3.5 TypeScript-style prop declaration guideline.


40-41: Verify necessity of mutable widget reference.

The shallowRef + watchEffect pattern creates a mutable copy of the prop. While triggerRef(widget) on line 89 suggests manual reactivity is needed (possibly for in-place LiteGraph mutations), this deviates from the preference for computed properties and immutability.

Confirm whether this mutable pattern is essential for LiteGraph integration. If the widget isn't mutated in place, consider replacing with:

const widget = computed(() => theWidget)

If manual triggering is genuinely required, document why in a code comment.

Based on learnings, prefer computed() over ref with watch when deriving values. As per coding guidelines, avoid mutable state and prefer immutability.


43-46: LGTM: Emits are properly typed.

The emit definitions follow Vue 3 composition API conventions with clear type signatures.


48-49: LGTM: Store initialization is correct.


51-54: LGTM: Component resolution logic is clear.

The fallback to WidgetLegacy provides a safe default when the registry lookup fails.


70-77: LGTM: Proxy widget handling is correct.

The logic properly resolves the source node for proxy widgets and provides appropriate fallbacks (title → type).


79-82: LGTM: Helper computed properties are clear.

The logic for hasParents and favoriteNode is straightforward and easy to follow.


84-91: Event handlers are appropriate for the chosen pattern.

The triggerRef call in handleWidgetUpdate is consistent with the shallow ref pattern on line 40. If that pattern is validated as necessary, these handlers are correct.


95-103: LGTM: Root element structure is appropriate.

The use of cn() for class merging, grid-cols-subgrid, and conditional draggable classes follows project conventions. Inline Tailwind classes are acceptable per project guidelines.


105-140: LGTM: Header structure is well-organized.

The layout clearly separates the widget label, source node name, and actions. Semantic color tokens (text-muted-foreground) align with the design system.


154-162: LGTM: Dynamic component rendering is well-structured.

The explicit model-value binding and conditional styling based on shouldExpand are appropriate for dynamic widget types.


142-152: Replace invalid z-2 class; PrimeIcons usage is appropriate.

Line 147: The z-2 class is not a valid Tailwind utility (standard z-index values are z-0, z-10, z-20, z-30, z-40, z-50, z-auto). Remove this class or replace with z-10 if z-index stacking is required. Given the relative/absolute positioning context here, the z-index may be unnecessary entirely.

The pi pi-star-fill icon is appropriate for this use case; PrimeIcons is the project's established icon library for Vue templates.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Around line 39-40: The code creates a local mutable ref via
shallowRef(theWidget) and keeps it synced with the prop using watchEffect(() =>
(widget.value = theWidget)), but lacks an explanatory comment; add a brief
inline comment above the declaration of widget (and the watchEffect) explaining
why a local ref is needed (e.g., to allow safe local mutation without mutating
the parent prop, or to limit reactivity tracking for large objects) and note the
alternative of using the prop directly if no local mutation/optimization is
required.
- Around line 133-143: The favorite star indicator is decorative and currently
inaccessible; update the element in WidgetItem.vue that renders the star (the
<i> with classes "pi pi-star-fill" inside the div guarded by
favoritedWidgetsStore.isFavorited) to include an accessible label for screen
readers (e.g., add aria-label or aria-hidden on decorative combined with a
visually-hidden span announcing widget.favorited) and wire the label to i18n by
adding the key "widget.favorited" to src/locales/en/main.json; ensure
pointer-events-none can remain but do not rely on it for accessibility and
prefer aria-label or a visually-hidden element for assistive technologies.

In @src/composables/graph/useGraphNodeManager.ts:
- Line 158: The call to useNodeDefStore() inside getSharedWidgetEnhancements is
invoked per widget (via safeWidgetMapper) which could hurt performance at large
render scales; modify getSharedWidgetEnhancements to accept an optional
nodeDefStore parameter (defaulting to useNodeDefStore()) so callers can pass a
single shared store instance, and update callers such as safeWidgetMapper to
obtain the store once and pass it through when mapping widgets to reuse the same
Pinia store instead of repeatedly calling useNodeDefStore().
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59b75ce and 40faf68.

📒 Files selected for processing (2)
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/composables/graph/useGraphNodeManager.ts
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/composables/graph/useGraphNodeManager.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧠 Learnings (24)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use `!important` or the `!` important prefix for Tailwind classes; find and correct interfering `!important` classes instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T20:39:30.137Z
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use the `dark:` Tailwind variant; use semantic values from the `style.css` theme instead (e.g., `bg-node-component-surface`)

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T17:30:29.719Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7559
File: .storybook/preview.ts:61-61
Timestamp: 2025-12-16T17:30:29.719Z
Learning: In .storybook/preview.ts for the Comfy-Org/ComfyUI_frontend repository, using `document.body.classList.add('[&_*]:!font-inter')` is the correct approach for applying the Inter font to all Storybook story elements. The simpler `font-inter` class alone does not work in this context. This runtime arbitrary variant pattern is valid and should not be flagged as an issue.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Tailwind 4 for styling in Vue components; avoid `<style>` blocks

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧬 Code graph analysis (1)
src/composables/graph/useGraphNodeManager.ts (3)
src/core/graph/subgraph/proxyWidget.ts (1)
  • isProxyWidget (51-53)
src/types/simplifiedWidget.ts (2)
  • WidgetValue (8-16)
  • SafeControlWidget (35-38)
src/schemas/nodeDef/nodeDefSchemaV2.ts (1)
  • InputSpec (177-177)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
  • GitHub Check: setup
🔇 Additional comments (6)
src/components/rightSidePanel/parameters/WidgetItem.vue (3)

141-141: PrimeIcons usage is acceptable for filled star variant.

Using pi pi-star-fill is appropriate here since Lucide lacks filled icon variants. This follows the established pattern in the codebase for mixing icon libraries when necessary.

Based on learnings, mixing PrimeIcons with Lucide is acceptable when one library doesn't provide an equivalent filled icon.


85-93: Tailwind class merging follows best practices.

The use of cn() utility with the additive pattern for class merging is correct and follows the shadcn-ui convention where later classes override conflicting earlier ones.


61-68: No action needed—the graph property is type-safe and getNodeByExecutionId already handles null values.

The _overlay.graph property is typed as LGraph (non-optional) and cannot be null by design. Additionally, getNodeByExecutionId includes an explicit null check at its entry point (if (!rootGraph) return null), making this code safe. This usage pattern is consistent with the official implementation in resolveLinkedWidget.

Likely an incorrect or invalid review comment.

src/composables/graph/useGraphNodeManager.ts (3)

129-173: Well-structured shared enhancement extraction.

The new SharedWidgetEnhancements interface and getSharedWidgetEnhancements function effectively centralize widget metadata extraction logic. This refactor improves maintainability and ensures consistency between different rendering contexts (Nodes 2.0 and Right Side Panel).

The function is well-documented with clear JSDoc comments explaining its purpose.


212-231: Refactored mapper correctly uses shared enhancements.

The safeWidgetMapper function now leverages getSharedWidgetEnhancements through spreading (...sharedEnhancements), which cleanly merges the shared properties while preserving mapper-specific logic like the callback wrapper. This approach maintains consistency and reduces code duplication.


106-110: Verify no external usage of useReactiveWidgetValue.

This function is now private to the module (no longer exported). Verified that no other files in the codebase import and use useReactiveWidgetValue, so this change introduces no breaking changes.

Comment on lines +133 to +143
<div
v-if="
!hiddenFavoriteIndicator &&
favoritedWidgetsStore.isFavorited(favoriteNode, widget.name)
"
class="relative z-2 pointer-events-none"
>
<i
class="absolute -right-1 -top-1 pi pi-star-fill text-xs text-muted-foreground pointer-events-none"
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider accessibility for the favorite indicator.

The favorite indicator (star icon) is purely decorative with pointer-events-none and lacks an accessible label. If this indicator conveys important information to users (whether a widget is favorited), consider adding aria-label or using a visually-hidden label for screen readers.

♿ Suggested accessibility improvement
     <div
       v-if="
         !hiddenFavoriteIndicator &&
         favoritedWidgetsStore.isFavorited(favoriteNode, widget.name)
       "
       class="relative z-2 pointer-events-none"
+      role="img"
+      :aria-label="$t('widget.favorited')"
     >
       <i
         class="absolute -right-1 -top-1 pi pi-star-fill text-xs text-muted-foreground pointer-events-none"
       />
     </div>

Note: Add the corresponding i18n key widget.favorited to src/locales/en/main.json

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue around lines 133 -
143, The favorite star indicator is decorative and currently inaccessible;
update the element in WidgetItem.vue that renders the star (the <i> with classes
"pi pi-star-fill" inside the div guarded by favoritedWidgetsStore.isFavorited)
to include an accessible label for screen readers (e.g., add aria-label or
aria-hidden on decorative combined with a visually-hidden span announcing
widget.favorited) and wire the label to i18n by adding the key
"widget.favorited" to src/locales/en/main.json; ensure pointer-events-none can
remain but do not rely on it for accessibility and prefer aria-label or a
visually-hidden element for assistive technologies.

node: LGraphNode,
widget: IBaseWidget
): SharedWidgetEnhancements {
const nodeDefStore = useNodeDefStore()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider performance impact of repeated store access.

The useNodeDefStore() call inside getSharedWidgetEnhancements is executed for every widget during rendering (via safeWidgetMapper). While Pinia stores are singletons and the overhead is minimal, consider whether this function should accept the store as a parameter if it becomes a performance bottleneck during large graph renders.

⚡ Optional performance optimization

If profiling reveals this to be a bottleneck, you could refactor to accept the store as a parameter:

export function getSharedWidgetEnhancements(
  node: LGraphNode,
  widget: IBaseWidget,
  nodeDefStore = useNodeDefStore()
): SharedWidgetEnhancements {
  // ... rest of implementation
}

This would allow callers to reuse the same store instance across multiple widget enhancements.

🤖 Prompt for AI Agents
In @src/composables/graph/useGraphNodeManager.ts at line 158, The call to
useNodeDefStore() inside getSharedWidgetEnhancements is invoked per widget (via
safeWidgetMapper) which could hurt performance at large render scales; modify
getSharedWidgetEnhancements to accept an optional nodeDefStore parameter
(defaulting to useNodeDefStore()) so callers can pass a single shared store
instance, and update callers such as safeWidgetMapper to obtain the store once
and pass it through when mapping widgets to reuse the same Pinia store instead
of repeatedly calling useNodeDefStore().

@github-actions
Copy link

github-actions bot commented Jan 8, 2026

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetActions.vue:
- Around line 128-179: Replace the raw <button> elements in the WidgetActions
template with the repo's common button components (e.g., IconTextButton /
IconButton / TextButton) so styling, accessibility and theme props are
consistent; preserve existing behavior by wiring the components' click handlers
to handleRename, handleHideInput/handleShowInput, handleToggleFavorite and
calling close() afterwards, pass the same icon classes and label via t(...) and
keep conditional rendering using hasParents, isShownOnParents and isFavorited,
and map any class binding from buttonClasses into the component's class or
variant prop as appropriate.
- Line 2: The import in WidgetActions.vue currently pulls cn from
'@comfyorg/tailwind-utils'; replace that import to use the project's standard
re-export path '@/utils/tailwindUtil' so the file imports cn from
'@/utils/tailwindUtil' (matching other components like WidgetItem.vue) to
maintain consistency across the codebase.

In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Around line 109-116: The template's long inline conditional combining
isDraggable and many Tailwind classes should be moved into a computed property
(e.g., draggableClasses or widgetItemClass) to improve readability; create the
computed in the component script (or setup) that returns the base class string
plus the conditional draggable class string when isDraggable is true, then
replace the inline cn(... isDraggable && '...') expression in the template with
cn('<base-classes>', draggableClasses) or the single computed property;
reference the existing isDraggable identifier and the cn usage so you update the
right logic in WidgetItem.vue.

In @src/components/rightSidePanel/RightSidePanel.vue:
- Around line 100-132: findParentGroupInGraph currently does a full scan of
canvasStore.canvas?.graph?.groups for every lookup, causing O(n) UI slowdown;
replace this on-demand traversal with a cached index: build and maintain a
spatial/map index of group boundingRects keyed for quick lookup (e.g., quadtree
or a simple map from group id to bounding rect plus a spatial bucket) when
groups change, and then use that index inside findParentGroupInGraph to query
candidate groups instead of iterating all groups. Implement cache population and
invalidation hooks where groups are created/updated/removed (the same codepaths
that modify canvasStore.canvas.graph.groups), ensure findParentGroupInGraph
still uses containsCentre and containsRect for final disambiguation among
candidates, and fall back to the full scan only if the index is absent to
preserve correctness during startup/edge cases.
- Line 352: The template is using a non-null assertion on selectedSingleNode;
create a properly typed computed like selectedSubgraphNode
(computed<SubgraphNode | null>() that returns selectedSingleNode.value if it is
instanceof SubgraphNode, otherwise null) and replace usages in the template
(e.g., the TabSubgraphInputs prop) to check v-if="selectedSubgraphNode" and pass
:node="selectedSubgraphNode" so you avoid both the non-null operator and manual
type assertions while relying on the existing isSingleSubgraphNode logic for
runtime safety.
- Around line 112-113: The code is using type assertions like "group as
LGraphGroup" for variables parent/group when iterating graphGroups; remove these
assertions and strengthen typings instead: ensure the graph interface (the type
of canvasStore.canvas?.graph) declares groups as LGraphGroup[] (not any or
unknown), update the local graphGroups variable to use that typed property, and
adjust the loop/guard so TypeScript already knows each item is LGraphGroup
(e.g., narrow or check before assignment) so you can assign to parent without
"as LGraphGroup"; make the same change for the second occurrence where "as
LGraphGroup" is used.

In @src/components/rightSidePanel/shared.ts:
- Around line 138-145: Extract the magic number 1000 into a module-level named
constant (e.g., MAX_TRAVERSAL_DEPTH) and replace the hardcoded literal in the
depth check (the condition using ctx.depth) with that constant; declare the
constant near the top of src/components/rightSidePanel/shared.ts so it is
reusable and documented, then use it in the existing if (ctx.depth >
MAX_TRAVERSAL_DEPTH) return { all: [], nodes: [], groups: [], others: [] }
check.
- Around line 190-199: The function repeatItems actually removes duplicates;
rename the function symbol repeatItems to a clearer name such as
deduplicateItems or uniqueItems (pick one consistently) and update all call
sites that reference repeatItems to the new name; ensure any exported or
imported references are updated as well (e.g., change the function declaration
repeatItems<T>(...) and all usages/imports to deduplicateItems or uniqueItems).
- Around line 147-181: Replace the indexed loop in flatItems with a for...of
iteration to avoid using an unused index: change the loop to iterate like "for
(const rawItem of items) { const item = rawItem as Positionable; ... }" and keep
the existing branching logic that calls isLGraphGroup, isLGraphNode and mutates
result, nodes, groups, others and ctx.nodeToParentGroup exactly as before so
behavior and order remain unchanged.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40faf68 and 37e4d4d.

📒 Files selected for processing (4)
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
  • src/components/rightSidePanel/shared.ts
🧰 Additional context used
📓 Path-based instructions (14)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/components/rightSidePanel/shared.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/components/rightSidePanel/shared.ts
🧠 Learnings (56)
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Implement proper error handling

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Implement proper error handling in code

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/shared.ts
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Write code that is expressive and self-documenting; avoid redundant comments and clean as you go

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Prefer single line `if` syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting and follow the arrow anti-pattern

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-30T22:22:38.162Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:38.162Z
Learning: In Pinia setup stores, when accessing reactive properties directly via `useStore().property` pattern (e.g., `useQueueUIStore().isOverlayExpanded`), Pinia automatically unwraps refs and returns the primitive value. The `.value` accessor is only needed when destructuring store properties or using `storeToRefs()`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/rightSidePanel/shared.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use `!important` or the `!` important prefix for Tailwind classes; find and correct interfering `!important` classes instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T20:39:30.137Z
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use the `dark:` Tailwind variant; use semantic values from the `style.css` theme instead (e.g., `bg-node-component-surface`)

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T17:30:29.719Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7559
File: .storybook/preview.ts:61-61
Timestamp: 2025-12-16T17:30:29.719Z
Learning: In .storybook/preview.ts for the Comfy-Org/ComfyUI_frontend repository, using `document.body.classList.add('[&_*]:!font-inter')` is the correct approach for applying the Inter font to all Storybook story elements. The simpler `font-inter` class alone does not work in this context. This runtime arbitrary variant pattern is valid and should not be flagged as an issue.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Tailwind 4 for styling in Vue components; avoid `<style>` blocks

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧬 Code graph analysis (1)
src/components/rightSidePanel/shared.ts (5)
src/lib/litegraph/src/types/widgets.ts (1)
  • IBaseWidget (271-430)
src/lib/litegraph/src/LGraph.ts (1)
  • groups (391-393)
src/utils/litegraphUtil.ts (2)
  • isLGraphGroup (58-60)
  • isLGraphNode (54-56)
src/lib/litegraph/src/LGraphGroup.ts (1)
  • children (121-123)
src/core/graph/subgraph/proxyWidget.ts (1)
  • isProxyWidget (51-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: deploy-and-comment
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect

@@ -0,0 +1,182 @@
<script setup lang="ts">
import { cn } from '@comfyorg/tailwind-utils'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for all cn utility imports to see the patterns
rg "import.*cn.*from" --type vue --type ts -C 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

# Check the specific files mentioned in the review
echo "=== WidgetActions.vue ===" && cat -n src/components/rightSidePanel/parameters/WidgetActions.vue | head -20
echo "=== WidgetItem.vue ===" && rg -n "import.*cn.*from" src/components/rightSidePanel/parameters/WidgetItem.vue -C 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1244


🏁 Script executed:

# Count which import path is used more frequently
echo "=== Count of @comfyorg/tailwind-utils ===" && rg "@comfyorg/tailwind-utils" --type vue --type ts | wc -l
echo "=== Count of @/utils/tailwindUtil ===" && rg "@/utils/tailwindUtil" --type vue --type ts | wc -l

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 226


🏁 Script executed:

# Search for all cn imports without file type flags
rg "import.*cn.*from" -C 1 | head -50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2836


🏁 Script executed:

# Check which path is the correct/standard one by looking at both modules
echo "=== Check if @/utils/tailwindUtil exists ===" && test -f src/utils/tailwindUtil.ts && echo "EXISTS" || echo "NOT FOUND"
echo "=== Check if @comfyorg/tailwind-utils exists ===" && test -f node_modules/@comfyorg/tailwind-utils && echo "EXISTS" || echo "NOT FOUND"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 180


🏁 Script executed:

# Count each import pattern across all files
echo "=== @comfyorg/tailwind-utils imports ===" && rg "@comfyorg/tailwind-utils" -c | wc -l
echo "=== @/utils/tailwindUtil imports ===" && rg "@/utils/tailwindUtil" -c | wc -l

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 153


🏁 Script executed:

# Find all files using @comfyorg/tailwind-utils
rg "@comfyorg/tailwind-utils" -l

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 634


🏁 Script executed:

# Check if there's a package in node_modules or package.json reference
rg "@comfyorg/tailwind-utils" package.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 116


🏁 Script executed:

# Check what's in the local tailwindUtil.ts file
cat src/utils/tailwindUtil.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 132


Use the standard cn import path for consistency.

Line 2 imports cn from '@comfyorg/tailwind-utils' directly. The codebase standard is to import from '@/utils/tailwindUtil', which re-exports cn. Update to match the pattern used throughout the codebase (e.g., WidgetItem.vue line 18).

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetActions.vue at line 2, The
import in WidgetActions.vue currently pulls cn from '@comfyorg/tailwind-utils';
replace that import to use the project's standard re-export path
'@/utils/tailwindUtil' so the file imports cn from '@/utils/tailwindUtil'
(matching other components like WidgetItem.vue) to maintain consistency across
the codebase.

Comment on lines +128 to +179
<button
:class="buttonClasses"
@click="
() => {
handleRename()
close()
}
"
>
<i class="icon-[lucide--edit] size-4" />
<span>{{ t('g.rename') }}</span>
</button>

<button
v-if="hasParents"
:class="buttonClasses"
@click="
() => {
if (isShownOnParents) handleHideInput()
else handleShowInput()
close()
}
"
>
<template v-if="isShownOnParents">
<i class="icon-[lucide--eye-off] size-4" />
<span>{{ t('rightSidePanel.hideInput') }}</span>
</template>
<template v-else>
<i class="icon-[lucide--eye] size-4" />
<span>{{ t('rightSidePanel.showInput') }}</span>
</template>
</button>

<button
:class="buttonClasses"
@click="
() => {
handleToggleFavorite()
close()
}
"
>
<template v-if="isFavorited">
<i class="icon-[lucide--star]" />
<span>{{ t('rightSidePanel.removeFavorite') }}</span>
</template>
<template v-else>
<i class="icon-[lucide--star]" />
<span>{{ t('rightSidePanel.addFavorite') }}</span>
</template>
</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use common button components instead of plain HTML buttons.

The template uses plain HTML <button> elements for the action menu items. Per project guidelines and learnings, prefer the repo's common button components from src/components/button/ (such as IconButton, TextButton, IconTextButton) for consistency with the design system.

Based on learnings, common button components should be used instead of plain HTML <button> elements to maintain consistent theming across the codebase.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetActions.vue around lines 128
- 179, Replace the raw <button> elements in the WidgetActions template with the
repo's common button components (e.g., IconTextButton / IconButton / TextButton)
so styling, accessibility and theme props are consistent; preserve existing
behavior by wiring the components' click handlers to handleRename,
handleHideInput/handleShowInput, handleToggleFavorite and calling close()
afterwards, pass the same icon classes and label via t(...) and keep conditional
rendering using hasParents, isShownOnParents and isFavorited, and map any class
binding from buttonClasses into the component's class or variant prop as
appropriate.

Comment on lines 100 to 132
/**
* TODO: This traverses the entire graph and could be very slow; needs optimization.
*/
function findParentGroupInGraph(node: LGraphNode): LGraphGroup | null {
const graphGroups = canvasStore.canvas?.graph?.groups ?? []
let parent: LGraphGroup | null = null
for (const group of graphGroups) {
const groupRect = group.boundingRect
if (!containsCentre(groupRect, node.boundingRect)) continue
if (!parent) {
parent = group as LGraphGroup
continue
}
const parentRect = (parent as LGraphGroup).boundingRect
const candidateInsideParent = containsRect(parentRect, groupRect)
const parentInsideCandidate = containsRect(groupRect, parentRect)
if (candidateInsideParent && !parentInsideCandidate) {
parent = group as LGraphGroup
continue
}
const candidateArea = groupRect[2] * groupRect[3]
const parentArea = parentRect[2] * parentRect[3]
const selectedNode = computed(() => {
if (candidateArea < parentArea) parent = group as LGraphGroup
}
return parent
}
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Address performance concern in findParentGroupInGraph.

The TODO at line 100 flags that this function traverses the entire graph and could be very slow. This O(n) traversal on every node lookup could cause UI lag with large graphs.

Consider:

  1. Caching the node-to-group mapping and invalidating on graph structure changes
  2. Building an index when groups are modified rather than on-demand traversal
  3. Using spatial indexing (quadtree/R-tree) if graph sizes justify it

Do you want me to generate an optimized caching solution for parent group lookups?

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/RightSidePanel.vue around lines 100 - 132,
findParentGroupInGraph currently does a full scan of
canvasStore.canvas?.graph?.groups for every lookup, causing O(n) UI slowdown;
replace this on-demand traversal with a cached index: build and maintain a
spatial/map index of group boundingRects keyed for quick lookup (e.g., quadtree
or a simple map from group id to bounding rect plus a spatial bucket) when
groups change, and then use that index inside findParentGroupInGraph to query
candidate groups instead of iterating all groups. Implement cache population and
invalidation hooks where groups are created/updated/removed (the same codepaths
that modify canvasStore.canvas.graph.groups), ensure findParentGroupInGraph
still uses containsCentre and containsRect for final disambiguation among
candidates, and fall back to the full scan only if the index is absent to
preserve correctness during startup/edge cases.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, adding this code is related to the issue where group sub-items were not updating correctly after a page refresh. It can be removed after the bug is fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LittleSound, thank you for the clarification! That makes sense—if this is a temporary workaround for the group sub-items update bug after page refresh, the performance optimization can wait until the underlying issue is resolved and this code is removed.

I've noted this context for future reference.


✏️ Learnings added
Learnt from: LittleSound
Repo: Comfy-Org/ComfyUI_frontend PR: 7812
File: src/components/rightSidePanel/RightSidePanel.vue:100-132
Timestamp: 2026-01-09T07:29:27.929Z
Learning: The `findParentGroupInGraph` function in `src/components/rightSidePanel/RightSidePanel.vue` is a temporary workaround for a bug where group sub-items were not updating correctly after a page refresh. It can be removed once that underlying bug is fixed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines +138 to +145
if (ctx.depth > 1000) {
return {
all: [],
nodes: [],
groups: [],
others: []
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Extract hardcoded depth limit to named constant.

The depth limit of 1000 at line 138 is hardcoded. Extract it to a named constant at the module level for clarity and maintainability.

♻️ Suggested refactor
+const MAX_FLATTEN_DEPTH = 1000
+
 function flatItems(
   items: Positionable[],
   ctx: FlatItemsContext
 ): Omit<FlatAndCategorizeSelectedItemsResult, 'nodeToParentGroup'> {
   const result: MixedSelectionItem[] = []
   const nodes: LGraphNode[] = []
   const groups: LGraphGroup[] = []
   const others: Positionable[] = []

-  if (ctx.depth > 1000) {
+  if (ctx.depth > MAX_FLATTEN_DEPTH) {
     return {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (ctx.depth > 1000) {
return {
all: [],
nodes: [],
groups: [],
others: []
}
}
const MAX_FLATTEN_DEPTH = 1000
function flatItems(
items: Positionable[],
ctx: FlatItemsContext
): Omit<FlatAndCategorizeSelectedItemsResult, 'nodeToParentGroup'> {
const result: MixedSelectionItem[] = []
const nodes: LGraphNode[] = []
const groups: LGraphGroup[] = []
const others: Positionable[] = []
if (ctx.depth > MAX_FLATTEN_DEPTH) {
return {
all: [],
nodes: [],
groups: [],
others: []
}
}
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/shared.ts around lines 138 - 145, Extract the
magic number 1000 into a module-level named constant (e.g., MAX_TRAVERSAL_DEPTH)
and replace the hardcoded literal in the depth check (the condition using
ctx.depth) with that constant; declare the constant near the top of
src/components/rightSidePanel/shared.ts so it is reusable and documented, then
use it in the existing if (ctx.depth > MAX_TRAVERSAL_DEPTH) return { all: [],
nodes: [], groups: [], others: [] } check.

Comment on lines +147 to +181
for (let i = 0; i < items.length; i++) {
const item = items[i] as Positionable

if (isLGraphGroup(item)) {
result.push(item)
groups.push(item)

const children = Array.from(item.children)
const childCtx: FlatItemsContext = {
nodeToParentGroup: ctx.nodeToParentGroup,
depth: ctx.depth + 1,
parentGroup: item
}
const {
all: childAll,
nodes: childNodes,
groups: childGroups,
others: childOthers
} = flatItems(children, childCtx)
result.push(...childAll)
nodes.push(...childNodes)
groups.push(...childGroups)
others.push(...childOthers)
} else if (isLGraphNode(item)) {
result.push(item)
nodes.push(item)
if (ctx.parentGroup) {
ctx.nodeToParentGroup.set(item, ctx.parentGroup)
}
} else {
// Other types of items are not supported yet
// Do not add to all
others.push(item)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Prefer for...of loop over indexed for loop.

Line 147 uses a traditional for loop with index. Per functional programming guidelines, prefer for...of when the index isn't needed for the iteration logic.

♻️ Suggested refactor
-  for (let i = 0; i < items.length; i++) {
-    const item = items[i] as Positionable
+  for (const item of items) {

Based on coding guidelines to keep functions functional and minimize unnecessary indexing.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/shared.ts around lines 147 - 181, Replace the
indexed loop in flatItems with a for...of iteration to avoid using an unused
index: change the loop to iterate like "for (const rawItem of items) { const
item = rawItem as Positionable; ... }" and keep the existing branching logic
that calls isLGraphGroup, isLGraphNode and mutates result, nodes, groups, others
and ctx.nodeToParentGroup exactly as before so behavior and order remain
unchanged.

Comment on lines +190 to +199
function repeatItems<T>(items: T[]): T[] {
const itemSet = new Set<T>()
const result: T[] = []
for (const item of items) {
if (itemSet.has(item)) continue
itemSet.add(item)
result.push(item)
}
return result
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Rename repeatItems to better describe its purpose.

The function name repeatItems is misleading—it actually deduplicates items using a Set. Consider renaming to deduplicateItems or uniqueItems for clarity.

♻️ Suggested refactor
-function repeatItems<T>(items: T[]): T[] {
+function deduplicateItems<T>(items: T[]): T[] {
   const itemSet = new Set<T>()
   const result: T[] = []
   for (const item of items) {
     if (itemSet.has(item)) continue
     itemSet.add(item)
     result.push(item)
   }
   return result
 }

And update all call sites:

   return {
-    all: repeatItems(all),
-    nodes: repeatItems(nodes),
-    groups: repeatItems(groups),
-    others: repeatItems(others),
+    all: deduplicateItems(all),
+    nodes: deduplicateItems(nodes),
+    groups: deduplicateItems(groups),
+    others: deduplicateItems(others),
     nodeToParentGroup: ctx.nodeToParentGroup
   }

Based on coding guidelines to write expressive, self-documenting code.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/shared.ts around lines 190 - 199, The function
repeatItems actually removes duplicates; rename the function symbol repeatItems
to a clearer name such as deduplicateItems or uniqueItems (pick one
consistently) and update all call sites that reference repeatItems to the new
name; ensure any exported or imported references are updated as well (e.g.,
change the function declaration repeatItems<T>(...) and all usages/imports to
deduplicateItems or uniqueItems).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetActions.vue:
- Line 172: The star icon in WidgetActions.vue currently uses the same class
"icon-[lucide--star]" for both states; update the template to render a filled
star for the favorited state (e.g., use the PrimeIcons class "pi pi-star-fill")
and the Lucide outline "icon-[lucide--star]" for the unfavorited state, toggling
between them based on the component's favorited state (use the component's
favorited prop/data and a conditional class binding or conditional render so the
UI shows filled when favorited and outline when not); apply the same change for
the second occurrence of the icon in the file.

In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Line 182: Remove the Tailwind important prefix used in the conditional class
expression in WidgetItem.vue (the fragment that renders '!opacity-0' when
!isDraggable); replace it with the normal class 'opacity-0' and then locate and
remove or adjust the actual CSS rule that is overriding opacity (search for any
'!important' or stronger selector targeting this widget or its wrapper) so the
intended opacity behavior works without using the '!' prefix.
- Line 163: WidgetItem uses PrimeIcons via the class "pi pi-star-fill" while the
related WidgetActions component uses Lucide icons, causing inconsistent icon
libraries; pick a consistent approach and update WidgetItem (or document/justify
mixing): either replace the PrimeIcon with a Lucide star implementation inside
WidgetItem (or apply a CSS-filled Lucide variant) to match WidgetActions, or add
a short code comment near the "pi pi-star-fill" class in WidgetItem explaining
the intentional mix and why PrimeIcons is required for the filled star; ensure
the chosen approach is applied consistently across both components and
referenced in the component comment.
- Around line 110-116: The template contains a complex conditional class
expression using cn and isDraggable; extract that logic into a computed property
(e.g., widgetItemClasses or draggableClasses) that returns the base classes plus
the additional draggable classes when isDraggable is true, then replace the
inline :class binding with a simple reference to that computed property; update
the component's setup/ computed block to import/define the computed and ensure
it reads isDraggable and returns the same combined class string or array so the
template remains clean and behavior is identical.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37e4d4d and c5f95bb.

📒 Files selected for processing (2)
  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧠 Learnings (36)
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Implement proper error handling

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Implement proper error handling in code

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-13T11:03:21.073Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:21.073Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, linting rules enforce keeping `import type` statements separate from regular `import` statements, even when importing from the same module. Do not suggest consolidating them into a single import statement.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: When testing components, import the real type definitions from the component files instead of duplicating interface definitions in the test files. This prevents type drift and maintains consistency.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Name Vue components using PascalCase (e.g., `MenuHamburger.vue`)

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetActions.vue
  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use `!important` or the `!` important prefix for Tailwind classes; find and correct interfering `!important` classes instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T20:39:30.137Z
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use the `dark:` Tailwind variant; use semantic values from the `style.css` theme instead (e.g., `bg-node-component-surface`)

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T17:30:29.719Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7559
File: .storybook/preview.ts:61-61
Timestamp: 2025-12-16T17:30:29.719Z
Learning: In .storybook/preview.ts for the Comfy-Org/ComfyUI_frontend repository, using `document.body.classList.add('[&_*]:!font-inter')` is the correct approach for applying the Inter font to all Storybook story elements. The simpler `font-inter` class alone does not work in this context. This runtime arbitrary variant pattern is valid and should not be flagged as an issue.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Tailwind 4 for styling in Vue components; avoid `<style>` blocks

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🔇 Additional comments (2)
src/components/rightSidePanel/parameters/WidgetActions.vue (1)

64-64: The setDirty parameter difference is intentional.

Line 64 calls setDirty(true) for widget rename operations, which only changes the widget's visual label and does not affect the graph structure. Lines 97 and 105 call setDirty(true, true) for promote/demote operations, which modify the graph's subgraph structure (adding/removing proxy widgets). The two parameters control foreground (nodes) and background (links/structure) canvas redraw respectively, so the different usage is correct and intentional.

src/components/rightSidePanel/parameters/WidgetItem.vue (1)

42-43: This pattern is intentional and necessary. The widget objects originate from the litegraph library and are mutated in place to update properties like label that affect the UI bindings. The code already documents this at line 257 of shared.ts with the comment "Intentionally mutate the widget object here as it's a reference to the actual widget in the graph."

The shallowRef + watchEffect + triggerRef pattern is the correct Vue approach for tracking mutations to external objects. Refactoring to create new widget objects would break the litegraph integration and is not feasible.

Likely an incorrect or invalid review comment.

Comment on lines +78 to +79
console.error('Could not find interior node for proxy widget')
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Enhance error handling with user-facing feedback.

Silent console errors when interior nodes or widgets cannot be found may leave users confused when the hide action fails. Consider using dialogService to show an error message.

💬 Proposed enhancement
     if (!interiorNode) {
-      console.error('Could not find interior node for proxy widget')
+      await dialogService.showErrorDialog({
+        title: t('g.error'),
+        message: t('rightSidePanel.cannotFindInteriorNode')
+      })
       return
     }

     const originalWidget = interiorNode.widgets?.find(
       (w) => w.name === widget._overlay.widgetName
     )

     if (!originalWidget) {
-      console.error('Could not find original widget for proxy widget')
+      await dialogService.showErrorDialog({
+        title: t('g.error'),
+        message: t('rightSidePanel.cannotFindOriginalWidget')
+      })
       return
     }

Also applies to: 87-88

"
>
<template v-if="isFavorited">
<i class="icon-[lucide--star]" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use filled star icon to differentiate favorited state.

Both favorited and unfavorited states use the same icon-[lucide--star] icon. Consider using a filled variant for the favorited state to provide clearer visual feedback.

⭐ Proposed differentiation

Based on learnings, mixing PrimeIcons with Lucide is acceptable when Lucide lacks filled variants. Use pi pi-star-fill for favorited:

       <template v-if="isFavorited">
-        <i class="icon-[lucide--star]" />
+        <i class="pi pi-star-fill" />
         <span>{{ t('rightSidePanel.removeFavorite') }}</span>
       </template>
       <template v-else>
         <i class="icon-[lucide--star]" />
         <span>{{ t('rightSidePanel.addFavorite') }}</span>
       </template>

Also applies to: 176-176

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetActions.vue at line 172, The
star icon in WidgetActions.vue currently uses the same class
"icon-[lucide--star]" for both states; update the template to render a filled
star for the favorited state (e.g., use the PrimeIcons class "pi pi-star-fill")
and the Lucide outline "icon-[lucide--star]" for the unfavorited state, toggling
between them based on the component's favorited state (use the component's
favorited prop/data and a conditional class binding or conditional render so the
UI shows filled when favorited and outline when not); apply the same change for
the second occurrence of the icon in the file.

class="relative z-2 pointer-events-none"
>
<i
class="absolute -right-1 -top-1 pi pi-star-fill text-xs text-muted-foreground pointer-events-none"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use consistent icon library across related components.

WidgetItem uses PrimeIcons (pi-star-fill) while the related WidgetActions component uses Lucide icons. For visual consistency, prefer one icon library unless a specific icon variant is unavailable.

🎨 Proposed consistency improvement

Since Lucide lacks a filled star icon and learnings confirm mixing is acceptable in such cases, using pi-star-fill here is valid. However, document this choice or consider using a CSS-filled Lucide star via custom styling for consistency:

-      <i
-        class="absolute -right-1 -top-1 pi pi-star-fill text-xs text-muted-foreground pointer-events-none"
-      />
+      <!-- Using PrimeIcons pi-star-fill as Lucide lacks filled star variant -->
+      <i
+        class="absolute -right-1 -top-1 pi pi-star-fill text-xs text-muted-foreground pointer-events-none"
+      />

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue at line 163,
WidgetItem uses PrimeIcons via the class "pi pi-star-fill" while the related
WidgetActions component uses Lucide icons, causing inconsistent icon libraries;
pick a consistent approach and update WidgetItem (or document/justify mixing):
either replace the PrimeIcon with a Lucide star implementation inside WidgetItem
(or apply a CSS-filled Lucide variant) to match WidgetActions, or add a short
code comment near the "pi pi-star-fill" class in WidgetItem explaining the
intentional mix and why PrimeIcons is required for the filled star; ensure the
chosen approach is applied consistently across both components and referenced in
the component comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @src/platform/settings/constants/coreSettings.ts:
- Around line 1143-1148: The new hidden setting object with id
'Comfy.RightSidePanel.IsOpen' lacks a versionAdded field for consistency; update
the setting definition (the object containing id: 'Comfy.RightSidePanel.IsOpen',
name: 'Right side panel open state', type: 'hidden', defaultValue: false) to
include a versionAdded property with the appropriate version string (matching
the convention used elsewhere in coreSettings.ts).

In @src/stores/workspace/rightSidePanelStore.ts:
- Line 13: The current type alias RightSidePanelSection ('advanced-inputs' |
string) collapses to plain string; decide whether sections are finite or
open-ended and update the alias accordingly: if finite, replace
RightSidePanelSection with an explicit union of string literals (e.g., include
'advanced-inputs', 'basic-inputs', etc.) and update all usages; if open-ended,
change it to just string and add JSDoc explaining accepted values;
alternatively, for stronger typing, implement a branded string pattern (declare
a branded type and convert/validate section values at creation points). Ensure
all references to RightSidePanelSection (including any setters/getters or
consumers in rightSidePanelStore) are updated to match the new type.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5f95bb and 34eeb37.

📒 Files selected for processing (3)
  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
🧰 Additional context used
📓 Path-based instructions (9)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/stores/workspace/rightSidePanelStore.ts
**/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores using the pattern *Store.ts

Files:

  • src/stores/workspace/rightSidePanelStore.ts
🧠 Learnings (10)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/settings/constants/coreSettings.ts
  • src/schemas/apiSchema.ts
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
🔇 Additional comments (8)
src/schemas/apiSchema.ts (1)

540-541: LGTM! Schema addition is correct.

The new Comfy.RightSidePanel.IsOpen boolean setting is properly defined using Zod v3 syntax and follows the existing patterns in the schema. This addition correctly aligns with the corresponding core setting definition.

src/stores/workspace/rightSidePanelStore.ts (7)

4-5: LGTM: Settings store integration.

The import is correctly structured and supports the new persistence feature for panel state.


6-12: LGTM: Tab type expansion.

The addition of the 'nodes' tab type is correctly implemented and aligns with the PR's right-side panel enhancements.


20-21: LGTM: Store initialization.

Correctly instantiates the settings store following standard Pinia composition patterns.


29-29: LGTM: Focused section state.

Correctly declares reactive state for tracking the focused section.


66-71: LGTM: Clear focused section function.

The cleanup function is correctly implemented. Ensure callers properly invoke clearFocusedSection after handling the focused section to prevent stale state.


73-83: LGTM: Store public interface.

The return object correctly exposes all necessary state and methods. The additions are justified by the new focus-section feature and maintain a clear public interface.


22-26: Setting key verified and properly configured.

The setting 'Comfy.RightSidePanel.IsOpen' is correctly defined in src/platform/settings/constants/coreSettings.ts as a hidden boolean setting with a default value of false. It is also registered in the Zod schema for type safety. The computed property correctly integrates with the settings store for persistence.

| 'info'
| 'subgraph'

type RightSidePanelSection = 'advanced-inputs' | string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider a more precise type definition.

The pattern 'advanced-inputs' | string is effectively just string in TypeScript, providing no additional type safety. Consider:

  • If sections are finite: use a union of string literals (e.g., 'advanced-inputs' | 'basic-inputs' | ...)
  • If truly open-ended: use string with JSDoc documentation
  • For branded types: use a branded string pattern
🤖 Prompt for AI Agents
In @src/stores/workspace/rightSidePanelStore.ts at line 13, The current type
alias RightSidePanelSection ('advanced-inputs' | string) collapses to plain
string; decide whether sections are finite or open-ended and update the alias
accordingly: if finite, replace RightSidePanelSection with an explicit union of
string literals (e.g., include 'advanced-inputs', 'basic-inputs', etc.) and
update all usages; if open-ended, change it to just string and add JSDoc
explaining accepted values; alternatively, for stronger typing, implement a
branded string pattern (declare a branded type and convert/validate section
values at creation points). Ensure all references to RightSidePanelSection
(including any setters/getters or consumers in rightSidePanelStore) are updated
to match the new type.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/TabGlobalParameters.vue:
- Around line 42-49: favoritedWidgets changes don't update the UI because
searchedFavoritedWidgets is initialized once; add a watcher on favoritedWidgets
that keeps searchedFavoritedWidgets in sync: when isSearching.value is true,
update searchedFavoritedWidgets.value = searchWidgets(favoritedWidgets.value,
currentQuery) (store the last query used by searcher in a small ref like
lastQuery) otherwise set searchedFavoritedWidgets.value =
favoritedWidgets.value; reference searchedFavoritedWidgets, favoritedWidgets,
searcher, isSearching (and introduce lastQuery ref) to implement this.
- Around line 78-93: Add a null guard at the start of the method (e.g., if
(!this.draggableItem) return) so TypeScript knows draggableItem is defined, then
remove the two casts "as HTMLElement" and use this.draggableItem directly when
assigning into reorderedItems and when calling
reorderedItems.indexOf(this.draggableItem); keep the rest of the logic
(rebuilding widgets and calling favoritedWidgetsStore.reorderFavorites)
unchanged so the method type-checks under strict mode without assertions.

In @src/components/rightSidePanel/parameters/TabNormalInputs.vue:
- Around line 39-49: The computed searchedWidgetsSectionDataList is created once
from widgetsSectionDataList.value so it becomes stale when the underlying
nodes/props change; add a Vue watcher (also import watch) that watches
widgetsSectionDataList (or the nodes prop/source) and updates
searchedWidgetsSectionDataList.value = widgetsSectionDataList.value whenever the
source changes (but only when not actively searching if desired), so the UI
stays in sync; ensure the watcher uses the same shallowRef
(searchedWidgetsSectionDataList) and does not overwrite during active searches
triggered by the searcher function.
- Around line 51-58: The computed const label currently declares a local
variable named nodes which shadows the nodes prop (different type); rename the
local variable (e.g., sectionWidgets or widgetsSection) and update its usages
inside the computed to use that new name so the nodes prop remains
unshadowed—specifically modify the computed label that references
widgetsSectionDataList.value, change const nodes = ... to const sectionWidgets =
widgetsSectionDataList.value and replace subsequent references (nodes.length,
nodes[0].widgets) accordingly.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34eeb37 and 8bbb44e.

📒 Files selected for processing (8)
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/stores/workspace/rightSidePanelStore.ts
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/stores/workspace/rightSidePanelStore.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/stores/workspace/rightSidePanelStore.ts
**/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores using the pattern *Store.ts

Files:

  • src/stores/workspace/rightSidePanelStore.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/stores/workspace/rightSidePanelStore.ts
🧠 Learnings (55)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/stores/workspace/rightSidePanelStore.ts
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/rightSidePanel/layout/SidePanelSearch.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-12-11T03:55:51.755Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:51.755Z
Learning: In Vue components under src/renderer/extensions/vueNodes (e.g., ImagePreview.vue and LGraphNode.vue), implement image gallery keyboard navigation so that it responds to the node's focus state rather than requiring focus inside the image preview wrapper. Achieve this by wiring keyEvent handling at the node focus level and injecting or propagating key events (arrow keys) to the gallery when the node is focused/selected. This improves accessibility and aligns navigation with node-level focus behavior.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use vue 3.5 style of default prop declaration

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-05T08:52:50.787Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/SectionWidgets.vue:41-49
Timestamp: 2025-12-05T08:52:50.787Z
Learning: In Vue 3.4+ SFCs with a build step, kebab-case prop shorthand (e.g., `:is-empty`) automatically resolves to the corresponding camelCase variable in scope (e.g., `isEmpty`). This is valid syntax combining same-name shorthand with automatic kebab-case-to-camelCase conversion and should not be flagged as an error.

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Write code that is expressive and self-documenting; avoid redundant comments and clean as you go

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/stores/workspace/rightSidePanelStore.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-30T22:22:38.162Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:38.162Z
Learning: In Pinia setup stores, when accessing reactive properties directly via `useStore().property` pattern (e.g., `useQueueUIStore().isOverlayExpanded`), Pinia automatically unwraps refs and returns the primitive value. The `.value` accessor is only needed when destructuring store properties or using `storeToRefs()`.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/components/rightSidePanel/layout/SidePanelSearch.vue
🔇 Additional comments (16)
src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue (1)

70-70: LGTM! Input width styling correctly applied.

The addition of w-full via the cn() utility ensures the search input properly fills the available horizontal space within its flex container parent. This change correctly follows the coding guidelines for class name composition.

src/components/rightSidePanel/subgraph/SubgraphEditor.vue (3)

3-3: LGTM: Store integration follows best practices.

The integration of searchQuery from rightSidePanelStore using storeToRefs is correct and aligns with the PR's goal of synchronizing search state across multiple panels.

Also applies to: 32-32, 38-39


251-260: LGTM: Empty search state handling.

The empty search results message is appropriately conditional and provides good user feedback when no results are found.


283-283: LGTM: Consistent styling updates.

The background color changes from bg-interface-panel-surface to bg-comfy-menu-bg maintain visual consistency across the subgraph widget items.

Also applies to: 315-315

src/components/rightSidePanel/parameters/TabSubgraphInputs.vue (1)

128-173: LGTM: Drag-and-drop implementation is well-guarded.

The setDraggableState function includes appropriate guards:

  • Mounted state check
  • Empty container check
  • Search state check

The applyNewItemsOrder implementation correctly updates the proxy widgets order and marks the canvas as dirty.

src/stores/workspace/rightSidePanelStore.ts (2)

22-26: LGTM: Settings store integration.

The migration of isOpen to use settingStore correctly persists the panel state across sessions. The computed getter/setter pattern is appropriate for two-way binding.


47-65: Verify setTimeout delay for scroll behavior.

The focusSection function uses a hardcoded 300ms setTimeout to ensure the panel is open before scrolling. This could be fragile:

  • Panel animations may vary in duration based on user settings or performance
  • No guarantee the DOM element exists after 300ms
  • Lacks error handling if the element is not found

Consider using nextTick with a short polling mechanism or checking for the element's presence before scrolling:

function focusSection(section: RightSidePanelSection) {
  openPanel('parameters')
  focusedSection.value = section

  nextTick(() => {
    const checkElement = (attempts = 0) => {
      const sectionElement = document.querySelector(`[data-section="${section}"]`)
      if (sectionElement) {
        sectionElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
      } else if (attempts < 10) {
        setTimeout(() => checkElement(attempts + 1), 50)
      }
    }
    checkElement()
  })
}

Alternatively, verify that 300ms is sufficient across different scenarios (slow devices, animations disabled, etc.).

src/components/rightSidePanel/layout/SidePanelSearch.vue (3)

19-21: LGTM: Improved debounce configuration.

Increasing the debounce delay from 100ms to 250ms with a 1000ms maxWait reduces search frequency and improves performance, especially for large datasets. This aligns with common UX patterns for search inputs.


48-51: LGTM: Auto-select text on focus.

The handleFocus function that auto-selects the input text is a good UX improvement, allowing users to quickly replace the search query.


82-88: LGTM: Clear button addition.

The clear button with conditional rendering (v-if="searchQuery.trim().length > 0") provides a convenient way to reset the search. The implementation follows accessible patterns with proper button semantics.

src/components/rightSidePanel/parameters/TabNodes.vue (3)

20-31: LGTM: Widget filtering logic.

The widgetsSectionDataList computed property correctly filters out canvasOnly and hidden widgets, ensuring only user-editable widgets are displayed. The mapping to { node, widget } tuples maintains proper node context.


33-42: LGTM: Clean search implementation.

The searcher function correctly:

  • Updates isSearching state based on query presence
  • Uses shallowRef for performance with large lists
  • Delegates to the shared searchWidgetsAndNodes utility

This implementation is cleaner than the one in TabSubgraphInputs.vue as it doesn't mutate props.


53-69: LGTM: TransitionGroup usage for smooth animations.

The TransitionGroup with name="list-scale" provides smooth enter/leave animations for the filtered results. The empty state message and per-node SectionWidgets rendering are appropriate.

src/components/rightSidePanel/parameters/TabNormalInputs.vue (1)

61-90: LGTM on template structure.

Good use of TransitionGroup with proper keying, i18n for user-facing strings, and conditional empty-state messaging.

src/components/rightSidePanel/parameters/TabGlobalParameters.vue (2)

104-110: LGTM on lifecycle management.

Proper cleanup with draggableList.value?.dispose() in onBeforeUnmount prevents memory leaks.


113-142: LGTM on template structure.

Clean implementation with proper slot usage for empty state, i18n strings, and reactive binding of isDraggable based on search state.

Comment on lines +44 to +56
// Use customRef to track proxyWidgets changes
const proxyWidgets = customRef<ProxyWidgetsProperty>((track, trigger) => ({
get() {
track()
return parseProxyWidgets(node.properties.proxyWidgets)
},
set(value?: ProxyWidgetsProperty) {
trigger()
if (!value) return
// eslint-disable-next-line vue/no-mutating-props
node.properties.proxyWidgets = value
}
}))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix direct prop mutation in customRef.

The proxyWidgets customRef directly mutates node.properties.proxyWidgets (line 54), which violates Vue's one-way data flow principle. While an ESLint disable comment acknowledges this, direct prop mutations can cause:

  • Unpredictable state updates across parent/child components
  • Debugging difficulties when tracking data changes
  • Potential reactivity issues
Recommended approach

Emit an event to the parent component to update the property:

-const proxyWidgets = customRef<ProxyWidgetsProperty>((track, trigger) => ({
-  get() {
-    track()
-    return parseProxyWidgets(node.properties.proxyWidgets)
-  },
-  set(value?: ProxyWidgetsProperty) {
-    trigger()
-    if (!value) return
-    // eslint-disable-next-line vue/no-mutating-props
-    node.properties.proxyWidgets = value
-  }
-}))
+const proxyWidgets = computed({
+  get() {
+    return parseProxyWidgets(node.properties.proxyWidgets)
+  },
+  set(value?: ProxyWidgetsProperty) {
+    if (!value) return
+    emit('update:proxyWidgets', value)
+  }
+})

Then handle the update in the parent component (RightSidePanel.vue).

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/layout/PropertiesAccordionItem.vue:
- Around line 76-78: The empty-state div in PropertiesAccordionItem.vue
currently has no styling; update the empty-state markup that renders {{
$t('g.empty') }} to include Tailwind utility classes (e.g., padding like px-4
py-2 or pb-4 to match surrounding layout, text color such as text-gray-500,
text-sm for sizing, and center/left alignment like text-center or text-left) so
it visually matches the component’s existing spacing (see surrounding uses of
pb-4 and pl-4 pr-3) — modify the element that contains {{ $t('g.empty') }} to
add these classes.
- Around line 19-25: The file redundantly sets isCollapse from
props.defaultCollapse and also watches it, causing type-safety and UX issues;
either treat defaultCollapse as initial-only or make the component fully
controlled. If defaultCollapse is only an initializer: remove the watcher,
initialize isCollapse to a boolean using the prop (e.g., set isCollapse =
!!props.defaultCollapse) and keep the click handler to allow user toggles. If it
must follow the parent: keep a single watch on () => props.defaultCollapse with
{ immediate: true } and guard the value (assign isCollapse = value ?? false) or
only assign when typeof value === "boolean", and document/implement a controlled
pattern (emit update or use v-model) so parent-driven changes intentionally
override user toggles.

In @src/components/rightSidePanel/parameters/TabSubgraphInputs.vue:
- Line 129: The check uses the Ref returned by useMounted() directly (isMounted)
instead of its boolean value; update the conditional to read isMounted.value so
the mounted state is actually evaluated (i.e., change the guard in the
TabSubgraphInputs.vue setup/logic that currently reads "if (!isMounted) return"
to use "if (!isMounted.value) return").

In
@src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue:
- Around line 152-167: The customSearcher function currently lets rejections
from props.searcher fail silently; wrap the await props.searcher(...) call in a
try/catch (or append a .catch) and handle errors by logging (or forwarding to a
provided error handler) and ensuring filteredItems.value is left in a safe
state; keep the existing onCleanup/cleanupFn/isCleanup logic intact so cleanup
still invokes cleanupFn and prevents stale updates to filteredItems.value on
error.

In
@src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue:
- Around line 95-101: The clear button for the search (the <button> that toggles
on v-if="searchQuery.trim().length > 0") needs an accessible label and the
unnecessary cn() wrapper should be removed: add an aria-label like
aria-label="Clear search" to that <button> and replace the <i
:class="cn('icon-[lucide--delete] size-4 cursor-pointer')" /> with a plain
static class attribute (e.g. <i class="icon-[lucide--delete] size-4
cursor-pointer" />) to simplify the markup.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bbb44e and 17808d6.

📒 Files selected for processing (10)
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
🧠 Learnings (55)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/TabGlobalParameters.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabNodes.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-12-11T03:55:51.755Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:51.755Z
Learning: In Vue components under src/renderer/extensions/vueNodes (e.g., ImagePreview.vue and LGraphNode.vue), implement image gallery keyboard navigation so that it responds to the node's focus state rather than requiring focus inside the image preview wrapper. Achieve this by wiring keyEvent handling at the node focus level and injecting or propagating key events (arrow keys) to the gallery when the node is focused/selected. This improves accessibility and aligns navigation with node-level focus behavior.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use vue 3.5 style of default prop declaration

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-05T08:52:50.787Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/SectionWidgets.vue:41-49
Timestamp: 2025-12-05T08:52:50.787Z
Learning: In Vue 3.4+ SFCs with a build step, kebab-case prop shorthand (e.g., `:is-empty`) automatically resolves to the corresponding camelCase variable in scope (e.g., `isEmpty`). This is valid syntax combining same-name shorthand with automatic kebab-case-to-camelCase conversion and should not be flagged as an error.

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/TabNormalInputs.vue
  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement proper props and emits definitions

Applied to files:

  • src/components/rightSidePanel/parameters/TabSubgraphInputs.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles in Vue components

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement cleanup for async operations in Vue components

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
📚 Learning: 2025-12-30T22:22:38.162Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:38.162Z
Learning: In Pinia setup stores, when accessing reactive properties directly via `useStore().property` pattern (e.g., `useQueueUIStore().isOverlayExpanded`), Pinia automatically unwraps refs and returns the primitive value. The `.value` accessor is only needed when destructuring store properties or using `storeToRefs()`.

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
🔇 Additional comments (11)
src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vue (2)

10-16: LGTM: Cleaner search abstraction.

The replacement of isQuerying with an optional searcher callback is a better abstraction that enables pluggable async search behavior while maintaining backward compatibility.


53-63: LGTM: FormSearchInput integration.

The FormSearchInput component is correctly integrated with v-model binding and the searcher prop is properly passed through. The styling uses the cn() utility correctly for class merging.

src/components/rightSidePanel/subgraph/SubgraphEditor.vue (3)

246-246: LGTM: Consistent border and background styling.

The border changes from border-t to border-b and the addition of bg-comfy-menu-bg to widget items improve visual consistency across sections.

Also applies to: 264-264, 283-283, 296-296, 315-315, 325-325


251-260: The i18n key rightSidePanel.noneSearchDesc is defined in src/locales/en/main.json (line 2491) with the value "No items match your search". The empty state UI is correctly implemented.


3-3: Shared searchQuery state is intentional and correctly implemented.

The searchQuery is intentionally shared across all right-side panel components (SubgraphEditor, TabSubgraphInputs, TabNormalInputs, TabNodes, TabGlobalParameters) using Pinia's store. The persistence of the search query when switching between tabs or subgraph editors is by design—it provides consistent filtering state across the entire panel. Using storeToRefs correctly preserves reactivity for the ref-based state. This follows proper Pinia patterns and requires no changes.

src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue (1)

208-208: LGTM: Searcher prop binding.

The change from :is-querying to :searcher="customSearcher" correctly passes the function reference to FormDropdownMenu.

src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue (1)

15-24: LGTM: Consistent prop changes.

The removal of isQuerying and addition of the optional searcher prop is consistent with the changes in FormDropdownMenuActions.vue. The prop is correctly passed through.

Also applies to: 56-56

src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue (4)

8-21: LGTM: Vue 3.5 style prop declaration.

The props are correctly declared using Vue 3.5 reactive props destructuring with defaults, which aligns with coding guidelines. The class prop aliased as customClass is a clear pattern.


26-28: Verify debounce timing change is intentional.

The debounce delay increased from 100ms to 250ms, and maxWait from 100ms to 1000ms. This will reduce search query frequency but may feel slightly less responsive. Confirm this change was intentional and has been tested with users.


55-58: LGTM: Select-all on focus.

The handleFocus handler that selects all text on focus is a good UX pattern for search inputs.


62-94: LGTM: Enhanced styling and autofocus.

The template updates correctly integrate the customClass prop using cn(), add group-based hover/focus styling, and bind the autofocus prop. The icon color transitions based on query state provide good visual feedback.

Comment on lines +76 to +78
<div>
{{ $t('g.empty') }}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add styling to the empty state.

The default empty state (lines 76-78) renders a plain <div> with no Tailwind classes for padding, text color, or alignment. This looks inconsistent with the rest of the component, which uses proper spacing (e.g., pb-4 on line 72, pl-4 pr-3 on line 47).

♻️ Suggested styling for consistency
-      <slot v-else-if="enableEmptyState && isEmpty" name="empty">
-        <div>
-          {{ $t('g.empty') }}
-        </div>
-      </slot>
+      <slot v-else-if="enableEmptyState && isEmpty" name="empty">
+        <div class="px-4 py-2 text-sm text-muted-foreground">
+          {{ $t('g.empty') }}
+        </div>
+      </slot>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div>
{{ $t('g.empty') }}
</div>
<slot v-else-if="enableEmptyState && isEmpty" name="empty">
<div class="px-4 py-2 text-sm text-muted-foreground">
{{ $t('g.empty') }}
</div>
</slot>
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/layout/PropertiesAccordionItem.vue around
lines 76 - 78, The empty-state div in PropertiesAccordionItem.vue currently has
no styling; update the empty-state markup that renders {{ $t('g.empty') }} to
include Tailwind utility classes (e.g., padding like px-4 py-2 or pb-4 to match
surrounding layout, text color such as text-gray-500, text-sm for sizing, and
center/left alignment like text-center or text-left) so it visually matches the
component’s existing spacing (see surrounding uses of pb-4 and pl-4 pr-3) —
modify the element that contains {{ $t('g.empty') }} to add these classes.

Comment on lines +152 to +167
async function customSearcher(
query: string,
onCleanup: (cleanupFn: () => void) => void
) {
let isCleanup = false
let cleanupFn: undefined | (() => void)
onCleanup(() => {
isCleanup = true
cleanupFn?.()
})
await props
.searcher(query, props.items, (cb) => (cleanupFn = cb))
.then((results) => {
if (!isCleanup) filteredItems.value = results
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add error handling for searcher failures.

The customSearcher function doesn't handle errors from props.searcher. If the searcher promise rejects, it will fail silently. Consider adding error handling:

♻️ Add error handling
 async function customSearcher(
   query: string,
   onCleanup: (cleanupFn: () => void) => void
 ) {
   let isCleanup = false
   let cleanupFn: undefined | (() => void)
   onCleanup(() => {
     isCleanup = true
     cleanupFn?.()
   })
-  await props
+  try {
+    await props
       .searcher(query, props.items, (cb) => (cleanupFn = cb))
       .then((results) => {
         if (!isCleanup) filteredItems.value = results
       })
+  } catch (error) {
+    console.error('[FormDropdown] searcher failed:', error)
+  }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function customSearcher(
query: string,
onCleanup: (cleanupFn: () => void) => void
) {
let isCleanup = false
let cleanupFn: undefined | (() => void)
onCleanup(() => {
isCleanup = true
cleanupFn?.()
})
await props
.searcher(query, props.items, (cb) => (cleanupFn = cb))
.then((results) => {
if (!isCleanup) filteredItems.value = results
})
}
async function customSearcher(
query: string,
onCleanup: (cleanupFn: () => void) => void
) {
let isCleanup = false
let cleanupFn: undefined | (() => void)
onCleanup(() => {
isCleanup = true
cleanupFn?.()
})
try {
await props
.searcher(query, props.items, (cb) => (cleanupFn = cb))
.then((results) => {
if (!isCleanup) filteredItems.value = results
})
} catch (error) {
console.error('[FormDropdown] searcher failed:', error)
}
}
🤖 Prompt for AI Agents
In
@src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
around lines 152 - 167, The customSearcher function currently lets rejections
from props.searcher fail silently; wrap the await props.searcher(...) call in a
try/catch (or append a .catch) and handle errors by logging (or forwarding to a
provided error handler) and ensuring filteredItems.value is left in a safe
state; keep the existing onCleanup/cleanupFn/isCleanup logic intact so cleanup
still invokes cleanupFn and prevents stale updates to filteredItems.value on
error.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Around line 110-116: Remove the `!` important prefix on the Tailwind class in
the WidgetItem component: replace `!will-change-auto` with `will-change-auto`
inside the class string used in the template (look for the isDraggable block
that builds the classes with cn and the 'draggable-item'/'drag-handle' tokens).
Then search for and remove any interfering `!important` declarations or
overly-specific CSS targeting `.draggable-item`, `.is-draggable`, or related
selectors (or adjust their specificity/order) that force a different will-change
value so the plain `will-change-auto` takes effect without using `!`.
- Around line 42-43: The widget is being proxied with shallowRef + watchEffect
which duplicates computed; inspect whether external code mutates theWidget
without Vue reactivity (search for triggerRef() calls on this widget at the
triggerRef locations) — if theWidget is reactive/immutable replace the
shallowRef/watchEffect pair with const widget = computed(() => theWidget); if
external non-reactive mutations occur and you need manual update keep the
shallowRef pattern but add a concise comment above the declaration explaining
why shallow reactivity and manual triggerRef() calls are required for
performance/controlled updates.
- Around line 177-185: Remove the Tailwind important prefix by replacing
'!opacity-0' with a regular conditional class (e.g., isDraggable ? '' :
'opacity-0') in the cn call inside the WidgetItem.vue template; do not
reintroduce '!'; if opacity is still overridden, locate and remove the offending
'!important' in your global/component CSS instead of forcing the utility—check
usages related to isDraggable, the cn helper, and any custom CSS that sets
opacity for this widget and fix that source of higher specificity.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17808d6 and 7d2c3af.

📒 Files selected for processing (1)
  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
🧠 Learnings (23)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `useModel` over separately defining prop and emit for two-way binding

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use `!important` or the `!` important prefix for Tailwind classes; find and correct interfering `!important` classes instead

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T20:39:30.137Z
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Do not use the `dark:` Tailwind variant; use semantic values from the `style.css` theme instead (e.g., `bg-node-component-surface`)

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T17:30:29.719Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7559
File: .storybook/preview.ts:61-61
Timestamp: 2025-12-16T17:30:29.719Z
Learning: In .storybook/preview.ts for the Comfy-Org/ComfyUI_frontend repository, using `document.body.classList.add('[&_*]:!font-inter')` is the correct approach for applying the Inter font to all Storybook story elements. The simpler `font-inter` class alone does not work in this context. This runtime arbitrary variant pattern is valid and should not be flagged as an issue.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Tailwind 4 for styling in Vue components; avoid `<style>` blocks

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/parameters/WidgetItem.vue

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/rightSidePanel/RightSidePanel.vue (1)

293-305: Icon-only Subgraph toggle button needs an aria-label.

This is an icon-only control, so it needs a localized accessible name (and optionally :aria-pressed if it’s a toggle).

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/RightSidePanel.vue:
- Around line 345-363: The template uses a non-null/type assertion on
selectedSingleNode and may pass the wrong type to TabSettings; create a computed
selectedSubgraphNode that narrows selectedSingleNode to SubgraphNode | null and
replace the inline assertion by rendering TabSubgraphInputs only when
selectedSubgraphNode is truthy (also update SubgraphEditor usage to rely on the
same computed), and verify TabSettings' prop contract: ensure TabSettings
expects MixedSelectionItem[] (not LGraphNode[]); if it expects
MixedSelectionItem[], map flattedItems to MixedSelectionItem[] before passing,
otherwise update TabSettings' prop type to accept LGraphNode[] as needed.
- Around line 156-173: The computed panelTitle currently uses hardcoded
fallbacks 'Group' and 'Node'; update the panelTitle computed to replace those
literals with i18n lookups (e.g., use t('rightSidePanel.fallbackGroupTitle') for
the group fallback and t('rightSidePanel.fallbackNodeTitle') for the node
fallback) and add corresponding keys in src/locales/en/main.json; keep the
existing logic (flattedItems, selectedNodes, selectedGroups,
directlySelectedItems) intact but ensure all user-facing strings go through
t(...).
- Around line 95-132: The injected getter (provide(GetNodeParentGroupKey)) calls
findParentGroupInGraph(node) which does an O(groups) scan per lookup; memoize
these lookups by adding a WeakMap<LGraphNode, LGraphGroup | null> (e.g.,
parentCache) and return cached results before calling findParentGroupInGraph;
invalidate/clear parentCache whenever the workflow/graph changes (watch
canvasStore.canvas?.graph or relevant workflow ref). Also type graphGroups as
LGraphGroup[] when reading canvasStore.canvas?.graph?.groups to avoid repeated
casting, and keep using nodeToParentGroup for explicit mappings before
consulting the cache and fallback to findParentGroupInGraph.
- Around line 88-98: The gating logic for selection is duplicated: keep
shouldShowGroupNames as the source of truth and make allowTitleEdit computed as
the inverse (allowTitleEdit = computed(() => !shouldShowGroupNames.value))
instead of re-encoding the same condition; update any places that currently
recompute the selection check (e.g., the provide(GetNodeParentGroupKey, ...)
early-return and the similar block at lines 234-239) to reference
shouldShowGroupNames.value (or allowTitleEdit.value where semantically clearer)
so the condition is centralized and cannot drift.
- Around line 270-286: The pencil <i> icon is not keyboard accessible; replace
that element with the project's Button component (size="icon") so it is
focusable and operable via keyboard, using an i18n aria-label (e.g.
aria-label="$t('editTitle')") and preserving the visibility condition
(v-if="!isEditing") and click behavior (@click="isEditing = true"); ensure you
keep the surrounding EditableText usage and existing handlers (panelTitle,
isEditing, handleTitleEdit, handleTitleCancel) unchanged so only the icon
element is swapped for an accessible icon-only Button.
- Around line 150-154: The computed rootLevelNodes currently reads the private
_nodes and uses a void workflowStore.activeWorkflow?.path hack; change it to
depend explicitly on activeWorkflow via storeToRefs(workflowStore) and use the
public LGraph nodes getter instead of _nodes: call storeToRefs(workflowStore) to
get activeWorkflow, reference activeWorkflow.value inside the computed to
establish the dependency, and return canvasStore.canvas?.graph?.nodes (adjust or
narrow the return type if nodes may include SubgraphNode instances) so you stop
accessing the private _nodes field.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d2c3af and 11f3a72.

📒 Files selected for processing (1)
  • src/components/rightSidePanel/RightSidePanel.vue
🧰 Additional context used
📓 Path-based instructions (9)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

src/**/*.vue: Use Vue 3 Single File Components (SFCs) with Composition API only; never use Options API
Use <script setup lang="ts"> syntax for component logic
Use Tailwind 4 utility classes for styling; avoid <style> blocks in Vue components
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use cn() utility from @/utils/tailwindUtil for merging class names; never use :class="[]" syntax
Never use !important or the ! prefix for Tailwind classes; find and fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentages (e.g., w-4/5 instead of w-[80%], w-1/2 instead of w-[50%])
Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoid withDefaults and runtime props
Use defineModel for v-model bindings instead of separately defining props and emits
Prefer reactive props destructuring over const props = defineProps<...>
Define slots via template usage, not defineSlots
Use same-name shorthand for slot prop bindings (e.g., :isExpanded instead of :is-expanded="isExpanded")
Use ref for reactive state, computed() for computed properties, and watch/watchEffect for side effects
Avoid using ref and watch t...

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Leverage VueUse functions for performance-enhancing utilities

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Use separate import type statements; do not mix inline type imports in the same statement
Sort and group imports by plugin; run pnpm format before committing
Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Code should be well-designed with clear names for everything; write code that is expressive and self-documenting
Avoid redundant comments and clean up code as you go; comments should explain why, not what
Ask if there is a simpler way to implement functionality; refactor complex code to simplify it
Minimize nesting depth (e.g., if () { ... } or for () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never use any type; use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Indent with 2 spaces; use single quotes; no trailing semicolons; max line width 80 (per .prettierrc)
Complex type definitions used in multiple related places should be extracted and named for reuse
Implement proper error handling

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
🧠 Learnings (39)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid redundant comments and clean up code as you go; comments should explain why, not what

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-06T02:11:00.385Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/RightSidePanel.vue:174-180
Timestamp: 2025-12-06T02:11:00.385Z
Learning: PrimeVue components have poor TypeScript typing, so type assertions (like `as RightSidePanelTab`) may be necessary when handling emitted events or prop values from PrimeVue components like TabList.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Be judicious with state additions: prefer props, avoid `computed` for simple values, use `computed` instead of `watch` for derived values

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Ask if there is a simpler way to implement functionality; refactor complex code to simplify it

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Avoid using `ref` and `watch` together if a `computed` would work instead

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use `ref` for reactive state, `computed()` for computed properties, and `watch`/`watchEffect` for side effects

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Watch out for code smells and refactor to avoid them

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Minimize nesting depth (e.g., `if () { ... }` or `for () { ... }`); watch for arrow anti-pattern

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{ts,tsx} : Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files at src/**/*.test.ts, when creating mock objects that partially implement an interface (e.g., LGraphNode), use `as Partial<InterfaceType> as InterfaceType` instead of `as any` or `as unknown as InterfaceType` to explicitly acknowledge the incomplete implementation while maintaining type safety.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use `<script setup lang="ts">` syntax for component logic

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-30T22:22:38.162Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:38.162Z
Learning: In Pinia setup stores, when accessing reactive properties directly via `useStore().property` pattern (e.g., `useQueueUIStore().isOverlayExpanded`), Pinia automatically unwraps refs and returns the primitive value. The `.value` accessor is only needed when destructuring store properties or using `storeToRefs()`.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
🔇 Additional comments (2)
src/components/rightSidePanel/RightSidePanel.vue (2)

184-230: Tab construction + activeTab normalization look consistent with the new model.

The “parameters tab labeled as nodes when multi-selected” is a bit semantically odd but seems intentional per PR description; the activeTab validity guard (including subgraph special-case) looks safe.


59-87: No changes needed. The code correctly uses watch() without deep: true because canvasStore.selectedItems is updated via array replacement (not in-place mutation), which Vue's reactivity system detects and triggers the watcher. Additionally, "flattedItems" is the correct naming—the past participle form derived from the function flatAndCategorizeSelectedItems. The triggerRef() calls are defensive but unnecessary given the array replacement pattern.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/layout/PropertiesAccordionItem.vue:
- Around line 75-79: The empty-state slot rendering for enableEmptyState &&
isEmpty returns an unstyled div; update the template in
PropertiesAccordionItem.vue (the <slot name="empty"> branch) to apply the same
pb-4 padding as the main content plus centered text and a muted/secondary text
color (e.g., add classes for padding, text-center and muted/secondary text) so
the empty message ($t('g.empty')) visually matches the surrounding layout and
spacing.
- Around line 19-25: The prop props.defaultCollapse is being treated as a
continuously-synced source of truth by the watch(( ) => props.defaultCollapse,
...) which overrides user toggles; to fix, remove the watch and only initialize
isCollapse.value from props.defaultCollapse (keep the initial if block) so user
interactions persist, or if you intend parent-driven control rename the prop to
collapse and implement explicit parent binding instead of a "default" prop;
update references to props.defaultCollapse and the watch function accordingly.

In @src/components/rightSidePanel/parameters/SectionWidgets.vue:
- Around line 73-94: The comparisons of node IDs in isWidgetShownOnParents use
loose equality (==) which can mask type mismatches; change both
occurrences—widget._overlay.nodeId == nodeId and widgetNode.id == nodeId—to
strict equality (===) in isWidgetShownOnParents, or if IDs may legitimately be
different types, normalize types first (e.g., String(...) or Number(...)) before
comparing to ensure deterministic behavior.
- Around line 189-204: The template shadows the component-level prop named
"node" by destructuring "node" in the v-for; rename the loop variable to
something like "itemNode" (update the v-for destructure, the :key, the :node
prop passed to <WidgetItem>, and the call to isWidgetShownOnParents(node,
widget) to isWidgetShownOnParents(itemNode, widget)) so the prop and loop
variable are unambiguous throughout SectionWidgets.vue while leaving event
bindings (@value-change, @widget-update) and other attributes unchanged.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11f3a72 and e00be30.

📒 Files selected for processing (2)
  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
🧰 Additional context used
📓 Path-based instructions (9)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

src/**/*.vue: Use Vue 3 Single File Components (SFCs) with Composition API only; never use Options API
Use <script setup lang="ts"> syntax for component logic
Use Tailwind 4 utility classes for styling; avoid <style> blocks in Vue components
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use cn() utility from @/utils/tailwindUtil for merging class names; never use :class="[]" syntax
Never use !important or the ! prefix for Tailwind classes; find and fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentages (e.g., w-4/5 instead of w-[80%], w-1/2 instead of w-[50%])
Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoid withDefaults and runtime props
Use defineModel for v-model bindings instead of separately defining props and emits
Prefer reactive props destructuring over const props = defineProps<...>
Define slots via template usage, not defineSlots
Use same-name shorthand for slot prop bindings (e.g., :isExpanded instead of :is-expanded="isExpanded")
Use ref for reactive state, computed() for computed properties, and watch/watchEffect for side effects
Avoid using ref and watch t...

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Leverage VueUse functions for performance-enhancing utilities

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Use separate import type statements; do not mix inline type imports in the same statement
Sort and group imports by plugin; run pnpm format before committing
Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Code should be well-designed with clear names for everything; write code that is expressive and self-documenting
Avoid redundant comments and clean up code as you go; comments should explain why, not what
Ask if there is a simpler way to implement functionality; refactor complex code to simplify it
Minimize nesting depth (e.g., if () { ... } or for () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never use any type; use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Indent with 2 spaces; use single quotes; no trailing semicolons; max line width 80 (per .prettierrc)
Complex type definitions used in multiple related places should be extracted and named for reuse
Implement proper error handling

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
🧠 Learnings (37)
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoid `withDefaults` and runtime props

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use vue 3.5 style of default prop declaration

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Be judicious with state additions: prefer props, avoid `computed` for simple values, use `computed` instead of `watch` for derived values

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Implement proper props and emits definitions in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Avoid using `ref` and `watch` together if a `computed` would work instead

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Watch out for code smells and refactor to avoid them

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use `ref` for reactive state, `computed()` for computed properties, and `watch`/`watchEffect` for side effects

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Prefer reactive props destructuring over `const props = defineProps<...>`

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Minimize nesting depth (e.g., `if () { ... }` or `for () { ... }`); watch for arrow anti-pattern

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-05T08:52:50.787Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/SectionWidgets.vue:41-49
Timestamp: 2025-12-05T08:52:50.787Z
Learning: In Vue 3.4+ SFCs with a build step, kebab-case prop shorthand (e.g., `:is-empty`) automatically resolves to the corresponding camelCase variable in scope (e.g., `isEmpty`). This is valid syntax combining same-name shorthand with automatic kebab-case-to-camelCase conversion and should not be flagged as an error.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use Tailwind 4 utility classes for styling; avoid `<style>` blocks in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-01T23:42:30.894Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7084
File: src/renderer/extensions/vueNodes/components/SlotConnectionDot.vue:23-26
Timestamp: 2025-12-01T23:42:30.894Z
Learning: In the ComfyUI frontend codebase, Tailwind CSS is configured with Preflight enabled (default), which automatically provides `content: ''` for pseudo-elements when using `after:` or `before:` variants - no need to explicitly add `after:content-['']`.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/rightSidePanel/layout/PropertiesAccordionItem.vue
  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use watch and watchEffect for side effects

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files at src/**/*.test.ts, when creating mock objects that partially implement an interface (e.g., LGraphNode), use `as Partial<InterfaceType> as InterfaceType` instead of `as any` or `as unknown as InterfaceType` to explicitly acknowledge the incomplete implementation while maintaining type safety.

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing utilities

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/rightSidePanel/parameters/SectionWidgets.vue
🔇 Additional comments (7)
src/components/rightSidePanel/parameters/SectionWidgets.vue (5)

28-57: LGTM!

Props are correctly defined using Vue 3.5 style destructuring with proper TypeScript types and inline defaults.


59-71: LGTM!

The use of shallowRef with watchEffect for syncing widgets is appropriate here since triggerRef is used later to manually trigger reactivity updates in onWidgetUpdate. This pattern correctly enables both prop synchronization and manual reactivity control.


96-107: LGTM!

Event handlers are concise and correctly implemented. The onWidgetUpdate function properly uses triggerRef to manually trigger reactivity updates on the shallow ref.


109-141: LGTM!

The computed properties are well-structured with proper null checks. The targetNode computed correctly handles the empty case before accessing array elements. The handleLocateNode function uses appropriate defensive programming with early returns.


143-145: LGTM!

Exposing widgetsContainer via defineExpose is appropriate for imperative DOM operations like drag-and-drop coordination (as indicated by the isDraggable prop).

src/components/rightSidePanel/layout/PropertiesAccordionItem.vue (2)

27-27: LGTM: Computed property correctly derives expansion state.

Good use of computed to derive isExpanded from isCollapse and isEmpty. The logic correctly ensures content is only shown when not collapsed and not empty.


31-70: LGTM: Template structure and styling updated correctly.

The changes look good:

  • Background class updated to bg-comfy-menu-bg (semantic token)
  • Tooltip logic properly uses i18n with fallback
  • Label slot pattern with flex-1 provides good layout flexibility
  • Chevron icon transitions correctly with collapse state
  • Proper disabled state and accessibility

Comment on lines +75 to +79
<slot v-else-if="enableEmptyState && isEmpty" name="empty">
<div>
{{ $t('g.empty') }}
</div>
</slot>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add styling to the empty state for visual consistency.

The empty state fallback (lines 76-78) lacks styling, while the main content above has pb-4 padding. Consider adding padding, text alignment, and color for visual consistency.

♻️ Proposed styling improvement
-      <slot v-else-if="enableEmptyState && isEmpty" name="empty">
-        <div>
-          {{ $t('g.empty') }}
-        </div>
-      </slot>
+      <slot v-else-if="enableEmptyState && isEmpty" name="empty">
+        <div class="pb-4 px-4 text-sm text-muted-foreground">
+          {{ $t('g.empty') }}
+        </div>
+      </slot>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<slot v-else-if="enableEmptyState && isEmpty" name="empty">
<div>
{{ $t('g.empty') }}
</div>
</slot>
<slot v-else-if="enableEmptyState && isEmpty" name="empty">
<div class="pb-4 px-4 text-sm text-muted-foreground">
{{ $t('g.empty') }}
</div>
</slot>
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/layout/PropertiesAccordionItem.vue around
lines 75 - 79, The empty-state slot rendering for enableEmptyState && isEmpty
returns an unstyled div; update the template in PropertiesAccordionItem.vue (the
<slot name="empty"> branch) to apply the same pb-4 padding as the main content
plus centered text and a muted/secondary text color (e.g., add classes for
padding, text-center and muted/secondary text) so the empty message
($t('g.empty')) visually matches the surrounding layout and spacing.

Comment on lines +73 to 94
function isWidgetShownOnParents(
widgetNode: LGraphNode,
widget: IBaseWidget
): boolean {
if (!parents.length) return false
const proxyWidgets = parseProxyWidgets(parents[0].properties.proxyWidgets)
// For proxy widgets (already promoted), check using overlay information
if (isProxyWidget(widget)) {
return proxyWidgets.some(
([nodeId, widgetName]) =>
widget._overlay.nodeId == nodeId &&
widget._overlay.widgetName === widgetName
)
}
// For regular widgets (not yet promoted), check using node ID and widget name
return proxyWidgets.some(
([nodeId, widgetName]) =>
widgetNode.id == nodeId && widget.name === widgetName
)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider using strict equality for ID comparisons.

Lines 84 and 92 use loose equality (==) for comparing node IDs. If the types can differ (string vs number), this is intentional; otherwise, prefer strict equality (===) for type safety and consistency.

♻️ Suggested change
-      widget._overlay.nodeId == nodeId &&
+      widget._overlay.nodeId === nodeId &&
-      widgetNode.id == nodeId && widget.name === widgetName
+      widgetNode.id === nodeId && widget.name === widgetName
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/SectionWidgets.vue around lines 73
- 94, The comparisons of node IDs in isWidgetShownOnParents use loose equality
(==) which can mask type mismatches; change both
occurrences—widget._overlay.nodeId == nodeId and widgetNode.id == nodeId—to
strict equality (===) in isWidgetShownOnParents, or if IDs may legitimately be
different types, normalize types first (e.g., String(...) or Number(...)) before
comparing to ensure deterministic behavior.

Comment on lines +189 to +204
<div ref="widgetsContainer" class="space-y-2 rounded-lg px-4 pt-1 relative">
<TransitionGroup name="list-scale">
<WidgetItem
v-for="{ widget, node } in widgets"
:key="`${node.id}-${widget.name}-${widget.type}`"
:widget="widget"
:model-value="useReactiveWidgetValue(widget)"
:node-id="String(node.id)"
:node-type="node.type"
:class="cn('col-span-1', shouldExpand(widget.type) && 'min-h-36')"
@update:model-value="
(value: string | number | boolean | object) =>
onWidgetValueChange(widget, value)
"
:node="node"
:is-draggable="isDraggable"
:hidden-favorite-indicator="hiddenFavoriteIndicator"
:show-node-name="showNodeName"
:parents="parents"
:is-shown-on-parents="isWidgetShownOnParents(node, widget)"
@value-change="onWidgetValueChange"
@widget-update="onWidgetUpdate"
/>
</div>
</TransitionGroup>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Variable shadowing of node prop in v-for loop.

The node destructured in the v-for (line 192) shadows the node prop from line 30/44. This is likely intentional since you want to pass each widget's associated node to WidgetItem, but consider renaming to itemNode or similar to improve clarity and avoid accidental confusion when reading the template.

♻️ Suggested change for clarity
-        <WidgetItem
-          v-for="{ widget, node } in widgets"
-          :key="`${node.id}-${widget.name}-${widget.type}`"
+        <WidgetItem
+          v-for="{ widget, node: itemNode } in widgets"
+          :key="`${itemNode.id}-${widget.name}-${widget.type}`"
           :widget="widget"
-          :node="node"
+          :node="itemNode"
           :is-draggable="isDraggable"
           :hidden-favorite-indicator="hiddenFavoriteIndicator"
           :show-node-name="showNodeName"
           :parents="parents"
-          :is-shown-on-parents="isWidgetShownOnParents(node, widget)"
+          :is-shown-on-parents="isWidgetShownOnParents(itemNode, widget)"
           @value-change="onWidgetValueChange"
           @widget-update="onWidgetUpdate"
         />
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/SectionWidgets.vue around lines 189
- 204, The template shadows the component-level prop named "node" by
destructuring "node" in the v-for; rename the loop variable to something like
"itemNode" (update the v-for destructure, the :key, the :node prop passed to
<WidgetItem>, and the call to isWidgetShownOnParents(node, widget) to
isWidgetShownOnParents(itemNode, widget)) so the prop and loop variable are
unambiguous throughout SectionWidgets.vue while leaving event bindings
(@value-change, @widget-update) and other attributes unchanged.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🤖 Fix all issues with AI agents
In @src/components/rightSidePanel/parameters/TabSubgraphInputs.vue:
- Line 111: The comparison uses loose equality (interiorNode.id == nodeId) which
risks type-coercion bugs; update the predicate to use strict equality and make
any necessary explicit conversions (e.g., convert nodeId to Number or
interiorNode.id to String) so the condition becomes a strict comparison between
interiorNode.id and nodeId while keeping the existing widget.name === widgetName
check unchanged.
- Around line 45-56: The customRef proxyWidgets directly mutates
node.properties.proxyWidgets (violating Vue one-way data flow); replace the
customRef with a computed getter/setter that reads
parseProxyWidgets(node.properties.proxyWidgets) and emits an update event
instead of writing the prop directly (use defineEmits to declare
'update:proxyWidgets' and call emit('update:proxyWidgets', value) in the
setter), or dispatch the update to a central store action that performs the
mutation; ensure you remove the eslint-disable and let the parent or store apply
the actual change to node.properties.proxyWidgets.

In @src/components/rightSidePanel/parameters/WidgetItem.vue:
- Around line 42-43: The local widget ref uses shallowRef(theWidget) plus
watchEffect(() => (widget.value = theWidget)) to keep a mutable local reference
and triggerRef(widget) is used elsewhere when renameWidget mutates the object;
replace this with a short inline comment explaining why the shallowRef +
triggerRef pattern is required (i.e., to allow in-place mutation updates from
renameWidget) and keep the existing shallowRef and watchEffect lines untouched
so behavior remains the same while clarifying intent for future readers.

In @src/components/rightSidePanel/RightSidePanel.vue:
- Around line 151-155: Add an inline comment above the `void
workflowStore.activeWorkflow?.path` line in the `rootLevelNodes` computed getter
explaining that this is intentionally reading the workflow's `path` solely to
create a reactive dependency so the computed will recompute when
`workflowStore.activeWorkflow` changes; reference the symbols `rootLevelNodes`,
`workflowStore.activeWorkflow?.path`, and `canvasStore.canvas?.graph?.nodes` so
reviewers can find the code quickly and keep the explanation short and focused
on intent.
- Around line 284-288: The pencil icon (<i> element controlling isEditing) is
not keyboard accessible; make it focusable and respond to Enter/Space by adding
tabindex="0" and a keydown handler that sets isEditing = true when key is Enter
or Space, and also add role="button" and an appropriate aria-label (e.g.,
"Edit") so screen readers and keyboard users get the same behavior as the @click
handler.

In @src/components/rightSidePanel/settings/TabGlobalSettings.vue:
- Around line 2-3: The PR adds direct PrimeVue imports InputNumber and Select;
per guidelines avoid new PrimeVue components—replace uses of InputNumber and
Select with the project design-system equivalents (e.g., the standardized number
input and select components), remove the PrimeVue imports and update the
component registration and template references (where InputNumber and Select are
used) to the design-system component names, and ensure props/events are mapped
or adapted to match the design-system API so behavior remains the same; run the
component story or unit test to verify rendering.
- Around line 61-72: TheOldLinkRenderMode is declared at module scope and shared
across instances; move it into the component instance (inside setup) as a local
reactive/ref variable so each TabGlobalSettings has its own copy; update the
showConnectedLinks computed (the getter/setter that reads/writes
settingStore.get('Comfy.LinkRenderMode') and settingStore.set(...)) to reference
the instance-scoped theOldLinkRenderMode instead of the module-scoped one,
initializing it to LiteGraph.SPLINE_LINK (or the current stored value) so state
doesn't bleed between component instances.
- Line 26: The showAdvancedParameters ref is a non-functional placeholder but is
already bound to the UI switch; remove the misleading interactive behavior by
disabling the switch instead of leaving it bound—keep the showAdvancedParameters
symbol for future use but remove or stop using it as the v-model for the switch,
add the switch's disabled prop and a visual indicator (e.g., tooltip or small
"Coming soon" caption) so users see it is intentionally inactive; update the
component UI where the switch is referenced to reflect the disabled state and
ensure no UI actions rely on toggling showAdvancedParameters.

In @src/renderer/extensions/vueNodes/components/LGraphNode.vue:
- Around line 123-138: The button currently can act as a form submit because it
lacks an explicit type; add type="button" to the existing <button> (the element
rendered when showAdvancedInputsButton is true) so the click handled by
handleShowAdvancedInputs does not trigger form submission, and preserve its
class binding that uses WidgetInputBaseClass and the label from
t('rightSidePanel.showAdvancedInputsButton'); alternatively replace the raw
<button> with the repo’s shared button component (e.g., Button/IconButton) while
passing the same props, classes, icon (<i class="icon-[lucide--settings-2]">)
and @click.stop="handleShowAdvancedInputs" to maintain styling/behavior.

Comment on lines +45 to +56
const proxyWidgets = customRef<ProxyWidgetsProperty>((track, trigger) => ({
get() {
track()
return parseProxyWidgets(node.properties.proxyWidgets)
},
set(value?: ProxyWidgetsProperty) {
trigger()
if (!value) return
// eslint-disable-next-line vue/no-mutating-props
node.properties.proxyWidgets = value
}
}))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Direct prop mutation breaks Vue reactivity contracts.

The customRef directly mutates node.properties.proxyWidgets (line 54), which violates Vue's one-way data flow principle. While the eslint-disable comment acknowledges this, it doesn't address the underlying architectural issue. This pattern can cause:

  1. Unpredictable reactivity behavior
  2. Difficulty tracking state changes
  3. Potential race conditions with parent component updates
  4. Breaking Vue DevTools time-travel debugging

Consider emitting an event to the parent or using a store to manage subgraph proxy widget order:

const emit = defineEmits<{
  'update:proxyWidgets': [ProxyWidgetsProperty]
}>()

const proxyWidgets = computed({
  get: () => parseProxyWidgets(node.properties.proxyWidgets),
  set: (value) => {
    if (value) emit('update:proxyWidgets', value)
  }
})

Then handle the mutation in the parent component or a dedicated store that manages graph state.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/TabSubgraphInputs.vue around lines
45 - 56, The customRef proxyWidgets directly mutates
node.properties.proxyWidgets (violating Vue one-way data flow); replace the
customRef with a computed getter/setter that reads
parseProxyWidgets(node.properties.proxyWidgets) and emits an update event
instead of writing the prop directly (use defineEmits to declare
'update:proxyWidgets' and call emit('update:proxyWidgets', value) in the
setter), or dispatch the update to a central store action that performs the
mutation; ensure you remove the eslint-disable and let the parent or store apply
the actual change to node.properties.proxyWidgets.

return allInteriorWidgets.filter(({ node: interiorNode, widget }) => {
return !proxyWidgetsValue.some(
([nodeId, widgetName]) =>
interiorNode.id == nodeId && widget.name === widgetName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use strict equality comparison.

Line 111 uses loose equality (==) which can lead to unexpected type coercion. If interiorNode.id is a number and nodeId is a string, this might work accidentally but is fragile.

♻️ Use strict equality with explicit conversion
       return !proxyWidgetsValue.some(
-        ([nodeId, widgetName]) =>
-          interiorNode.id == nodeId && widget.name === widgetName
+        ([nodeId, widgetName]) =>
+          String(interiorNode.id) === nodeId && widget.name === widgetName
       )

This makes the type conversion explicit and uses strict equality throughout.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interiorNode.id == nodeId && widget.name === widgetName
return !proxyWidgetsValue.some(
([nodeId, widgetName]) =>
String(interiorNode.id) === nodeId && widget.name === widgetName
)
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/TabSubgraphInputs.vue at line 111,
The comparison uses loose equality (interiorNode.id == nodeId) which risks
type-coercion bugs; update the predicate to use strict equality and make any
necessary explicit conversions (e.g., convert nodeId to Number or
interiorNode.id to String) so the condition becomes a strict comparison between
interiorNode.id and nodeId while keeping the existing widget.name === widgetName
check unchanged.

Comment on lines +42 to +43
const widget = shallowRef(theWidget)
watchEffect(() => (widget.value = theWidget))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider simplifying the widget ref pattern.

The shallowRef + watchEffect pattern here is used to create a locally mutable copy of the widget prop. However, this pattern is typically used when you need to mutate the local copy. Since triggerRef(widget) is called to notify Vue of changes to the underlying widget object (which is mutated externally via renameWidget), this approach works but could be clearer.

If the intent is just to force reactivity updates when the widget object is mutated in place, consider documenting this with a brief comment explaining why shallowRef + triggerRef is needed here.

📝 Suggested documentation
+// shallowRef allows us to manually trigger updates via triggerRef when the
+// widget object is mutated in place (e.g., during rename operations)
 const widget = shallowRef(theWidget)
 watchEffect(() => (widget.value = theWidget))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const widget = shallowRef(theWidget)
watchEffect(() => (widget.value = theWidget))
// shallowRef allows us to manually trigger updates via triggerRef when the
// widget object is mutated in place (e.g., during rename operations)
const widget = shallowRef(theWidget)
watchEffect(() => (widget.value = theWidget))
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/parameters/WidgetItem.vue around lines 42 -
43, The local widget ref uses shallowRef(theWidget) plus watchEffect(() =>
(widget.value = theWidget)) to keep a mutable local reference and
triggerRef(widget) is used elsewhere when renameWidget mutates the object;
replace this with a short inline comment explaining why the shallowRef +
triggerRef pattern is required (i.e., to allow in-place mutation updates from
renameWidget) and keep the existing shallowRef and watchEffect lines untouched
so behavior remains the same while clarifying intent for future readers.

Comment on lines +151 to +155
const rootLevelNodes = computed((): LGraphNode[] => {
// Depend on activeWorkflow to trigger recomputation when workflow changes
void workflowStore.activeWorkflow?.path
return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[]
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding a brief comment explaining the dependency tracking pattern.

The void workflowStore.activeWorkflow?.path line is a clever way to create a reactive dependency, but its purpose may not be immediately clear to other developers.

📝 Suggested documentation
 const rootLevelNodes = computed((): LGraphNode[] => {
-  // Depend on activeWorkflow to trigger recomputation when workflow changes
+  // Access activeWorkflow.path to establish reactive dependency - ensures
+  // this computed re-evaluates when the active workflow changes
   void workflowStore.activeWorkflow?.path
   return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[]
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const rootLevelNodes = computed((): LGraphNode[] => {
// Depend on activeWorkflow to trigger recomputation when workflow changes
void workflowStore.activeWorkflow?.path
return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[]
})
const rootLevelNodes = computed((): LGraphNode[] => {
// Access activeWorkflow.path to establish reactive dependency - ensures
// this computed re-evaluates when the active workflow changes
void workflowStore.activeWorkflow?.path
return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[]
})
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/RightSidePanel.vue around lines 151 - 155, Add
an inline comment above the `void workflowStore.activeWorkflow?.path` line in
the `rootLevelNodes` computed getter explaining that this is intentionally
reading the workflow's `path` solely to create a reactive dependency so the
computed will recompute when `workflowStore.activeWorkflow` changes; reference
the symbols `rootLevelNodes`, `workflowStore.activeWorkflow?.path`, and
`canvasStore.canvas?.graph?.nodes` so reviewers can find the code quickly and
keep the explanation short and focused on intent.

Comment on lines +284 to +288
<i
v-if="!isEditing"
class="icon-[lucide--pencil] size-4 text-muted-foreground ml-2 content-center relative top-[2px] hover:text-base-foreground cursor-pointer shrink-0"
@click="isEditing = true"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding keyboard accessibility for the edit pencil icon.

The pencil icon is clickable but lacks keyboard accessibility. Consider adding tabindex="0" and a keydown handler for Enter/Space to make it accessible via keyboard.

♿ Suggested accessibility improvement
             <i
               v-if="!isEditing"
-              class="icon-[lucide--pencil] size-4 text-muted-foreground ml-2 content-center relative top-[2px] hover:text-base-foreground cursor-pointer shrink-0"
+              class="icon-[lucide--pencil] size-4 text-muted-foreground ml-2 content-center relative top-[2px] hover:text-base-foreground focus:text-base-foreground cursor-pointer shrink-0"
+              tabindex="0"
+              role="button"
+              :aria-label="t('g.edit')"
               @click="isEditing = true"
+              @keydown.enter.prevent="isEditing = true"
+              @keydown.space.prevent="isEditing = true"
             />
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/RightSidePanel.vue around lines 284 - 288, The
pencil icon (<i> element controlling isEditing) is not keyboard accessible; make
it focusable and respond to Enter/Space by adding tabindex="0" and a keydown
handler that sets isEditing = true when key is Enter or Space, and also add
role="button" and an appropriate aria-label (e.g., "Edit") so screen readers and
keyboard users get the same behavior as the @click handler.

const dialogService = useDialogService()
// NODES settings
const showAdvancedParameters = ref(false) // Placeholder for future implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Non-functional placeholder connected to UI.

The showAdvancedParameters ref is marked as a placeholder for future implementation, but it's already bound to a UI switch (line 104). This creates a misleading user experience where toggling the switch appears to work but has no effect.

Options to resolve

Option 1: Remove the UI binding until the feature is implemented:

-        <FieldSwitch
-          v-model="showAdvancedParameters"
-          :label="t('rightSidePanel.globalSettings.showAdvanced')"
-          :tooltip="t('rightSidePanel.globalSettings.showAdvancedTooltip')"
-        />

Option 2: Disable the switch with a visual indicator:

         <FieldSwitch
           v-model="showAdvancedParameters"
           :label="t('rightSidePanel.globalSettings.showAdvanced')"
           :tooltip="t('rightSidePanel.globalSettings.showAdvancedTooltip')"
+          disabled
         />

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @src/components/rightSidePanel/settings/TabGlobalSettings.vue at line 26, The
showAdvancedParameters ref is a non-functional placeholder but is already bound
to the UI switch; remove the misleading interactive behavior by disabling the
switch instead of leaving it bound—keep the showAdvancedParameters symbol for
future use but remove or stop using it as the v-model for the switch, add the
switch's disabled prop and a visual indicator (e.g., tooltip or small "Coming
soon" caption) so users see it is intentionally inactive; update the component
UI where the switch is referenced to reflect the disabled state and ensure no UI
actions rely on toggling showAdvancedParameters.

Comment on lines +61 to +72
let theOldLinkRenderMode: LinkRenderType = LiteGraph.SPLINE_LINK
const showConnectedLinks = computed({
get: () => settingStore.get('Comfy.LinkRenderMode') !== LiteGraph.HIDDEN_LINK,
set: (value) => {
let oldLinkRenderMode = settingStore.get('Comfy.LinkRenderMode')
if (oldLinkRenderMode !== LiteGraph.HIDDEN_LINK) {
theOldLinkRenderMode = oldLinkRenderMode
}
const newMode = value ? theOldLinkRenderMode : LiteGraph.HIDDEN_LINK
settingStore.set('Comfy.LinkRenderMode', newMode)
}
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Module-scope state causes issues in multi-instance scenarios.

The variable theOldLinkRenderMode is declared at module scope with let, which means it's shared across all component instances. This can cause state bleeding between multiple instances of TabGlobalSettings if they exist simultaneously or are recreated.

🔧 Move to component scope
 const { t } = useI18n()
 const settingStore = useSettingStore()
 const dialogService = useDialogService()
+
+const theOldLinkRenderMode = ref<LinkRenderType>(LiteGraph.SPLINE_LINK)

 // NODES settings
 const showAdvancedParameters = ref(false) // Placeholder for future implementation
 
 // ... other code ...

-let theOldLinkRenderMode: LinkRenderType = LiteGraph.SPLINE_LINK
 const showConnectedLinks = computed({
   get: () => settingStore.get('Comfy.LinkRenderMode') !== LiteGraph.HIDDEN_LINK,
   set: (value) => {
     let oldLinkRenderMode = settingStore.get('Comfy.LinkRenderMode')
     if (oldLinkRenderMode !== LiteGraph.HIDDEN_LINK) {
-      theOldLinkRenderMode = oldLinkRenderMode
+      theOldLinkRenderMode.value = oldLinkRenderMode
     }
-    const newMode = value ? theOldLinkRenderMode : LiteGraph.HIDDEN_LINK
+    const newMode = value ? theOldLinkRenderMode.value : LiteGraph.HIDDEN_LINK
     settingStore.set('Comfy.LinkRenderMode', newMode)
   }
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let theOldLinkRenderMode: LinkRenderType = LiteGraph.SPLINE_LINK
const showConnectedLinks = computed({
get: () => settingStore.get('Comfy.LinkRenderMode') !== LiteGraph.HIDDEN_LINK,
set: (value) => {
let oldLinkRenderMode = settingStore.get('Comfy.LinkRenderMode')
if (oldLinkRenderMode !== LiteGraph.HIDDEN_LINK) {
theOldLinkRenderMode = oldLinkRenderMode
}
const newMode = value ? theOldLinkRenderMode : LiteGraph.HIDDEN_LINK
settingStore.set('Comfy.LinkRenderMode', newMode)
}
})
const { t } = useI18n()
const settingStore = useSettingStore()
const dialogService = useDialogService()
const theOldLinkRenderMode = ref<LinkRenderType>(LiteGraph.SPLINE_LINK)
// NODES settings
const showAdvancedParameters = ref(false) // Placeholder for future implementation
// ... other code ...
const showConnectedLinks = computed({
get: () => settingStore.get('Comfy.LinkRenderMode') !== LiteGraph.HIDDEN_LINK,
set: (value) => {
let oldLinkRenderMode = settingStore.get('Comfy.LinkRenderMode')
if (oldLinkRenderMode !== LiteGraph.HIDDEN_LINK) {
theOldLinkRenderMode.value = oldLinkRenderMode
}
const newMode = value ? theOldLinkRenderMode.value : LiteGraph.HIDDEN_LINK
settingStore.set('Comfy.LinkRenderMode', newMode)
}
})
🤖 Prompt for AI Agents
In @src/components/rightSidePanel/settings/TabGlobalSettings.vue around lines 61
- 72, TheOldLinkRenderMode is declared at module scope and shared across
instances; move it into the component instance (inside setup) as a local
reactive/ref variable so each TabGlobalSettings has its own copy; update the
showConnectedLinks computed (the getter/setter that reads/writes
settingStore.get('Comfy.LinkRenderMode') and settingStore.set(...)) to reference
the instance-scoped theOldLinkRenderMode instead of the module-scoped one,
initializing it to LiteGraph.SPLINE_LINK (or the current stored value) so state
doesn't bleed between component instances.

:pt="{
option: 'text-xs',
dropdown: 'w-8',
label: cn('truncate min-w-[4ch]', $slots.default && 'mr-5'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Invalid slot reference.

Line 175 references $slots.default in the pt binding, but this component does not define or use any slots in its template. This will always evaluate to a falsy value and the conditional class logic won't work as intended.

🔧 Remove incorrect slot reference
               :pt="{
                 option: 'text-xs',
                 dropdown: 'w-8',
-                label: cn('truncate min-w-[4ch]', $slots.default && 'mr-5'),
+                label: 'truncate min-w-[4ch]',
                 overlay: 'w-fit min-w-full'
               }"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
label: cn('truncate min-w-[4ch]', $slots.default && 'mr-5'),
:pt="{
option: 'text-xs',
dropdown: 'w-8',
label: 'truncate min-w-[4ch]',
overlay: 'w-fit min-w-full'
}"

Comment on lines +123 to +138
<!-- Show advanced inputs button for subgraph nodes -->
<div v-if="showAdvancedInputsButton" class="flex justify-center px-3">
<button
:class="
cn(
WidgetInputBaseClass,
'w-full h-7 flex justify-center items-center gap-2 text-sm px-3 outline-0 ring-0 truncate',
'transition-all cursor-pointer hover:bg-accent-background duration-150 active:scale-95'
)
"
@click.stop="handleShowAdvancedInputs"
>
<i class="icon-[lucide--settings-2] size-4" />
<span>{{ t('rightSidePanel.showAdvancedInputsButton') }}</span>
</button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add type="button" and consider using the repo’s shared button component.

  • As-is, <button> defaults to type="submit" which can cause accidental form submits if this ever renders inside a <form>.
  • Repo learnings suggest preferring shared button components from src/components/button/* for consistent theming/behavior (instead of raw <button>). Based on learnings, prefer the common button components.
Proposed minimal safe fix
-          <button
+          <button
+            type="button"
             :class="
               cn(
                 WidgetInputBaseClass,
                 'w-full h-7 flex justify-center items-center gap-2 text-sm px-3 outline-0 ring-0 truncate',
                 'transition-all cursor-pointer hover:bg-accent-background duration-150 active:scale-95'
               )
             "
             @click.stop="handleShowAdvancedInputs"
           >
🤖 Prompt for AI Agents
In @src/renderer/extensions/vueNodes/components/LGraphNode.vue around lines 123
- 138, The button currently can act as a form submit because it lacks an
explicit type; add type="button" to the existing <button> (the element rendered
when showAdvancedInputsButton is true) so the click handled by
handleShowAdvancedInputs does not trigger form submission, and preserve its
class binding that uses WidgetInputBaseClass and the label from
t('rightSidePanel.showAdvancedInputsButton'); alternatively replace the raw
<button> with the repo’s shared button component (e.g., Button/IconButton) while
passing the same props, classes, icon (<i class="icon-[lucide--settings-2]">)
and @click.stop="handleShowAdvancedInputs" to maintain styling/behavior.

Comment on lines +496 to +510
const showAdvancedInputsButton = computed(() => {
const node = lgraphNode.value
if (!node || !(node instanceof SubgraphNode)) return false
// Check if there are hidden inputs (widgets not promoted)
const interiorNodes = node.subgraph.nodes
const allInteriorWidgets = interiorNodes.flatMap((n) => n.widgets ?? [])
return allInteriorWidgets.some((w) => !w.computedDisabled && !w.promoted)
})
function handleShowAdvancedInputs() {
const rightSidePanelStore = useRightSidePanelStore()
rightSidePanelStore.focusSection('advanced-inputs')
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard subgraph access and avoid instanceof brittleness; reduce allocations in the computed.

  • Line 501-502 can throw if subgraph or nodes is missing/undefined in any transitional state.
  • This file already uses isSubgraphNode() elsewhere (Line 471), which is typically safer than instanceof across module boundaries.
  • flatMap() allocates; a nested loop can short-circuit without extra arrays.
Proposed fix (safer + cheaper)
 const showAdvancedInputsButton = computed(() => {
   const node = lgraphNode.value
-  if (!node || !(node instanceof SubgraphNode)) return false
+  if (!node || typeof node.isSubgraphNode !== 'function' || !node.isSubgraphNode())
+    return false
+  if (!('subgraph' in node) || !node.subgraph?.nodes?.length) return false
 
   // Check if there are hidden inputs (widgets not promoted)
-  const interiorNodes = node.subgraph.nodes
-  const allInteriorWidgets = interiorNodes.flatMap((n) => n.widgets ?? [])
-
-  return allInteriorWidgets.some((w) => !w.computedDisabled && !w.promoted)
+  for (const interiorNode of node.subgraph.nodes) {
+    const widgets = interiorNode.widgets ?? []
+    for (const w of widgets) {
+      if (!w.computedDisabled && !w.promoted) return true
+    }
+  }
+  return false
 })

@LittleSound
Copy link
Collaborator Author

Fixed a lot of suggestions from coderabbitai. It would take too much time to go through the remaining nitpicks one by one, and blindly adopting them might introduce new bugs.

<Button
size="icon"
variant="secondary"
:class="buttonClass"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I wonder if just using v-bind is better for cases like this on common MoreButton type of components. 110% Non-blocking

Comment on lines +19 to +25
if (props.defaultCollapse) {
isCollapse.value = true
}
watch(
() => props.defaultCollapse,
(value) => (isCollapse.value = value)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could just use immediate right? Or potentially better: shouldn't this just be a computed?

Comment on lines +10 to 17
defaultCollapse?: boolean
label?: string
enableEmptyState?: boolean
noTooltip?: boolean
tooltip?: string
}>()
const isCollapse = defineModel<boolean>('collapse', { default: false })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: do we need a defaultCollapse? For all cases it's being used, could we just set collapse=... on the component?

Comment on lines +39 to +40
noTooltip = false,
tooltip
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (non-blocking): could this be simplified?

Comment on lines +63 to +64
const widgets = shallowRef(widgetsProp)
watchEffect(() => (widgets.value = widgetsProp))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: is there a way to simplify this or make more idiomatic (e.g., using a single "need re-render" version counter ref)?

/**
* TODO: This traverses the entire graph and could be very slow; needs optimization.
*/
function findParentGroupInGraph(node: LGraphNode): LGraphGroup | null {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this type of function best fits in the view layer (in a component)? Would it be good to move this to the selection service/store/composables?

Comment on lines +135 to +155
const hasSelection = computed(() => flattedItems.value.length > 0)
const isSingleNodeSelected = computed(
() => selectedNodes.value.length === 1 && flattedItems.value.length === 1
)
const selectedSingleNode = computed(() => {
return isSingleNodeSelected.value ? selectedNodes.value[0] : null
})
const selectionCount = computed(() => selectedItems.value.length)
const isSingleSubgraphNode = computed(() => {
return selectedSingleNode.value instanceof SubgraphNode
})
const selectionCount = computed(() => flattedItems.value.length)
const rootLevelNodes = computed((): LGraphNode[] => {
// Depend on activeWorkflow to trigger recomputation when workflow changes
void workflowStore.activeWorkflow?.path
return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[]
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar question to above comment


// Ensure extra object exists
graph.extra ??= {}
graph.extra.favoritedWidgets = data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: for future, might be slightly better to just have graph.extra.favoritedWidgets instead of an extra layer of indirection and duplication with favoritedIds ref.

Would need to make it reactive though and solve some potential issues with serialization, private properties, centralized graph state.

Just noting for future, not blocking on this PR!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job on this!

Comment on lines +57 to +64
setTimeout(() => {
const sectionElement = document.querySelector(
`[data-section="${section}"]`
)
if (sectionElement) {
sectionElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}, 300)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be done in the component rather than the store? Or would there be a way to use a more Vue-idiomatic approach rather than querySelector? Or when we are passing the section, can we get the ref?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants