-
Notifications
You must be signed in to change notification settings - Fork 461
feat: right side panel favorites, no selection state, and more... #7812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughRefactors 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
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
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)
Possibly related PRs
✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (3)
🧰 Additional context used📓 Path-based instructions (5)src/**/*.{vue,ts}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/**/*.ts📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/**/*.{ts,tsx,vue}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/*.{vue,ts,tsx}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (7)📚 Learning: 2025-12-09T03:39:54.501ZApplied to files:
📚 Learning: 2025-12-13T11:03:11.264ZApplied to files:
📚 Learning: 2025-12-17T00:40:09.635ZApplied to files:
📚 Learning: 2025-12-30T22:22:33.836ZApplied to files:
📚 Learning: 2025-12-11T12:25:15.470ZApplied to files:
📚 Learning: 2025-12-09T04:35:43.971ZApplied to files:
📚 Learning: 2025-12-05T20:35:28.330ZApplied to files:
⏰ 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)
🔇 Additional comments (5)
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. Comment |
There was a problem hiding this 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
📒 Files selected for processing (18)
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/locales/en/main.jsonsrc/renderer/extensions/vueNodes/components/LGraphNode.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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 useanytype oras anytype 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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/locales/en/main.jsonsrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.tssrc/stores/workspace/rightSidePanelStore.ts
**/*Store.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name Pinia stores using the pattern
*Store.ts
Files:
src/stores/workspace/favoritedWidgetsStore.tssrc/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.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/index.tssrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/stores/workspace/favoritedWidgetsStore.tssrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/settings/GroupSettings.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.tssrc/stores/workspace/favoritedWidgetsStore.tssrc/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.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/settings/NodeSettings.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/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.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/settings/TabGlobalSettings.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabParameters.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/SectionWidgets.vuesrc/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.tssrc/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.vuesrc/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)
| 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 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| const searchedFavoritedWidgets = shallowRef<ValidFavoritedWidget[]>([]) | ||
| async function searcher(query: string) { | ||
| searchQuery.value = query | ||
| searchedFavoritedWidgets.value = searchWidgets(favoritedWidgets.value, query) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this 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: Addupdate-keyprop to reset search when nodes change.
SidePanelSearchwatches both the search query andupdateKeyprop. 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.
searchedWidgetsSectionDataListstarts as an empty array and is only populated whensearcher()is called, causing nothing to render on mount. Additionally, theasynckeyword is unnecessary since noawaitis 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
widgetsSectionDataListchanges:watch(widgetsSectionDataList, (newVal) => { if (!searchQuery.value) { searchedWidgetsSectionDataList.value = newVal } }, { immediate: true })
58-61: Reference comparison will always fail—use search state instead.
widgetsSectionDataListis a computed that returns a new array on each access. Comparing it with===tosearchedWidgetsSectionDataList(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,searchedFavoritedWidgetsstarts empty and is only populated whensearcher()is called. Theasynckeyword 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: Addupdate-keyprop to reset search when favorites change.Without the
update-keyprop, 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 publicnodesaccessor instead of private_nodes.Accessing the private
_nodesproperty violates encapsulation and the type assertionas LGraphNode[]is unsafe since the array may containSubgraphNodeinstances. Use the publicgraph.nodesgetter 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
📒 Files selected for processing (7)
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/settings/TabSettings.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabNodes.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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 useanytype oras anytype 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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/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.vuesrc/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:
- Only nodes: renders directly without accordion
- Multiple types: wraps each in
PropertiesAccordionItemThis provides a cleaner UX when only one type is present.
47-53: LGTM! Type guards correctly narrow selection types.The computed properties correctly use
isLGraphNodeandisLGraphGrouptype 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
repeatItemsfunction 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 —computedDisabledis the correct property to use.The
computedDisabledproperty is a valid, readonly computed property onIBaseWidgetthat reflects the actual disabled state used for rendering. It accounts for both the widget'sdisabledflag 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
allowTitleEditcomputed correctly restricts editing to single item selections, andhandleTitleEditproperly 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.
There was a problem hiding this 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.
TabParametersreceives:nodes="selectedNodes"(typed asLGraphNode[]) whileTabSettingsreceives:nodes="flattedItems"(typed asMixedSelectionItem[]). Using the same prop namenodesfor different types may be confusing. IfTabSettingsaccepts mixed items (groups and nodes), consider renaming its prop toitemsorselectionfor clarity.
♻️ Duplicate comments (1)
src/components/rightSidePanel/RightSidePanel.vue (1)
69-71: Replace_nodesaccess with the publicnodesgetter.This issue was already identified in a previous review. Use
graph.nodesinstead of the private_nodesproperty and apply proper type narrowing to filter outSubgraphNodeinstances.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 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.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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 useanytype oras anytype 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
selectedSingleNodecomputed returnsLGraphNode | null, but thev-else-ifcondition ensures it's aSubgraphNodeat runtime. TypeScript cannot infer this narrowing from the template condition. Verify thatSubgraphEditorproperly handles the nullable type or consider creating a dedicated computed that returnsSubgraphNode | undefinedwith 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.
| const node = selectedGroups.value[0] || selectedNodes.value[0] | ||
| if (!node) return |
There was a problem hiding this comment.
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 = trimmedTitleCommittable 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.
There was a problem hiding this 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
📒 Files selected for processing (2)
src/locales/en/main.jsonsrc/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}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.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 useanytype oras anytype 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.tssrc/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
useFavoritedWidgetsStoreis 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.FavoriteWidgetandcontextMenu.UnfavoriteWidgetexist insrc/locales/en/main.json. The placement of the favorite/unfavorite logic outside theif (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 theif (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", |
There was a problem hiding this comment.
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.
| "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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| "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", |
There was a problem hiding this comment.
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:
- "TRUE" in all-caps is inconsistent with typical UI patterns (should be "enabled" or lowercase "true")
- 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.
| "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.
There was a problem hiding this 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
📒 Files selected for processing (2)
src/components/rightSidePanel/parameters/WidgetItem.vuesrc/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.tssrc/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}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.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.tssrc/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.tssrc/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.tssrc/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.tssrc/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 useanytype oras anytype 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.tssrc/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.tssrc/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.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.tssrc/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. TheuseReactiveWidgetValuefunction 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:
- Add JSDoc documentation describing the function's purpose, parameters, and return value (consistent with the
normalizeWidgetValuedocumentation pattern in this file), or- Remove the
exportkeyword if this function is not intended for external usesrc/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-fillfrom 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 propertiesLearnt 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="[]"` syntaxLearnt 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 insteadLearnt 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 + triggerRefpattern is not an architectural flaw but a necessary solution. Widgets are mutated directly by child components (WidgetActions.vue explicitly mutateswidget.labelwith an eslint-disable comment, and SectionWidgets.vue mutateswidget.value). Since these widgets come from LiteGraph—an external library designed for mutation—the current approach is appropriate:
shallowRefis correct because only shallow reactivity is neededwatchEffectensures sync when the prop updates from the parenttriggerRefis required because shallowRef cannot auto-detect mutations to nested propertiesImmutability 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) |
There was a problem hiding this comment.
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.
| 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.
There was a problem hiding this 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
📒 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.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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 useanytype oras anytype 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+watchEffectpattern creates a mutable copy of the prop. WhiletriggerRef(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
WidgetLegacyprovides 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
hasParentsandfavoriteNodeis straightforward and easy to follow.
84-91: Event handlers are appropriate for the chosen pattern.The
triggerRefcall inhandleWidgetUpdateis 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
shouldExpandare appropriate for dynamic widget types.
142-152: Replace invalidz-2class; PrimeIcons usage is appropriate.Line 147: The
z-2class 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 withz-10if z-index stacking is required. Given the relative/absolute positioning context here, the z-index may be unnecessary entirely.The
pi pi-star-fillicon is appropriate for this use case; PrimeIcons is the project's established icon library for Vue templates.
There was a problem hiding this 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
📒 Files selected for processing (2)
src/components/rightSidePanel/parameters/WidgetItem.vuesrc/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.tssrc/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}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.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.tssrc/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.tssrc/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.tssrc/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.tssrc/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 useanytype oras anytype 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.tssrc/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.tssrc/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.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.tssrc/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-fillis 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—thegraphproperty is type-safe andgetNodeByExecutionIdalready handles null values.The
_overlay.graphproperty is typed asLGraph(non-optional) and cannot be null by design. Additionally,getNodeByExecutionIdincludes 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 inresolveLinkedWidget.Likely an incorrect or invalid review comment.
src/composables/graph/useGraphNodeManager.ts (3)
129-173: Well-structured shared enhancement extraction.The new
SharedWidgetEnhancementsinterface andgetSharedWidgetEnhancementsfunction 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
safeWidgetMapperfunction now leveragesgetSharedWidgetEnhancementsthrough 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 ofuseReactiveWidgetValue.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.
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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() |
There was a problem hiding this comment.
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().
🔧 Auto-fixes AppliedThis PR has been automatically updated to fix linting and formatting issues.
Changes made:
|
There was a problem hiding this 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
📒 Files selected for processing (4)
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/parameters/WidgetActions.vuesrc/components/rightSidePanel/parameters/WidgetItem.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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 useanytype oras anytype 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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/shared.tssrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/components/rightSidePanel/RightSidePanel.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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' | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Search for all cn utility imports to see the patterns
rg "import.*cn.*from" --type vue --type ts -C 1Repository: 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 1Repository: 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 -lRepository: 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 -50Repository: 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 -lRepository: Comfy-Org/ComfyUI_frontend
Length of output: 153
🏁 Script executed:
# Find all files using @comfyorg/tailwind-utils
rg "@comfyorg/tailwind-utils" -lRepository: 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.jsonRepository: Comfy-Org/ComfyUI_frontend
Length of output: 116
🏁 Script executed:
# Check what's in the local tailwindUtil.ts file
cat src/utils/tailwindUtil.tsRepository: 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.
| <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> |
There was a problem hiding this comment.
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.
| /** | ||
| * 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 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
- Caching the node-to-group mapping and invalidating on graph structure changes
- Building an index when groups are modified rather than on-demand traversal
- 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| if (ctx.depth > 1000) { | ||
| return { | ||
| all: [], | ||
| nodes: [], | ||
| groups: [], | ||
| others: [] | ||
| } | ||
| } |
There was a problem hiding this comment.
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.
| 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.
| 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) | ||
| } | ||
| } |
There was a problem hiding this comment.
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.
| 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 | ||
| } |
There was a problem hiding this comment.
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).
There was a problem hiding this 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
📒 Files selected for processing (2)
src/components/rightSidePanel/parameters/WidgetActions.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/WidgetItem.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/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 useanytype oras anytype 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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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: ThesetDirtyparameter 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 callsetDirty(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 likelabelthat affect the UI bindings. The code already documents this at line 257 ofshared.tswith the comment "Intentionally mutate the widget object here as it's a reference to the actual widget in the graph."The
shallowRef+watchEffect+triggerRefpattern 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.
| console.error('Could not find interior node for proxy widget') | ||
| return |
There was a problem hiding this comment.
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]" /> |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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.
There was a problem hiding this 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
📒 Files selected for processing (3)
src/platform/settings/constants/coreSettings.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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 useanytype oras anytype 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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.tssrc/schemas/apiSchema.tssrc/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.IsOpenboolean 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
clearFocusedSectionafter 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 insrc/platform/settings/constants/coreSettings.tsas a hidden boolean setting with a default value offalse. 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 |
There was a problem hiding this comment.
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
stringwith 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.
There was a problem hiding this 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
📒 Files selected for processing (8)
src/components/rightSidePanel/layout/SidePanelSearch.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/components/rightSidePanel/parameters/TabNodes.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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 useanytype oras anytype 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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/stores/workspace/rightSidePanelStore.tssrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/rightSidePanel/layout/SidePanelSearch.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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-fullvia thecn()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
searchQueryfromrightSidePanelStoreusingstoreToRefsis 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-surfacetobg-comfy-menu-bgmaintain 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
setDraggableStatefunction includes appropriate guards:
- Mounted state check
- Empty container check
- Search state check
The
applyNewItemsOrderimplementation 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
isOpento usesettingStorecorrectly 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
focusSectionfunction uses a hardcoded 300mssetTimeoutto 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
nextTickwith 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
maxWaitreduces 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
handleFocusfunction 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
widgetsSectionDataListcomputed property correctly filters outcanvasOnlyandhiddenwidgets, ensuring only user-editable widgets are displayed. The mapping to{ node, widget }tuples maintains proper node context.
33-42: LGTM: Clean search implementation.The
searcherfunction correctly:
- Updates
isSearchingstate based on query presence- Uses
shallowReffor performance with large lists- Delegates to the shared
searchWidgetsAndNodesutilityThis implementation is cleaner than the one in TabSubgraphInputs.vue as it doesn't mutate props.
53-69: LGTM: TransitionGroup usage for smooth animations.The
TransitionGroupwithname="list-scale"provides smooth enter/leave animations for the filtered results. The empty state message and per-nodeSectionWidgetsrendering are appropriate.src/components/rightSidePanel/parameters/TabNormalInputs.vue (1)
61-90: LGTM on template structure.Good use of
TransitionGroupwith 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()inonBeforeUnmountprevents memory leaks.
113-142: LGTM on template structure.Clean implementation with proper slot usage for empty state, i18n strings, and reactive binding of
isDraggablebased on search state.
| // 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 | ||
| } | ||
| })) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this 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
📒 Files selected for processing (10)
src/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabGlobalParameters.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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 useanytype oras anytype 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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabNodes.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/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.vuesrc/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuActions.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/components/rightSidePanel/parameters/TabNormalInputs.vuesrc/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.vuesrc/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/components/rightSidePanel/parameters/TabSubgraphInputs.vuesrc/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
isQueryingwith an optionalsearchercallback 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-ttoborder-band the addition ofbg-comfy-menu-bgto widget items improve visual consistency across sections.Also applies to: 264-264, 283-283, 296-296, 315-315, 325-325
251-260: The i18n keyrightSidePanel.noneSearchDescis defined insrc/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
searchQueryis 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. UsingstoreToRefscorrectly 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-queryingto: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
isQueryingand addition of the optionalsearcherprop is consistent with the changes inFormDropdownMenuActions.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
classprop aliased ascustomClassis 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
handleFocushandler 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
customClassprop usingcn(), add group-based hover/focus styling, and bind theautofocusprop. The icon color transitions based on query state provide good visual feedback.
| <div> | ||
| {{ $t('g.empty') }} | ||
| </div> |
There was a problem hiding this comment.
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.
| <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.
| 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 | ||
| }) | ||
| } |
There was a problem hiding this comment.
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.
| 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.
src/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue
Show resolved
Hide resolved
There was a problem hiding this 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
📒 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.vuefiles, 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 usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses 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 useanytype oras anytype 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
There was a problem hiding this 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-pressedif 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
📒 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 thedark:Tailwind variant; use semantic values fromstyle.csstheme instead (e.g.,bg-node-component-surface)
Usecn()utility from@/utils/tailwindUtilfor merging class names; never use:class="[]"syntax
Never use!importantor the!prefix for Tailwind classes; find and fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentages (e.g.,w-4/5instead ofw-[80%],w-1/2instead ofw-[50%])
Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoidwithDefaultsand runtime props
UsedefineModelfor v-model bindings instead of separately defining props and emits
Prefer reactive props destructuring overconst props = defineProps<...>
Define slots via template usage, notdefineSlots
Use same-name shorthand for slot prop bindings (e.g.,:isExpandedinstead of:is-expanded="isExpanded")
Usereffor reactive state,computed()for computed properties, andwatch/watchEffectfor side effects
Avoid usingrefandwatcht...
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.jsonLeverage 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 separateimport typestatements; do not mix inlinetypeimports in the same statement
Sort and group imports by plugin; runpnpm formatbefore committing
Derive component types usingvue-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 () { ... }orfor () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never useanytype; use proper TypeScript types
Never useas anytype 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 componentsName 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 useswatch()withoutdeep: truebecausecanvasStore.selectedItemsis 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 functionflatAndCategorizeSelectedItems. ThetriggerRef()calls are defensive but unnecessary given the array replacement pattern.Likely an incorrect or invalid review comment.
There was a problem hiding this 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
📒 Files selected for processing (2)
src/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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 thedark:Tailwind variant; use semantic values fromstyle.csstheme instead (e.g.,bg-node-component-surface)
Usecn()utility from@/utils/tailwindUtilfor merging class names; never use:class="[]"syntax
Never use!importantor the!prefix for Tailwind classes; find and fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentages (e.g.,w-4/5instead ofw-[80%],w-1/2instead ofw-[50%])
Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoidwithDefaultsand runtime props
UsedefineModelfor v-model bindings instead of separately defining props and emits
Prefer reactive props destructuring overconst props = defineProps<...>
Define slots via template usage, notdefineSlots
Use same-name shorthand for slot prop bindings (e.g.,:isExpandedinstead of:is-expanded="isExpanded")
Usereffor reactive state,computed()for computed properties, andwatch/watchEffectfor side effects
Avoid usingrefandwatcht...
Files:
src/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.jsonLeverage VueUse functions for performance-enhancing utilities
Files:
src/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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 separateimport typestatements; do not mix inlinetypeimports in the same statement
Sort and group imports by plugin; runpnpm formatbefore committing
Derive component types usingvue-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 () { ... }orfor () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never useanytype; use proper TypeScript types
Never useas anytype 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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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 componentsName Vue components in PascalCase (e.g., MenuHamburger.vue)
Files:
src/components/rightSidePanel/layout/PropertiesAccordionItem.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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.vuesrc/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
shallowRefwithwatchEffectfor syncingwidgetsis appropriate here sincetriggerRefis used later to manually trigger reactivity updates inonWidgetUpdate. This pattern correctly enables both prop synchronization and manual reactivity control.
96-107: LGTM!Event handlers are concise and correctly implemented. The
onWidgetUpdatefunction properly usestriggerRefto manually trigger reactivity updates on the shallow ref.
109-141: LGTM!The computed properties are well-structured with proper null checks. The
targetNodecomputed correctly handles the empty case before accessing array elements. ThehandleLocateNodefunction uses appropriate defensive programming with early returns.
143-145: LGTM!Exposing
widgetsContainerviadefineExposeis appropriate for imperative DOM operations like drag-and-drop coordination (as indicated by theisDraggableprop).src/components/rightSidePanel/layout/PropertiesAccordionItem.vue (2)
27-27: LGTM: Computed property correctly derives expansion state.Good use of
computedto deriveisExpandedfromisCollapseandisEmpty. 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-1provides good layout flexibility- Chevron icon transitions correctly with collapse state
- Proper disabled state and accessibility
| <slot v-else-if="enableEmptyState && isEmpty" name="empty"> | ||
| <div> | ||
| {{ $t('g.empty') }} | ||
| </div> | ||
| </slot> |
There was a problem hiding this comment.
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.
| <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.
| 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 | ||
| ) | ||
| } |
There was a problem hiding this comment.
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.
| <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> |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
| 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 | ||
| } | ||
| })) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
- Unpredictable reactivity behavior
- Difficulty tracking state changes
- Potential race conditions with parent component updates
- 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 |
There was a problem hiding this comment.
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.
| 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.
| const widget = shallowRef(theWidget) | ||
| watchEffect(() => (widget.value = theWidget)) |
There was a problem hiding this comment.
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.
| 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.
| const rootLevelNodes = computed((): LGraphNode[] => { | ||
| // Depend on activeWorkflow to trigger recomputation when workflow changes | ||
| void workflowStore.activeWorkflow?.path | ||
| return (canvasStore.canvas?.graph?.nodes ?? []) as LGraphNode[] | ||
| }) |
There was a problem hiding this comment.
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.
| 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.
| <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" | ||
| /> |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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) | ||
| } | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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' | |
| }" |
| <!-- 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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add type="button" and consider using the repo’s shared button component.
- As-is,
<button>defaults totype="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.
| 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') | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard subgraph access and avoid instanceof brittleness; reduce allocations in the computed.
- Line 501-502 can throw if
subgraphornodesis missing/undefined in any transitional state. - This file already uses
isSubgraphNode()elsewhere (Line 471), which is typically safer thaninstanceofacross 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
})|
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" |
There was a problem hiding this comment.
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
| if (props.defaultCollapse) { | ||
| isCollapse.value = true | ||
| } | ||
| watch( | ||
| () => props.defaultCollapse, | ||
| (value) => (isCollapse.value = value) | ||
| ) |
There was a problem hiding this comment.
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?
| defaultCollapse?: boolean | ||
| label?: string | ||
| enableEmptyState?: boolean | ||
| noTooltip?: boolean | ||
| tooltip?: string | ||
| }>() | ||
| const isCollapse = defineModel<boolean>('collapse', { default: false }) |
There was a problem hiding this comment.
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?
| noTooltip = false, | ||
| tooltip |
There was a problem hiding this comment.
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?
| const widgets = shallowRef(widgetsProp) | ||
| watchEffect(() => (widgets.value = widgetsProp)) |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
| 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[] | ||
| }) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job on this!
| setTimeout(() => { | ||
| const sectionElement = document.querySelector( | ||
| `[data-section="${section}"]` | ||
| ) | ||
| if (sectionElement) { | ||
| sectionElement.scrollIntoView({ behavior: 'smooth', block: 'start' }) | ||
| } | ||
| }, 300) |
There was a problem hiding this comment.
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?
Most of the features in this pull request are completed and can be reviewed and merged.
TODO
┆Issue is synchronized with this Notion page by Unito