-
Notifications
You must be signed in to change notification settings - Fork 429
feat: right side panel #6952
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
feat: right side panel #6952
Conversation
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (18)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the 📝 WalkthroughWalkthroughAdds a new right-side properties panel system: Pinia store for panel state, a RightSidePanel UI with tabs (parameters, settings, info), many new components (search, sections, settings, info), Graph/Canvas and TopMenu integration, widget search/layout updates, and migration of subgraph editing from a dialog to the panel. Changes
Sequence Diagram(s)mermaid Possibly related PRs
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
🎭 Playwright Test Results❌ Some tests failed ⏰ Completed at: 12/03/2025, 05:37:29 AM UTC 📈 Summary
📊 Test Reports by Browser
🎉 Click on the links above to view detailed test results for each browser configuration. |
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 12/03/2025, 05:25:28 AM UTC 🔗 Links🎉 Your Storybook is ready for review! |
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
🧹 Nitpick comments (10)
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)
3-14: Injection usage is good; verify type matches provider and consider a shared InjectionKeyUsing
injecthere cleanly follows the provide/inject pattern the repo prefers, and the defaultfalsekeeps behavior unchanged when nothing is provided. Please double‑check that whatever isprovided under'hideLayoutField'is actually a plainboolean; if it’s aRef/ComputedRef, it would be better to type this as that and use a matching default (e.g.ref(false)) to keep TypeScript accurate. Also consider promoting'hideLayoutField'to a sharedInjectionKey<boolean>(Symbol) so both provider and consumer share a single, typed token instead of a magic string. The ESLintimport-x/no-unresolvedhint on the'vue'import looks like a resolver/configuration issue rather than a problem with this code, but it’s worth confirming your ESLint setup so it doesn’t fail CI. As per coding guidelines and learnings, this is a good use of provide/inject in Vue 3.src/components/rightSidePanel/parameters/SectionWidgets.vue (1)
47-50: Consider using Vue 3.5 destructured props with defaults.Per coding guidelines, use Vue 3.5 style of default prop declaration. The current definition is valid but could leverage destructuring for consistency with other components.
src/components/rightSidePanel/SubgraphNodeWidget.vue (1)
19-25: Consider convertinggetIcon()to a computed property.Since
getIcon()is called in the template and depends only on reactive props, making it acomputedwould cache the result and be more idiomatic Vue.+import { computed } from 'vue' + +const icon = computed(() => { + return props.isPhysical + ? 'icon-[lucide--link]' + : props.isDraggable + ? 'icon-[lucide--eye]' + : 'icon-[lucide--eye-off]' +}) -function getIcon() { - return props.isPhysical - ? 'icon-[lucide--link]' - : props.isDraggable - ? 'icon-[lucide--eye]' - : 'icon-[lucide--eye-off]' -}Then use
:icon="icon"in the template.src/stores/workspace/rightSidePanelStore.ts (1)
17-18: ExportPanelTabtype for consumer type safety.The
PanelTabtype is defined inside the store but consumers callingsetActiveTabwon't have access to it for type checking. Export it for better TypeScript support.+export type PanelTab = 'properties' | 'subgraph' + export const useRightSidePanelStore = defineStore('rightSidePanel', () => { const canvasStore = useCanvasStore() // Panel visibility state const isOpen = ref(false) // Active tab in the panel - type PanelTab = 'properties' | 'subgraph' const activeTab = ref<PanelTab>('properties')src/components/rightSidePanel/layout/RightPanelSection.vue (1)
10-18: Simplify initialization logic to avoid redundancy.The combination of the if-block (lines 12-14) and the watch (lines 15-18) is redundant. The watch also has a potential type issue:
props.defaultCollapseisboolean | undefinedbutisCollapseexpectsboolean. Use{ immediate: true }on the watch to handle both initial and subsequent updates cleanly.const isCollapse = defineModel<boolean>('collapse', { default: false }) -if (props.defaultCollapse) { - isCollapse.value = true -} watch( () => props.defaultCollapse, - (value) => (isCollapse.value = value) + (value) => { + if (value !== undefined) { + isCollapse.value = value + } + }, + { immediate: true } )src/components/rightSidePanel/parameters/SidePanelSearch.vue (1)
72-77: Missing i18n for placeholder text.The placeholder "Search" should use vue-i18n for internationalization. As per coding guidelines, all user-facing strings should use i18n.
Apply this diff:
<input v-model="searchQuery" type="text" class="bg-transparent border-0 outline-0 ring-0 text-left" - placeholder="Search" + :placeholder="$t('g.search')" />Ensure the translation key exists in
src/locales/en/main.json.src/components/rightSidePanel/NodePropertiesPanel.vue (2)
45-51: Hardcoded 'Node' fallback should use i18n.The fallback string 'Node' on line 48 should be internationalized.
if (isSingleNodeSelected.value && selectedNode.value) { - return selectedNode.value.title || selectedNode.value.type || 'Node' + return selectedNode.value.title || selectedNode.value.type || t('rightSidePanel.node') }Add the translation key to
src/locales/en/main.json.
99-115: Remove duplicate static class attribute.The
classattribute on line 103 duplicates styles already in the:classbinding. Thecn()utility on lines 105-110 already includes the same base classes.<IconButton v-if="isSubgraphNode" type="transparent" size="sm" - class="bg-secondary-background hover:bg-secondary-background-hover" :class=" cn( 'bg-secondary-background hover:bg-secondary-background-hover', isEditingSubgraph ? 'bg-secondary-background-selected' : 'bg-secondary-background' ) " @click="isEditingSubgraph = !isEditingSubgraph" >src/components/rightSidePanel/SubgraphEditor.vue (1)
236-247: Misleading return statements in void functions.
demoteandpromotereturn empty arrays on early exit, but they're used as event handlers and their return values are never consumed. This is confusing.function demote([node, widget]: WidgetItem) { const subgraphNode = activeNode.value - if (!subgraphNode) return [] + if (!subgraphNode) return demoteWidget(node, widget, [subgraphNode]) triggerRef(proxyWidgets) } function promote([node, widget]: WidgetItem) { const subgraphNode = activeNode.value - if (!subgraphNode) return [] + if (!subgraphNode) return promoteWidget(node, widget, [subgraphNode]) triggerRef(proxyWidgets) }src/renderer/extensions/vueNodes/widgets/components/form/FormSelectButton.vue (1)
20-30: Template now uses index-based selection helpersThe switch to
isSelected(index)andhandleSelect(index)looks consistent with the new index-based logic and keeps the template simple. One small optional tweak:isSelected(index)is called three times per button; if this component is ever used with very large option lists, you could compute a singleselectedIndex(viacomputed) and compareindex === selectedIndexin the template to avoid repeatedgetOptionValuework, but it’s not required for typical usage.
| const nodeState = computed({ | ||
| get() { | ||
| let mode: LGraphNode['mode'] | null = null | ||
|
|
||
| // For multiple nodes, if all nodes have the same mode, return that mode, otherwise return null | ||
| if (targetNodes.value.length > 1) { | ||
| mode = targetNodes.value[0].mode | ||
| if (!targetNodes.value.every((node) => node.mode === mode)) { | ||
| mode = null | ||
| } | ||
| } else { | ||
| mode = targetNodes.value[0].mode | ||
| } | ||
|
|
||
| return mode | ||
| }, | ||
| set(value: LGraphNode['mode']) { | ||
| targetNodes.value.forEach((node) => { | ||
| node.mode = value | ||
| }) | ||
| triggerRef(targetNodes) | ||
| canvasStore.canvas?.setDirty(true, 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.
Potential undefined access when no nodes selected.
In the getter (lines 117-124), when targetNodes.value.length is 0, the code falls through to line 123 which accesses targetNodes.value[0].mode, causing a runtime error.
Apply this diff:
const nodeState = computed({
get() {
let mode: LGraphNode['mode'] | null = null
+ if (targetNodes.value.length === 0) return null
+
// For multiple nodes, if all nodes have the same mode, return that mode, otherwise return null
if (targetNodes.value.length > 1) {
mode = targetNodes.value[0].mode
if (!targetNodes.value.every((node) => node.mode === mode)) {
mode = null
}
} else {
mode = targetNodes.value[0].mode
}
return mode
},📝 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 nodeState = computed({ | |
| get() { | |
| let mode: LGraphNode['mode'] | null = null | |
| // For multiple nodes, if all nodes have the same mode, return that mode, otherwise return null | |
| if (targetNodes.value.length > 1) { | |
| mode = targetNodes.value[0].mode | |
| if (!targetNodes.value.every((node) => node.mode === mode)) { | |
| mode = null | |
| } | |
| } else { | |
| mode = targetNodes.value[0].mode | |
| } | |
| return mode | |
| }, | |
| set(value: LGraphNode['mode']) { | |
| targetNodes.value.forEach((node) => { | |
| node.mode = value | |
| }) | |
| triggerRef(targetNodes) | |
| canvasStore.canvas?.setDirty(true, true) | |
| } | |
| }) | |
| const nodeState = computed({ | |
| get() { | |
| let mode: LGraphNode['mode'] | null = null | |
| if (targetNodes.value.length === 0) return null | |
| // For multiple nodes, if all nodes have the same mode, return that mode, otherwise return null | |
| if (targetNodes.value.length > 1) { | |
| mode = targetNodes.value[0].mode | |
| if (!targetNodes.value.every((node) => node.mode === mode)) { | |
| mode = null | |
| } | |
| } else { | |
| mode = targetNodes.value[0].mode | |
| } | |
| return mode | |
| }, | |
| set(value: LGraphNode['mode']) { | |
| targetNodes.value.forEach((node) => { | |
| node.mode = value | |
| }) | |
| triggerRef(targetNodes) | |
| canvasStore.canvas?.setDirty(true, true) | |
| } | |
| }) |
🤖 Prompt for AI Agents
In src/components/rightSidePanel/appearance/TabAppearance.vue around lines 112
to 135, the getter unconditionally reads targetNodes.value[0] and will throw
when targetNodes.value.length === 0; update the getter to first check for an
empty array and return null when there are no nodes selected, otherwise keep the
existing logic for single or multiple nodes (i.e., if length === 0 return null;
else if length > 1 compare modes and return mode or null; else return the single
node's mode). Ensure no other changes to the setter behavior besides leaving it
safe when targetNodes is empty.
| const node = computed(() => props.nodes[0]) | ||
| const nodeDefStore = useNodeDefStore() | ||
| const nodeHelpStore = useNodeHelpStore() | ||
| const nodeInfo = computed(() => { | ||
| return nodeDefStore.fromLGraphNode(node.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.
Add a guard for empty nodes array to prevent potential errors.
When props.nodes is empty, node.value will be undefined, and nodeDefStore.fromLGraphNode(undefined) may produce unexpected results or errors.
Consider adding a guard:
const node = computed(() => props.nodes[0])
const nodeDefStore = useNodeDefStore()
const nodeHelpStore = useNodeHelpStore()
const nodeInfo = computed(() => {
+ if (!node.value) return null
return nodeDefStore.fromLGraphNode(node.value)
})📝 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 node = computed(() => props.nodes[0]) | |
| const nodeDefStore = useNodeDefStore() | |
| const nodeHelpStore = useNodeHelpStore() | |
| const nodeInfo = computed(() => { | |
| return nodeDefStore.fromLGraphNode(node.value) | |
| }) | |
| const node = computed(() => props.nodes[0]) | |
| const nodeDefStore = useNodeDefStore() | |
| const nodeHelpStore = useNodeHelpStore() | |
| const nodeInfo = computed(() => { | |
| if (!node.value) return null | |
| return nodeDefStore.fromLGraphNode(node.value) | |
| }) |
🤖 Prompt for AI Agents
In src/components/rightSidePanel/info/TabInfo.vue around lines 18 to 25,
props.nodes is accessed without checking length which can make node.value
undefined and lead to errors when calling nodeDefStore.fromLGraphNode; add a
guard so node is computed defensively (e.g., compute node as props.nodes.length
? props.nodes[0] : null/undefined) and update nodeInfo to return early or null
when node is null/undefined before calling fromLGraphNode (also adjust any
downstream consumers to handle a null nodeInfo).
| const getOptionValue = (option: T, index: number): ModelValue => { | ||
| if (typeof option !== 'object') { | ||
| return option as ModelValue | ||
| } | ||
| return String(option) | ||
| const valueField = props.optionValue | ||
| const value = | ||
| (option as any)[valueField] ?? | ||
| option.value ?? | ||
| (option as any).name ?? | ||
| option.label ?? | ||
| index | ||
| return 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.
Add null guard in getOptionValue and reconsider string-based equality
Two points here:
- Null safety in
getOptionValue
getOptionValue treats anything with typeof option === 'object' as an object, but unlike getOptionLabel it doesn’t guard against null:
const getOptionValue = (option: T, index: number): ModelValue => {
if (typeof option !== 'object') {
return option as ModelValue
}
const valueField = props.optionValue
const value =
(option as any)[valueField] ??
option.value ??
(option as any).name ??
option.label ??
index
return value
}If options ever contains null at runtime, this will throw when accessing properties. Mirroring the label helper’s option !== null check would harden this:
-const getOptionValue = (option: T, index: number): ModelValue => {
- if (typeof option !== 'object') {
- return option as ModelValue
- }
+const getOptionValue = (option: T, index: number): ModelValue => {
+ if (option === null || typeof option !== 'object') {
+ return option as ModelValue
+ }
const valueField = props.optionValue
const value =
(option as any)[valueField] ??
option.value ??
(option as any).name ??
option.label ??
index
return value
}- String-based comparison in
isSelected
isSelected compares via String(optionValue) === String(props.modelValue ?? ''). This deliberately allows 1 and '1' to be treated as equal, but it can also conflate distinct values whose string representations collide (e.g. '01' vs 1). If you don’t need cross-type matching, consider using strict equality on the underlying ModelValue instead to avoid surprises; otherwise, keeping String(...) is fine but the trade-off is worth being aware of.
Also applies to: 92-92, 94-94, 101-104, 106-110
🤖 Prompt for AI Agents
In src/renderer/extensions/vueNodes/widgets/components/form/FormSelectButton.vue
around lines 71-83 (also review uses at 92, 94, 101-104, 106-110), add a null
guard to getOptionValue so it treats null the same as non-object (e.g. check
option !== null before accessing properties) to avoid runtime NPEs; and for
isSelected replace the String(...) comparison with a strict equality comparison
between the derived optionValue and props.modelValue (use ===) unless you
explicitly want cross-type matching — if you keep String conversion, add a clear
comment explaining the trade-off; apply these changes to all the listed
occurrences.
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 3.2 MB (baseline 3.21 MB) • 🟢 -11.6 kBMain entry bundles and manifests
Status: 3 added / 3 removed Graph Workspace — 974 kB (baseline 929 kB) • 🔴 +45.2 kBGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 1 added / 1 removed Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 6 added / 6 removed UI Components — 169 kB (baseline 169 kB) • 🔴 +162 BReusable component library chunks
Status: 9 added / 9 removed Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 3 added / 3 removed Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 1 added / 1 removed Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Status: 5 added / 5 removed Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 BBundles that do not match a named category
Status: 23 added / 23 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: 1
🧹 Nitpick comments (1)
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)
3-3: AlignhideLayoutFieldinjection type with provider and desired reactivityRight now
hideLayoutFieldis injected as a plainboolean, and the template usesv-if="!hideLayoutField". This is fine if the provider always passes a non‑reactive boolean and you don’t expect it to change over time.If the provider instead passes a
Ref<boolean>(common when wiring it to a store or reactive state),hideLayoutFieldhere will actually be an object;!hideLayoutFieldwill then befalseregardless of the ref’s internal value, so the label block will always be hidden. Also, injection of primitives is not reactive unless you explicitly pass a ref.To avoid subtle mismatches:
- If you only need a static flag, ensure the provider passes a plain boolean.
- If you need reactive behavior, inject a ref and rely on template unwrapping, e.g.:
-import { inject } from 'vue' +import { inject, type Ref } from 'vue' -const hideLayoutField = inject<boolean>('hideLayoutField', false) +const hideLayoutField = inject<Ref<boolean>>('hideLayoutField')And in the template keep:
v-if="!hideLayoutField"since Vue will unwrap the
Refautomatically in the template.Also applies to: 13-13, 20-23
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/components/TopMenuSection.vue(3 hunks)src/locales/en/main.json(1 hunks)src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/locales/en/main.json
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/*.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 conventionsFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/*.{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.jsonFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vue**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/*.{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 codebaseFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/**/{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.jsonFiles:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/components/TopMenuSection.vuesrc/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 componentsFiles:
src/components/TopMenuSection.vuesrc/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 packageFiles:
src/components/TopMenuSection.vuesrc/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 stringsFiles:
src/components/TopMenuSection.vue🧠 Learnings (11)
📚 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 provide/inject for dependency injectionApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 provide/inject for dependency injection in Vue componentsApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize provide/inject for dependency injection in Vue 3Applied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 APIApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Leverage VueUse functions for performance-enhancing utilitiesApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Use setup() function for component logic in Vue 3 Composition APIApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 logicApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 stylesApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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} : Use es-toolkit for utility functions instead of other utility librariesApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 PopoverApplied to files:
src/components/TopMenuSection.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue filesApplied to files:
src/components/TopMenuSection.vue🪛 ESLint
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
[error] 3-3: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
src/components/TopMenuSection.vue
[error] 85-85: Unable to resolve path to module '@/stores/workspace/rightSidePanelStore'.
(import-x/no-unresolved)
[error] 86-86: Unable to resolve path to module '@/stores/workspaceStore'.
(import-x/no-unresolved)
[error] 87-87: Unable to resolve path to module '@/utils/envUtil'.
(import-x/no-unresolved)
🔇 Additional comments (1)
src/components/TopMenuSection.vue (1)
107-115: Translation key verified successfully.The translation key
'rightSidePanel.togglePanel'exists insrc/locales/en/main.json(line 2236) with the value "Toggle properties panel". The implementation correctly follows Vue 3 Composition API patterns and satisfies all coding guidelines.
| <IconButton | ||
| v-if="!isRightSidePanelOpen" | ||
| v-tooltip.bottom="rightSidePanelTooltipConfig" | ||
| type="transparent" | ||
| size="sm" | ||
| class="mr-2 transition-colors duration-200 ease-in-out hover:bg-secondary-background-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background" | ||
| :aria-pressed="isRightSidePanelOpen" | ||
| :aria-label="t('rightSidePanel.togglePanel')" | ||
| @click="toggleRightSidePanel" | ||
| > | ||
| <i | ||
| class="icon-[lucide--panel-right] block size-4 text-muted-foreground" | ||
| /> | ||
| </IconButton> |
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.
Remove aria-pressed or keep button always visible for consistency.
The button is only rendered when the panel is closed (v-if="!isRightSidePanelOpen"), which means aria-pressed will always be false when the button is visible. This doesn't follow accessibility best practices for toggle buttons.
Consider one of these approaches:
- Recommended: Remove the
aria-pressedattribute since the button's visibility already indicates state - Alternative: Keep the button always visible (like the queue history button on lines 23-44) and toggle
aria-pressedbetween true/false
Apply this diff to remove the unnecessary aria-pressed attribute:
<IconButton
v-if="!isRightSidePanelOpen"
v-tooltip.bottom="rightSidePanelTooltipConfig"
type="transparent"
size="sm"
class="mr-2 transition-colors duration-200 ease-in-out hover:bg-secondary-background-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background"
- :aria-pressed="isRightSidePanelOpen"
:aria-label="t('rightSidePanel.togglePanel')"
@click="toggleRightSidePanel"
>📝 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.
| <IconButton | |
| v-if="!isRightSidePanelOpen" | |
| v-tooltip.bottom="rightSidePanelTooltipConfig" | |
| type="transparent" | |
| size="sm" | |
| class="mr-2 transition-colors duration-200 ease-in-out hover:bg-secondary-background-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background" | |
| :aria-pressed="isRightSidePanelOpen" | |
| :aria-label="t('rightSidePanel.togglePanel')" | |
| @click="toggleRightSidePanel" | |
| > | |
| <i | |
| class="icon-[lucide--panel-right] block size-4 text-muted-foreground" | |
| /> | |
| </IconButton> | |
| <IconButton | |
| v-if="!isRightSidePanelOpen" | |
| v-tooltip.bottom="rightSidePanelTooltipConfig" | |
| type="transparent" | |
| size="sm" | |
| class="mr-2 transition-colors duration-200 ease-in-out hover:bg-secondary-background-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background" | |
| :aria-label="t('rightSidePanel.togglePanel')" | |
| @click="toggleRightSidePanel" | |
| > | |
| <i | |
| class="icon-[lucide--panel-right] block size-4 text-muted-foreground" | |
| /> | |
| </IconButton> |
🤖 Prompt for AI Agents
In src/components/TopMenuSection.vue around lines 47 to 60, the IconButton is
conditionally rendered only when the right side panel is closed so aria-pressed
will always be false; remove the unnecessary :aria-pressed binding to avoid a
misleading toggle attribute, keeping the rest of the props and event handler
intact (or alternatively render the button unconditionally and keep
:aria-pressed toggling if you prefer the always-visible pattern).
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
🧹 Nitpick comments (1)
src/components/rightSidePanel/parameters/SidePanelSearch.vue (1)
35-52: Consider simplifying the cleanup mechanism.The cleanup logic uses multiple state variables (
isCleanup,cleanupFn) to coordinate race conditions. While functional, this complexity could make future maintenance more challenging.Consider using an AbortController pattern if the searcher supports it, or documenting the cleanup flow more explicitly for future maintainers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/rightSidePanel/parameters/SidePanelSearch.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/rightSidePanel/parameters/SidePanelSearch.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/**/*.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 conventionsFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/**/*.{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.jsonFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vue**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/components/rightSidePanel/parameters/SidePanelSearch.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/**/*.{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 codebaseFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/**/{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/SidePanelSearch.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/**/{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.jsonFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/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 componentsFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/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 packageFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vuesrc/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 stringsFiles:
src/components/rightSidePanel/parameters/SidePanelSearch.vue🧠 Learnings (5)
📚 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 DrawerApplied to files:
src/components/rightSidePanel/parameters/SidePanelSearch.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3Applied to files:
src/components/rightSidePanel/parameters/SidePanelSearch.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Leverage VueUse functions for performance-enhancing utilitiesApplied to files:
src/components/rightSidePanel/parameters/SidePanelSearch.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 stateApplied to files:
src/components/rightSidePanel/parameters/SidePanelSearch.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 stylesApplied to files:
src/components/rightSidePanel/parameters/SidePanelSearch.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). (3)
- GitHub Check: setup
- GitHub Check: test
- GitHub Check: lint-and-format
🔇 Additional comments (2)
src/components/rightSidePanel/parameters/SidePanelSearch.vue (2)
1-18: LGTM! Clean imports and Vue 3.5 prop definitions.The component correctly uses Vue 3.5 style prop declarations with
defineProps<T>()andwithDefaults, follows VueUse patterns withrefDebounced, and imports thecnutility for proper class name merging.
20-28: LGTM! Proper reactive state and debouncing.The state management correctly uses
defineModelfor two-way binding,reffor internal state, andrefDebouncedfrom VueUse for the 700ms debounce. The watch effectively tracks loading state by comparing the immediate and debounced values.
| void props | ||
| .searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb)) | ||
| .finally(() => { | ||
| if (!isCleanup) isQuerying.value = 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.
Add error handling for the searcher promise.
The searcher promise lacks error handling. If it rejects, it will result in an unhandled promise rejection, potentially causing silent failures and degraded user experience.
Apply this diff to add error handling:
- void props
- .searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb))
- .finally(() => {
- if (!isCleanup) isQuerying.value = false
- })
+ void props
+ .searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb))
+ .catch((error) => {
+ console.error('Search error:', error)
+ })
+ .finally(() => {
+ if (!isCleanup) isQuerying.value = false
+ })📝 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.
| void props | |
| .searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb)) | |
| .finally(() => { | |
| if (!isCleanup) isQuerying.value = false | |
| }) | |
| void props | |
| .searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb)) | |
| .catch((error) => { | |
| console.error('Search error:', error) | |
| }) | |
| .finally(() => { | |
| if (!isCleanup) isQuerying.value = false | |
| }) |
🤖 Prompt for AI Agents
In src/components/rightSidePanel/parameters/SidePanelSearch.vue around lines 45
to 49, the promise returned by props.searcher is missing error handling; add a
.catch handler to the promise chain to handle rejections (e.g., log the error or
emit an error event), ensure isQuerying.value is set to false in the catch (so
UI state is cleared on failure), and still run the existing cleanup logic
(invoke cleanupFn if set) before or after logging; keep the .finally to preserve
current finalization behavior or move the isQuerying reset into both catch and
finally to guarantee consistent state.
| <label | ||
| :class=" | ||
| cn( | ||
| 'h-8 bg-zinc-500/20 rounded-lg outline outline-offset-[-1px] outline-node-component-border transition-all duration-150', |
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.
Replace arbitrary color with semantic design token.
The bg-zinc-500/20 class uses an arbitrary Tailwind color instead of a semantic token from the design system. As per coding guidelines, use semantic values from style.css (e.g., bg-node-component-surface or similar).
Replace with an appropriate semantic background token from your design system, for example:
- 'h-8 bg-zinc-500/20 rounded-lg outline outline-offset-[-1px] outline-node-component-border transition-all duration-150',
+ 'h-8 bg-component-background rounded-lg outline outline-offset-[-1px] outline-node-component-border transition-all duration-150',As per coding guidelines for **/*.{vue,html}: Never use arbitrary Tailwind colors—use semantic values from the theme.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/components/rightSidePanel/parameters/SidePanelSearch.vue around line 59,
the class list uses an arbitrary Tailwind color `bg-zinc-500/20`; replace it
with the design-system semantic background token (for example
`bg-node-component-surface` or the equivalent token defined in style.css) so the
component uses a semantic color class instead of an arbitrary one; ensure the
semantic class exists in the theme (or add it to style.css) and keep the rest of
the utility classes unchanged.
AustinMroz
left a 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.
Nice!
| const searchQuery = defineModel<string>({ default: '' }) | ||
|
|
||
| const isQuerying = ref(false) | ||
| const debouncedSearchQuery = refDebounced(searchQuery, 700, { |
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.
| const debouncedSearchQuery = refDebounced(searchQuery, 700, { | |
| const debouncedSearchQuery = refDebounced(searchQuery, 100, { |
700 ms feels super unresponsive here. Can we lower it?
| <div class="space-y-4 rounded-lg bg-interface-surface px-4"> | ||
| <div | ||
| v-for="({ widget, node }, index) in widgets" | ||
| :key="`widget-${index}-${widget.name}`" | ||
| class="widget-item flex flex-col gap-1.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.
| <div class="space-y-4 rounded-lg bg-interface-surface px-4"> | |
| <div | |
| v-for="({ widget, node }, index) in widgets" | |
| :key="`widget-${index}-${widget.name}`" | |
| class="widget-item flex flex-col gap-1.5" | |
| <div class="space-y-4 rounded-lg bg-interface-surface px-4 | |
| grid grid-cols-[minmax(80px,max-content)_minmax(125px,auto)]"> | |
| <div | |
| v-for="({ widget, node }, index) in widgets" | |
| :key="`widget-${index}-${widget.name}`" | |
| class="widget-item gap-1.5 group col-span-full grid grid-cols-subgrid items-stretch" |
Looks like this PR got shoved a bit by the grid widgets change. I don't quite match Alex's wizardy, but this is enough to make it usable
|
What about the right side positioning of the sidebar? This will obviously cause massive inconveniences for anyone that prefer to have the sidebar there, me included. There is already issues with devs not considering the right side positioned sidebar as is so this would only increase the complexity of making it usable. |
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: 0
🧹 Nitpick comments (2)
src/components/rightSidePanel/parameters/TabParameters.vue (2)
31-48: Optionally skip empty widget sections and simplify mappingCurrently every node becomes a section, even when it has no visible widgets, and
shownWidgetsis always an array so the optional chaining/nullish coalescing is unnecessary. You can slightly simplify and avoid rendering empty sections like this:const widgetsSectionDataList = computed(() => { const list: { widgets: { node: LGraphNode; widget: IBaseWidget }[] node: LGraphNode }[] = [] for (const node of props.nodes) { - const shownWidgets: IBaseWidget[] = [] + const widgets: IBaseWidget[] = [] for (const widget of node.widgets ?? []) { if (widget.options?.canvasOnly || widget.options?.hidden) continue - shownWidgets.push(widget) + widgets.push(widget) } - list.push({ - widgets: shownWidgets?.map((widget) => ({ node, widget })) ?? [], - node - }) + if (widgets.length > 0) { + list.push({ + widgets: widgets.map((widget) => ({ node, widget })), + node + }) + } } return list })
57-88: Drop unnecessaryasynconsearcher(and minor search behavior notes)
searchernever awaits anything, so marking itasynconly wraps the result in a Promise and may triggerrequire-await-style lint errors. You can make it synchronous:-async function searcher(query: string) { +function searcher(query: string) {If you ever revisit search behavior, you might also consider tokenizing with
/\s+/to handle multiple whitespace characters more robustly, and (if SidePanelSearch doesn’t already do this) initializingsearchedWidgetsSectionDataListwith the fullwidgetsSectionDataListso the panel isn’t empty before the first search call.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/rightSidePanel/parameters/TabParameters.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/rightSidePanel/parameters/TabParameters.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/rightSidePanel/parameters/TabParameters.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/**/*.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 conventionsFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/**/*.{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.jsonFiles:
src/components/rightSidePanel/parameters/TabParameters.vue**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/components/rightSidePanel/parameters/TabParameters.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/rightSidePanel/parameters/TabParameters.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/**/*.{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 codebaseFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/**/{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/TabParameters.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/**/{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.jsonFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/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 componentsFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/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 packageFiles:
src/components/rightSidePanel/parameters/TabParameters.vuesrc/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 stringsFiles:
src/components/rightSidePanel/parameters/TabParameters.vue🧠 Learnings (1)
📚 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 panelsApplied to files:
src/components/rightSidePanel/parameters/TabParameters.vue🪛 ESLint
src/components/rightSidePanel/parameters/TabParameters.vue
[error] 1-1: Resolve error: EACCES: permission denied, open '/vLoVvxhSAX'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at processBodyStatement (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:9:31)
at Program (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/zzkdVpssJV'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-unresolved.js:31:34)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/QxUqOwFWKH'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at importType (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/import-type.js:126:63)
at checkImportForRelativePackage (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:15:38)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:59:40
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/muxqzJhofu'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at checkDefault (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 1-1: Resolve error: EACCES: permission denied, open '/oEtCqzTEFI'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-useless-path-segments.js:58:34
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 19-19: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
[error] 24-24: Unable to resolve path to module './SectionWidgets.vue'.
(import-x/no-unresolved)
[error] 25-25: Unable to resolve path to module './SidePanelSearch.vue'.
(import-x/no-unresolved)
⏰ 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 (1)
src/components/rightSidePanel/parameters/TabParameters.vue (1)
1-16: Template wiring and default-collapse condition look solidSidePanelSearch and SectionWidgets are wired correctly, and the
default-collapsecondition cleanly distinguishes “no active search” via ref unwrapping/equality in the template; no changes needed here.
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: 0
♻️ Duplicate comments (2)
src/components/rightSidePanel/NodePropertiesPanel.vue (2)
98-115: Remove duplicated static classes and rely solely oncn()The first
IconButtonfor subgraph editing defines base classes both inclassand withincn():class="bg-secondary-background hover:bg-secondary-background-hover" :class=" cn( 'bg-secondary-background hover:bg-secondary-background-hover', isEditingSubgraph ? 'bg-secondary-background-selected' : 'bg-secondary-background' ) "To avoid duplicate and conflicting classes and to follow the “use
cnfor class merging” guideline, drop the staticclassattribute and keep only thecncall:- <IconButton + <IconButton v-if="isSubgraphNode" type="transparent" size="sm" - class="bg-secondary-background hover:bg-secondary-background-hover" :class=" cn( 'bg-secondary-background hover:bg-secondary-background-hover', isEditingSubgraph ? 'bg-secondary-background-selected' : 'bg-secondary-background' ) "
46-52: Localize the'Node'fallback inpanelTitleThe fallback
'Node'is still a hardcoded user-facing string; everything else here already goes through i18n.Consider switching to a dedicated key, e.g.:
- return selectedNode.value.title || selectedNode.value.type || 'Node' + return ( + selectedNode.value.title || + selectedNode.value.type || + t('rightSidePanel.unnamedNode') + )and add
rightSidePanel.unnamedNodetosrc/locales/en/main.json(and other locales as appropriate).
🧹 Nitpick comments (2)
src/components/LiteGraphCanvasSplitterOverlay.vue (1)
163-167: Consider avoiding style-based selectors for hiding guttersThe selector
:deep(.side-bar-panel[style*='display: none'] + .p-splitter-gutter)couples behavior to the exact inlinestylestring, which is brittle to formatting changes and harder to reason about.If feasible, prefer a class-based approach, e.g. toggling a
.is-hiddenclass on the sidebar panel and keying the CSS off that class instead of thestyleattribute.src/stores/workspace/rightSidePanelStore.ts (1)
18-41: Store API is clean; clarifytogglePanelbehavior w.r.t. subgraph modeState shape and actions (
openPanel,closePanel,togglePanel,setActiveTab) are well-structured and typed.One behavioral edge case:
togglePanel()flipsisOpenbut does not resetisEditingSubgraph, whereasclosePanel()does. That means:
- Open via
openPanel('subgraph')→isEditingSubgraph = true- Toggle to close →
isOpen = false,isEditingSubgraphstilltrue- Toggle to reopen → panel comes back already in subgraph-edit mode
If the intended UX is “closing the panel exits subgraph edit mode”, consider delegating to
closePanel()when toggling from open → closed, e.g.:function togglePanel() { if (isOpen.value) { closePanel() } else { isOpen.value = true } }If the current sticky behavior is intentional, maybe add a short comment to document it.
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: 0
♻️ Duplicate comments (2)
src/components/rightSidePanel/RightSidePanel.vue (2)
46-52: Localize the'Node'fallback title.The literal string
'Node'on line 49 should be localized using i18n to maintain consistency with the codebase's internationalization standards.- return selectedNode.value.title || selectedNode.value.type || 'Node' + return ( + selectedNode.value.title || + selectedNode.value.type || + t('rightSidePanel.unnamedNode') + )Add the key to
src/locales/en/main.json.
99-115: Remove duplicate classes from static class attribute.Lines 103 and 106 both specify the same background classes. Per coding guidelines, class merging should be handled exclusively through
cn():<IconButton v-if="isSubgraphNode" type="transparent" size="sm" - class="bg-secondary-background hover:bg-secondary-background-hover" :class=" cn( 'bg-secondary-background hover:bg-secondary-background-hover', isEditingSubgraph ? 'bg-secondary-background-selected' : 'bg-secondary-background' ) " @click="isEditingSubgraph = !isEditingSubgraph" >
🧹 Nitpick comments (2)
src/components/graph/GraphCanvas.vue (1)
116-116: Consider renaming the import alias for consistency.The component is imported as
NodePropertiesPanelbut the source file isRightSidePanel.vue. This naming mismatch may cause confusion during maintenance. Consider aligning the import alias with the file name:-import NodePropertiesPanel from '@/components/rightSidePanel/RightSidePanel.vue' +import RightSidePanel from '@/components/rightSidePanel/RightSidePanel.vue'And update the template reference accordingly.
src/components/rightSidePanel/subgraph/SubgraphEditor.vue (1)
59-61: Remove unnecessaryasynckeyword.The
searcherfunction performs a synchronous assignment and doesn't useawait. Theasynckeyword is unnecessary:-async function searcher(query: string) { +function searcher(query: string) { searchQuery.value = query }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/components/graph/GraphCanvas.vue(2 hunks)src/components/rightSidePanel/RightSidePanel.vue(1 hunks)src/components/rightSidePanel/subgraph/SubgraphEditor.vue(9 hunks)src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue(3 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/*.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 conventionsFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/*.{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.jsonFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/*.{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 codebaseFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/{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.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/**/{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.jsonFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/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 componentsFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/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 packageFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vuesrc/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 stringsFiles:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphNodeWidget.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue🧠 Learnings (20)
📚 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 panelsApplied to files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.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 DrawerApplied to files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3Applied to files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.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 guideApplied 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 : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.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 panelsApplied to files:
src/components/rightSidePanel/RightSidePanel.vuesrc/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.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 conventionsApplied to files:
src/components/rightSidePanel/RightSidePanel.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.vue : Never use `:class="[]"` to merge class names - always use `import { cn } from '@/utils/tailwindUtil'` for class merging in Vue templatesApplied to files:
src/components/rightSidePanel/RightSidePanel.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{vue,html} : Never use `dark:` or `dark-theme:` Tailwind variants - instead use semantic values from `style.css` theme, e.g. `bg-node-component-surface`Applied to files:
src/components/rightSidePanel/RightSidePanel.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.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 ToggleSwitchApplied to files:
src/components/rightSidePanel/subgraph/SubgraphEditor.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Applied to files:
src/components/rightSidePanel/subgraph/SubgraphEditor.vuesrc/components/graph/GraphCanvas.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 stateApplied 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 ref/reactive for state management in Vue 3 Composition APIApplied to files:
src/components/rightSidePanel/subgraph/SubgraphEditor.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Leverage VueUse functions for performance-enhancing utilitiesApplied 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,ts} : Leverage VueUse functions for performance-enhancing stylesApplied to files:
src/components/rightSidePanel/subgraph/SubgraphEditor.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Use watch and watchEffect for side effects in Vue 3Applied 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 APIApplied 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 watch and watchEffect for side effectsApplied 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 : Replace PrimeVue Dropdown component with SelectApplied to files:
src/components/graph/GraphCanvas.vue🪛 ESLint
src/components/rightSidePanel/RightSidePanel.vue
[error] 1-1: Resolve error: EACCES: permission denied, open '/eiBZwYxeye'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at processBodyStatement (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:9:31)
at Program (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/RDJSgFXKTL'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-unresolved.js:31:34)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/LrTZkGsaJS'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at importType (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/import-type.js:126:63)
at checkImportForRelativePackage (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:15:38)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:59:40
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/thGUJbBZCR'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at checkDefault (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 1-1: Resolve error: EACCES: permission denied, open '/kTfHyfbwpn'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-useless-path-segments.js:58:34
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 2-2: Unable to resolve path to module 'pinia'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'vue-i18n'.
(import-x/no-unresolved)
[error] 6-6: Unable to resolve path to module '@/components/button/IconButton.vue'.
(import-x/no-unresolved)
[error] 7-7: Unable to resolve path to module '@/components/tab/Tab.vue'.
(import-x/no-unresolved)
[error] 8-8: Unable to resolve path to module '@/components/tab/TabList.vue'.
(import-x/no-unresolved)
[error] 9-9: Unable to resolve path to module '@/lib/litegraph/src/litegraph'.
(import-x/no-unresolved)
[error] 11-11: Unable to resolve path to module '@/renderer/core/canvas/canvasStore'.
(import-x/no-unresolved)
[error] 12-12: Unable to resolve path to module '@/stores/workspace/rightSidePanelStore'.
(import-x/no-unresolved)
[error] 13-13: Unable to resolve path to module '@/utils/litegraphUtil'.
(import-x/no-unresolved)
[error] 14-14: Unable to resolve path to module '@/utils/tailwindUtil'.
(import-x/no-unresolved)
[error] 16-16: Unable to resolve path to module './info/TabInfo.vue'.
(import-x/no-unresolved)
[error] 17-17: Unable to resolve path to module './parameters/TabParameters.vue'.
(import-x/no-unresolved)
[error] 18-18: Unable to resolve path to module './settings/TabSettings.vue'.
(import-x/no-unresolved)
[error] 19-19: Unable to resolve path to module './subgraph/SubgraphEditor.vue'.
(import-x/no-unresolved)
src/components/rightSidePanel/subgraph/SubgraphEditor.vue
[error] 2-2: Unable to resolve path to module '@vueuse/core'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module 'primevue/button'.
(import-x/no-unresolved)
[error] 32-32: Unable to resolve path to module '../layout/SidePanelSearch.vue'.
(import-x/no-unresolved)
[error] 33-33: Unable to resolve path to module './SubgraphNodeWidget.vue'.
(import-x/no-unresolved)
src/components/graph/GraphCanvas.vue
[error] 116-116: Unable to resolve path to module '@/components/rightSidePanel/RightSidePanel.vue'.
(import-x/no-unresolved)
⏰ 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). (2)
- GitHub Check: setup
- GitHub Check: test
🔇 Additional comments (7)
src/components/graph/GraphCanvas.vue (1)
39-41: LGTM!The right-side panel slot follows the established pattern used by other UI slots in the template.
src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue (1)
1-58: LGTM!The component correctly uses
cn()for class merging as per coding guidelines, and the newclassprop withClassValuetype provides good flexibility. The styling uses semantic tokens appropriately.src/components/rightSidePanel/RightSidePanel.vue (2)
82-86: LGTM!The
watchEffectcorrectly ensures the active tab falls back to the first available tab when the current selection becomes invalid.
145-170: LGTM!The content rendering logic correctly handles the three states: subgraph editing, no selection, and tab-based content display.
src/components/rightSidePanel/subgraph/SubgraphEditor.vue (3)
245-282: LGTM!The "shown" widgets section correctly implements draggable functionality that's disabled during search, and properly uses i18n for labels.
284-325: LGTM!The hidden widgets and recommended sections follow the same pattern as the shown section. The "Show Recommended" button properly integrates with the subgraph editing workflow.
229-235: LGTM!The debounced watch on
filteredActiveis appropriate for preventing rapid re-initialization of the draggable list during filtering operations.
|
Updating Playwright Expectations |
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
🧹 Nitpick comments (4)
src/components/LiteGraphCanvasSplitterOverlay.vue (4)
103-125: Store wiring for right-side panel looks good; consider consistent store usage
useRightSidePanelStore+rightSidePanelVisible = computed(() => rightSidePanelStore.isOpen)is clean and matches the pattern from other stores. UsinguseSettingStore()forComfy.Sidebar.Location/Comfy.Sidebar.UnifiedWidthalso aligns with the settings-store guideline. Based on learnings, this is the intended way to retrieve settings.One optional improvement:
useSidebarTabStore()is called separately in multiple computeds; you might want to grab it once (e.g.,const sidebarTabStore = useSidebarTabStore()) for clarity and to avoid repeated calls, matching how you handledrightSidePanelStore.
129-135: RevisitsidebarStateKeyvssplitterRefreshKeyresponsibilities
sidebarStateKeychanges withunifiedWidthandactiveSidebarTabId, whilesplitterRefreshKeytoggles between'main-splitter-with-right-panel'and'main-splitter'based solely onrightSidePanelVisible.Conceptually this splits concerns well (state persistence vs forced recomputation), but it does mean that:
- Layouts with and without the right panel share the same persisted sizes keyed only by sidebar state, and
- You still pay the cost of a full remount on every toggle of the right panel.
If you observe jank or unexpected widths when toggling the right panel, consider:
- Encoding the presence of the right panel in the
state-keyinstead of usingkey, or- Using a distinct
state-keywhen the right panel is visible and droppingkeyentirely, if PrimeVue’s state handling is robust for dynamic panel counts.Please double‑check the runtime behavior (sizes, gutter positions) when toggling the right panel a few times and after reload with persisted state; adjust
state-keyvskeyif you see inconsistencies.Also applies to: 140-144
166-170: Attribute‑selector gutter hiding is somewhat brittle but acceptableThe CSS hides gutters when the sidebar panel’s inline style contains
display: none. This works with the current Vue binding but couples behavior to an inline style string, which could break if the style shape changes (e.g., multiple properties, different ordering).If you want a more robust approach, you could:
- Toggle a class on the panel (
:class="{ 'is-hidden': !sidebarPanelVisible }") and target that instead of[style*='display: none'].
146-150:getSplitterGutterClassescomputed is a no-op that can be simplifiedThe computed always returns an empty string and is used for
:pt:gutter="getSplitterGutterClasses". Since PrimeVue'spt:gutterdoes accept string values directly (as confirmed by the nested Splitter's usage of:pt:gutter="'rounded-tl-lg rounded-tr-lg ' + ..."in the same file), this indirection is unnecessary.Replace
:pt:gutter="getSplitterGutterClasses"with:pt:gutter="''"and remove the computed property, or keep the computed if you anticipate adding dynamic gutter classes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (21)
browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.pngis excluded by!**/*.pngbrowser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.pngis excluded by!**/*.png
📒 Files selected for processing (1)
src/components/LiteGraphCanvasSplitterOverlay.vue(6 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/LiteGraphCanvasSplitterOverlay.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/LiteGraphCanvasSplitterOverlay.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/*.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 conventionsFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/*.{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.jsonFiles:
src/components/LiteGraphCanvasSplitterOverlay.vue**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/components/LiteGraphCanvasSplitterOverlay.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/LiteGraphCanvasSplitterOverlay.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/*.{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 codebaseFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/**/{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.jsonFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/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 componentsFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/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 packageFiles:
src/components/LiteGraphCanvasSplitterOverlay.vuesrc/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 stringsFiles:
src/components/LiteGraphCanvasSplitterOverlay.vue🧠 Learnings (4)
📚 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 DrawerApplied to files:
src/components/LiteGraphCanvasSplitterOverlay.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 PopoverApplied to files:
src/components/LiteGraphCanvasSplitterOverlay.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue filesApplied to files:
src/components/LiteGraphCanvasSplitterOverlay.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{ts,tsx,vue} : Use `await settingStore.set('Comfy.SomeSetting', newValue)` to update settings in TypeScript/Vue filesApplied to files:
src/components/LiteGraphCanvasSplitterOverlay.vue
| <Splitter | ||
| key="main-splitter-stable" | ||
| :key="splitterRefreshKey" | ||
| class="splitter-overlay flex-1 overflow-hidden" | ||
| :pt:gutter="sidebarPanelVisible ? '' : 'hidden'" | ||
| :state-key="sidebarStateKey || 'main-splitter'" | ||
| :pt:gutter="getSplitterGutterClasses" | ||
| :state-key="sidebarStateKey" | ||
| state-storage="local" |
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:
cat -n src/components/LiteGraphCanvasSplitterOverlay.vue | head -100Repository: Comfy-Org/ComfyUI_frontend
Length of output: 3799
🏁 Script executed:
# Search for splitterRefreshKey, getSplitterGutterClasses, and sidebarStateKey definitions
rg -n "splitterRefreshKey|getSplitterGutterClasses|sidebarStateKey" src/components/LiteGraphCanvasSplitterOverlay.vue -A 3Repository: Comfy-Org/ComfyUI_frontend
Length of output: 757
🏁 Script executed:
# Check the rightSidePanelVisible state usage
rg -n "rightSidePanelVisible" src/components/LiteGraphCanvasSplitterOverlay.vue -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 686
🏁 Script executed:
# Look for any rightSidePanelStore usage
rg -n "rightSidePanelStore" src/components/LiteGraphCanvasSplitterOverlay.vue -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 825
🏁 Script executed:
# Search for other Splitter usage patterns with state-key
rg -n "state-key.*splitter|Splitter.*state-key" --type vue -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 97
🏁 Script executed:
# Look for any dynamic panel handling or state reset logic
rg -n "stateKey|stateStorage" src/components/ --type vue -B 1 -A 1Repository: Comfy-Org/ComfyUI_frontend
Length of output: 97
🏁 Script executed:
# Check rightSidePanelStore implementation for isOpen property
cat -n src/stores/workspace/rightSidePanelStore.ts 2>/dev/null || echo "File may not exist yet"Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1629
🏁 Script executed:
# Search for PrimeVue Splitter package.json or docs reference
fd -t f "package.json" | xargs grep -l "primevue" | head -1 | xargs cat | grep -A 5 "primevue"Repository: Comfy-Org/ComfyUI_frontend
Length of output: 362
🏁 Script executed:
# Search for any comments or error handling related to splitter state mismatch
rg -n "splitter|state.*panel|panel.*state" src/components/LiteGraphCanvasSplitterOverlay.vue -iRepository: Comfy-Org/ComfyUI_frontend
Length of output: 1752
🏁 Script executed:
# Check if there's any logic that resets or handles stale state
rg -n "localStorage|stateStorage" src/ -i --type ts --type vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 97
🏁 Script executed:
# Look for PrimeVue Splitter API documentation or type definitions
fd -name "*.d.ts" -o -name "*.ts" | xargs grep -l "Splitter" | head -5 | xargs cat | grep -A 10 "state-key\|stateKey" | head -30Repository: Comfy-Org/ComfyUI_frontend
Length of output: 300
🏁 Script executed:
# Check if there's any migration or reset logic when panel visibility changes
rg -n "rightSidePanelVisible|splitterRefreshKey" src/components/LiteGraphCanvasSplitterOverlay.vue -B 5 -A 5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1543
🏁 Script executed:
# Get the full sidebarStateKey computation to verify it doesn't reference rightSidePanelVisible
rg -n "sidebarStateKey" src/components/LiteGraphCanvasSplitterOverlay.vue -A 8Repository: Comfy-Org/ComfyUI_frontend
Length of output: 625
🏁 Script executed:
# Search for how PrimeVue Splitter handles state persistence to understand the risk
rg -n "state.*storage\|stateStorage" src/ --type tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
Include rightSidePanelVisible in the sidebarStateKey to prevent localStorage state mismatch when the right panel opens/closes.
When rightSidePanelVisible changes, splitterRefreshKey forces a Splitter remount, but sidebarStateKey remains unchanged (derived only from unifiedWidth and activeSidebarTabId). The Splitter then loads saved sizes from localStorage using the same state-key, even though the panel configuration has changed (3 panels → 4 panels, or vice versa). This causes PrimeVue to apply sizes saved for the old layout to the new layout, resulting in misaligned widths.
Consider:
- Adding
rightSidePanelVisibleto thesidebarStateKeycomputation so each configuration has its own persisted state, or - Using a separate
state-keywhen the right panel is present
Also, getSplitterGutterClasses returns an empty string; this could be simplified to a literal "" unless you expect to add dynamic classes later.
🤖 Prompt for AI Agents
In src/components/LiteGraphCanvasSplitterOverlay.vue around lines 16 to 21, the
Splitter's persisted state-key only uses unifiedWidth and activeSidebarTabId so
when rightSidePanelVisible toggles the panel count changes but the same
localStorage key is reused causing size mismatches; update the computation of
sidebarStateKey to include rightSidePanelVisible (or switch to a different
state-key when the right panel is present) so each layout configuration has its
own persisted sizes, and simplify getSplitterGutterClasses to return a literal
"" if no dynamic classes are needed.
| <!-- Right Side Panel - independent of sidebar --> | ||
| <SplitterPanel | ||
| v-if="rightSidePanelVisible" | ||
| class="right-side-panel pointer-events-auto" | ||
| :min-size="15" | ||
| :size="20" | ||
| > | ||
| <slot name="right-side-panel" /> | ||
| </SplitterPanel> |
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:
find src -name "LiteGraphCanvasSplitterOverlay.vue" -type fRepository: Comfy-Org/ComfyUI_frontend
Length of output: 119
🏁 Script executed:
wc -l src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 123
🏁 Script executed:
cat -n src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 7416
🏁 Script executed:
head -n 220 src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 7416
🏁 Script executed:
cat src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 5988
🏁 Script executed:
sed -n '170,185p' src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 338
🏁 Script executed:
sed -n '60,180p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 4310
🏁 Script executed:
sed -n '1,100p' src/components/LiteGraphCanvasSplitterOverlay.vue | tail -n 50Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1545
🏁 Script executed:
grep -n "sidebarLocation" src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 613
🏁 Script executed:
sed -n '1,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2581
🏁 Script executed:
grep -n "topPositionedSidebar\|leftPositionedSidebar\|rightPositionedSidebar" src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
grep -rn "sidebarLocation.*right\|right.*sidebar" src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 377
🏁 Script executed:
sed -n '1,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2581
🏁 Script executed:
head -n 70 src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2293
🏁 Script executed:
grep -A5 -B5 "topPositionedSidebar\|leftPositionedSidebar" src/components/LiteGraphCanvasSplitterOverlay.vue | head -n 30Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
sed -n '20,45p' src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 886
🏁 Script executed:
sed -n '15,50p' src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 1206
🏁 Script executed:
grep -A3 "sidebarLocation" src/components/LiteGraphCanvasSplitterOverlay.vue | head -n 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 377
🏁 Script executed:
python3 << 'EOF'
with open('src/components/LiteGraphCanvasSplitterOverlay.vue', 'r') as f:
content = f.read()
# Find the props section
import re
props_match = re.search(r'defineProps.*?\{.*?\}(?=\s*[\n);])', content, re.DOTALL)
if props_match:
print(props_match.group(0)[:1500])
EOFRepository: Comfy-Org/ComfyUI_frontend
Length of output: 156
🏁 Script executed:
ast-grep --pattern 'defineProps<$_>()'Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
grep -n "computed" src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 553
🏁 Script executed:
sed -n '20,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 1878
🏁 Script executed:
grep -rn "sidebarLocation.*=.*['\"]right" src/ --include="*.vue" --include="*.ts" | head -n 20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1420
🏁 Script executed:
grep -rn "sidebarLocation" src/ --include="*.vue" --include="*.ts" | grep -E "(type|interface|as const|enum)" | head -n 20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
find src -name "*store*" -o -name "*settings*" | grep -E "\.(ts|js|vue)$"Repository: Comfy-Org/ComfyUI_frontend
Length of output: 96
🏁 Script executed:
grep -rn "sidebarLocation" src/stores src/composables --include="*.ts" 2>/dev/null | head -n 20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
find . -name "*.test.*" -o -name "*.spec.*" | grep -i "LiteGraphCanvasSplitterOverlay\|splitter"Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
find . -path "*/node_modules" -prune -o -type f -name "*.spec.*" -print | head -n 20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 920
🏁 Script executed:
sed -n '60,120p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2309
🏁 Script executed:
sed -n '84,120p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 1502
🏁 Script executed:
find src/components -name "*Sidebar*" -o -name "*sidebar*" | head -n 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 534
🏁 Script executed:
ls -la src/components/ | grep -i sidebarRepository: Comfy-Org/ComfyUI_frontend
Length of output: 127
🏁 Script executed:
grep -rn "LiteGraphCanvasSplitterOverlay" src/ --include="*.vue" --include="*.ts" | grep -v "import"Repository: Comfy-Org/ComfyUI_frontend
Length of output: 240
🏁 Script executed:
grep -rn "LiteGraphCanvasSplitterOverlay" src/ --include="*.vue" -A5 -B2 | head -n 40Repository: Comfy-Org/ComfyUI_frontend
Length of output: 2044
🏁 Script executed:
grep -n "rightPositionedSidebar\|const.*sidebar\|computed.*sidebar" src/components/LiteGraphCanvasSplitterOverlay.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 217
Right-side panel can coexist with right-positioned sidebar, creating layout constraints
When sidebarLocation === 'right' and rightSidePanelVisible === true, both panels appear in the same horizontal splitter:
- Center panel (size: 80) + right sidebar (size: 20, min-size: 10) + right-side-panel (size: 20, min-size: 15) = potential overflow
Test this layout on smaller viewports to verify the main canvas remains usable and gutter handles discoverable when both right-side panels are visible. Consider whether adaptive sizing or constraints are needed when both panels are enabled.
🤖 Prompt for AI Agents
In src/components/LiteGraphCanvasSplitterOverlay.vue around lines 84-92, the
template unconditionally renders a separate right-side-panel splitter when
rightSidePanelVisible is true, which conflicts with a right-positioned sidebar
(sidebarLocation === 'right') and can overflow on small viewports; change the
rendering logic so that when sidebarLocation === 'right' you do one of: 1)
render the right-side-panel inside the sidebar slot instead of as a separate
splitter, or 2) compute adaptive :size and :min-size values so the sum of center
+ sidebar + right-side-panel never exceeds 100 (e.g. reduce right-side-panel
size/min-size when sidebar is right or viewport width is small), and ensure the
computed sizes enforce a minimum center panel width and discoverable gutter
handles; implement this by adding a small computed property that returns
size/min-size for the right-side-panel based on sidebarLocation and window width
and use that instead of hardcoded 20/15, or move the slot rendering into the
sidebar conditional when sidebarLocation === 'right'.
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
🧹 Nitpick comments (2)
src/components/graph/GraphCanvas.vue (1)
118-118: Consider aligning the import alias with the file name.The component file is named
RightSidePanel.vuebut imported asNodePropertiesPanel. This naming inconsistency can create confusion when navigating the codebase or searching for the component definition.Consider one of these approaches:
- Keep the import name consistent with the file:
import RightSidePanel from '@/components/rightSidePanel/RightSidePanel.vue'- Or rename the file to match the semantic purpose:
NodePropertiesPanel.vueNote: The ESLint error about the unresolved path is likely a false positive if
RightSidePanel.vuewas added in this PR.src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)
3-11: hideLayoutField injection is clean and backward‑compatibleUsing
inject<boolean>('hideLayoutField', false)gives you a simple, safe default so existing contexts keep showing the label when no provider is present. As an optional improvement, you might consider centralizing the injection key as a typedInjectionKey<boolean>(e.g., exported from a sharedinjectionKeys.ts) to avoid stringly‑typed keys and tighten TS checking across providers/consumers. Based on learnings, this aligns well with the provide/inject guidance.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/components/graph/GraphCanvas.vue(2 hunks)src/locales/en/main.json(1 hunks)src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue(1 hunks)src/services/litegraphService.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/locales/en/main.json
🧰 Additional context used
📓 Path-based instructions (20)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.ts**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.tssrc/**/*.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 conventionsFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/**/*.{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.jsonFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.ts**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.ts**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.tssrc/**/*.{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 codebaseFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.tssrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/services/litegraphService.tssrc/**/{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.jsonFiles:
src/components/graph/GraphCanvas.vuesrc/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vuesrc/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 componentsFiles:
src/components/graph/GraphCanvas.vuesrc/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 packageFiles:
src/components/graph/GraphCanvas.vuesrc/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 stringsFiles:
src/components/graph/GraphCanvas.vue**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
src/services/litegraphService.ts**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Use TypeScript for type safety
**/*.{ts,tsx}: Never useanytype - use proper TypeScript types
Never useas anytype assertions - fix the underlying type issueFiles:
src/services/litegraphService.tssrc/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safetyFiles:
src/services/litegraphService.ts**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
UsedefaultsByInstallVersionproperty for gradual feature rollout based on version in settings configurationFiles:
src/services/litegraphService.tssrc/**/{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 directlyFiles:
src/services/litegraphService.ts🧠 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 : Replace PrimeVue Sidebar component with DrawerApplied to files:
src/components/graph/GraphCanvas.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/graph/GraphCanvas.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 PopoverApplied to files:
src/components/graph/GraphCanvas.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 panelsApplied to files:
src/components/graph/GraphCanvas.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Applied to files:
src/components/graph/GraphCanvas.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 panelsApplied to files:
src/components/graph/GraphCanvas.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 SelectApplied to files:
src/components/graph/GraphCanvas.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 provide/inject for dependency injectionApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 provide/inject for dependency injection in Vue componentsApplied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize provide/inject for dependency injection in Vue 3Applied to files:
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.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 setupApplied to files:
src/services/litegraphService.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/**/*.{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 issuesApplied to files:
src/services/litegraphService.ts📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue filesApplied to files:
src/services/litegraphService.ts🧬 Code graph analysis (1)
src/services/litegraphService.ts (1)
src/stores/workspace/rightSidePanelStore.ts (1)
useRightSidePanelStore(10-52)🪛 ESLint
src/components/graph/GraphCanvas.vue
[error] 118-118: Unable to resolve path to module '@/components/rightSidePanel/RightSidePanel.vue'.
(import-x/no-unresolved)
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
[error] 3-3: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
src/services/litegraphService.ts
[error] 52-52: Unable to resolve path to module '@/stores/workspace/rightSidePanelStore'.
(import-x/no-unresolved)
⏰ 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: setup
- GitHub Check: lint-and-format
- GitHub Check: collect
🔇 Additional comments (3)
src/components/graph/GraphCanvas.vue (1)
41-43: The#right-side-panelslot is properly defined in the parent componentLiteGraphCanvasSplitterOverlay.vue(lines 88-93) and is conditionally rendered based onrightSidePanelVisiblefrom theuseRightSidePanelStore(). The implementation inGraphCanvas.vuecorrectly uses this slot with thev-if="showUI"condition, following the established pattern for other UI slots in the component.src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)
18-21: Conditional label rendering matches new panel behaviorGuarding the left label container with
v-if="!hideLayoutField"achieves the desired “hide label in specific contexts” behavior while leaving the right‑side slot content untouched. With the injected default offalse, this shouldn’t affect existing layouts outside the new right‑side panel usage, and no new raw user‑facing strings were added, so i18n rules stay satisfied.src/services/litegraphService.ts (1)
656-672: Right-side panel hook for “Edit Subgraph Widgets” looks correct, but confirm behaviorSwitching the callback to
useRightSidePanelStore().openPanel('subgraph')is consistent with therightSidePanelStoreAPI and should correctly flipisOpenandisEditingSubgraphso subgraph editing happens in the shared right panel instead of a dialog.Please double‑check in the UI that:
- Clicking “Edit Subgraph Widgets” opens the right panel, and
- When multiple subgraph nodes exist, the panel edits the intended subgraph (selection/active‑node state is still wired correctly after removing the old dialog flow).
| import { useNodeOutputStore } from '@/stores/imagePreviewStore' | ||
| import { ComfyNodeDefImpl } from '@/stores/nodeDefStore' | ||
| import { useSubgraphStore } from '@/stores/subgraphStore' | ||
| import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore' |
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 unresolved import for useRightSidePanelStore
ESLint is flagging this import as import-x/no-unresolved, which will break linting and likely the build. Please verify that:
src/stores/workspace/rightSidePanelStore.tsis committed, and- The import path and alias resolution (for
@/) match how other store modules are imported.
If the file lives under a different folder or name (e.g. an index.ts barrel or a different directory), update this import accordingly, or adjust the resolver/tsconfig so the path is resolvable.
Based on static analysis hints.
🧰 Tools
🪛 ESLint
[error] 52-52: Unable to resolve path to module '@/stores/workspace/rightSidePanelStore'.
(import-x/no-unresolved)
🤖 Prompt for AI Agents
In src/services/litegraphService.ts around line 52, the import of
useRightSidePanelStore is unresolved by the linter; verify that
src/stores/workspace/rightSidePanelStore.ts exists and is committed, confirm the
correct export name (default vs named) and the correct path/filename (or index
barrel), and if it lives elsewhere update the import to the correct relative or
aliased path used by other stores; if the alias @/ is misconfigured, update
tsconfig/webpack/vite path mappings to include the stores directory so the
resolver recognizes "@/stores/workspace/rightSidePanelStore".
christian-byrne
left a 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.
LGTM!
#7129) This test https://github.com/Comfy-Org/ComfyUI_frontend/blob/68274134c88d210c0929a616ceb3c4cf77aa8a9f/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts#L830-L879 started failing after #6952 https://14e0c969.comfyui-playwright-chromium.pages.dev/trace/?trace=https://14e0c969.comfyui-playwright-chromium.pages.dev/data/cf5b5bf984069c2f397270ac6c0c7e92479d3d31.zip No idea how they could be related, disabling temporarily to not mess up the CI signal on `main`. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7129-test-temporarily-mark-linkInteraction-spec-ts-as-test-case-as-fixme-2be6d73d36508172925af3e7fa681f25) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <[email protected]>
┆Issue is synchronized with this Notion page by Unito