Skip to content

Conversation

@LittleSound
Copy link
Collaborator

@LittleSound LittleSound commented Nov 26, 2025

CleanShot 2025-11-26 at 16 01 15

┆Issue is synchronized with this Notion page by Unito

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

coderabbitai bot commented Nov 26, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (18)
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Right-side panel store
src/stores/workspace/rightSidePanelStore.ts
New Pinia store managing panel visibility, active tab, subgraph editing flag, and actions: openPanel, closePanel, togglePanel, setActiveTab.
Right-side panel container & layout
src/components/rightSidePanel/RightSidePanel.vue, src/components/rightSidePanel/layout/RightPanelSection.vue, src/components/rightSidePanel/layout/SidePanelSearch.vue
New main panel component with dynamic title/tabs and controls; collapsible section component; debounced search component (SidePanelSearch).
Right-side tabs & content
src/components/rightSidePanel/parameters/TabParameters.vue, src/components/rightSidePanel/parameters/SectionWidgets.vue, src/components/rightSidePanel/settings/TabSettings.vue, src/components/rightSidePanel/info/TabInfo.vue, src/components/rightSidePanel/subgraph/SubgraphEditor.vue, src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
Added parameters/settings/info tabs and subgraph editor; widget list rendering, search/filtering, settings controls, NodeInfo wiring; SubgraphNodeWidget gains class prop and draggable UI changes.
Node help component & refactor
src/components/node/NodeHelpContent.vue, src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
New NodeHelpContent component (loading, rendered HTML, fallback tables); NodeHelpPage refactored to use NodeHelpContent.
Canvas & Graph integration
src/components/LiteGraphCanvasSplitterOverlay.vue, src/components/graph/GraphCanvas.vue
Splitter overlay updated for independent right-side panel, reactive refresh key and gutter classes; GraphCanvas renders node properties into right-side slot.
Top menu control
src/components/TopMenuSection.vue
Added top-menu toggle button and wiring to open/close the right-side panel via the store.
Search/widgets utilities
src/components/rightSidePanel/parameters/SectionWidgets.vue, src/components/rightSidePanel/layout/SidePanelSearch.vue
SectionWidgets resolves widget components and handles value updates; SidePanelSearch provides debounced query + update-key re-run and cleanup hook.
Form widgets & layout changes
src/renderer/extensions/vueNodes/widgets/components/form/FormSelectButton.vue, src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
FormSelectButton refactored to index-based selection and typed ModelValue; WidgetLayoutField injects hideLayoutField to conditionally render labels.
Subgraph dialog removal & migration
src/core/graph/subgraph/useSubgraphNodeDialog.ts, src/components/graph/selectionToolbox/ConfigureSubgraph.vue, src/composables/useCoreCommands.ts, src/services/litegraphService.ts
Removed showSubgraphNodeDialog; replaced call sites to open subgraph editor via rightSidePanelStore.openPanel('subgraph').
Translations
src/locales/en/main.json
Added rightSidePanel localization strings (toggle, titles, tabs, selection states).

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant User
participant TopMenu
participant GraphCanvas
participant Store as RightSidePanelStore
participant RightPanel as RightSidePanel
Note over User,TopMenu: User clicks "open right panel" or triggers subgraph edit
User->>TopMenu: click toggle/open
TopMenu->>Store: useRightSidePanelStore().togglePanel()/openPanel('subgraph')
Store-->>GraphCanvas: state change (isOpen, activeTab, isEditingSubgraph)
GraphCanvas->>RightPanel: render/update right-side slot (parameters/settings/info or SubgraphEditor)
RightPanel-->>User: panel UI opens with requested tab/content

Possibly related PRs

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rizumu/feat/right-side-panel

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

@github-actions
Copy link

github-actions bot commented Nov 26, 2025

🎭 Playwright Test Results

Some tests failed

⏰ Completed at: 12/03/2025, 05:37:29 AM UTC

📈 Summary

  • Total Tests: 476
  • Passed: 444 ✅
  • Failed: 19 ❌
  • Flaky: 4 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 435 / ❌ 19 / ⚠️ 4 / ⏭️ 9
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Nov 26, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/03/2025, 05:25:28 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 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 InjectionKey

Using inject here cleanly follows the provide/inject pattern the repo prefers, and the default false keeps behavior unchanged when nothing is provided. Please double‑check that whatever is provided under 'hideLayoutField' is actually a plain boolean; if it’s a Ref/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 shared InjectionKey<boolean> (Symbol) so both provider and consumer share a single, typed token instead of a magic string. The ESLint import-x/no-unresolved hint 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 converting getIcon() to a computed property.

Since getIcon() is called in the template and depends only on reactive props, making it a computed would 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: Export PanelTab type for consumer type safety.

The PanelTab type is defined inside the store but consumers calling setActiveTab won'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.defaultCollapse is boolean | undefined but isCollapse expects boolean. 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 class attribute on line 103 duplicates styles already in the :class binding. The cn() 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.

demote and promote return 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 helpers

The switch to isSelected(index) and handleSelect(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 single selectedIndex (via computed) and compare index === selectedIndex in the template to avoid repeated getOptionValue work, but it’s not required for typical usage.

Comment on lines +112 to +135
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)
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Comment on lines +18 to +25
const node = computed(() => props.nodes[0])
const nodeDefStore = useNodeDefStore()
const nodeHelpStore = useNodeHelpStore()
const nodeInfo = computed(() => {
return nodeDefStore.fromLGraphNode(node.value)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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).

Comment on lines +71 to +83
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
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add null guard in getOptionValue and reconsider string-based equality

Two points here:

  1. 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
}
  1. 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.

@github-actions
Copy link

github-actions bot commented Nov 26, 2025

Bundle Size Report

Summary

  • Raw size: 17 MB baseline 17 MB — 🔴 +33.7 kB
  • Gzip: 3.38 MB baseline 3.37 MB — 🔴 +6.1 kB
  • Brotli: 2.59 MB baseline 2.59 MB — 🔴 +4.56 kB
  • Bundles: 97 current • 97 baseline • 52 added / 52 removed

Category Glance
Graph Workspace 🔴 +45.2 kB (974 kB) · App Entry Points 🟢 -11.6 kB (3.2 MB) · UI Components 🔴 +162 B (169 kB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Panels & Settings ⚪ 0 B (298 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.2 MB (baseline 3.21 MB) • 🟢 -11.6 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-DQ5fpUyX.js (removed) 2.99 MB 🟢 -2.99 MB 🟢 -622 kB 🟢 -472 kB
assets/index-DM-aVTyf.js (new) 2.97 MB 🔴 +2.97 MB 🔴 +619 kB 🔴 +470 kB
assets/index-Cg8bVZC1.js (removed) 223 kB 🟢 -223 kB 🟢 -47.5 kB 🟢 -39.2 kB
assets/index-DBjSzVrG.js (new) 223 kB 🔴 +223 kB 🔴 +47.5 kB 🔴 +39.2 kB
assets/index-B35_IeT0.js (new) 345 B 🔴 +345 B 🔴 +245 B 🔴 +237 B
assets/index-CihEWd6C.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -231 B

Status: 3 added / 3 removed

Graph Workspace — 974 kB (baseline 929 kB) • 🔴 +45.2 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-Ba5M2Qm3.js (new) 974 kB 🔴 +974 kB 🔴 +188 kB 🔴 +144 kB
assets/GraphView-DVG_rasM.js (removed) 929 kB 🟢 -929 kB 🟢 -180 kB 🟢 -138 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-B4u6dwOA.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB
assets/UserSelectView-CaWTtW2v.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.9 kB

Status: 1 added / 1 removed

Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-CXG0ikcg.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/CreditsPanel-DgbfDXFa.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.49 kB
assets/KeybindingPanel-C5vVdNWO.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.01 kB
assets/KeybindingPanel-COwBOn3n.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.04 kB
assets/ExtensionPanel-ClTyXaQO.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.26 kB
assets/ExtensionPanel-D2OdogbL.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.26 kB
assets/AboutPanel-DWIVJVQL.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/AboutPanel-jg9_kT8o.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/ServerConfigPanel-CehZFKJF.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/ServerConfigPanel-CFg3gUE-.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/UserPanel-CJ8LXfP0.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-z51KQ4uo.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 169 kB (baseline 169 kB) • 🔴 +162 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-BV7ZowzA.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.31 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-Dg4o2IAX.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.31 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-ByiLfNM2.js (removed) 47.6 kB 🟢 -47.6 kB 🟢 -10.3 kB 🟢 -8.9 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DUh3EXVX.js (new) 47.6 kB 🔴 +47.6 kB 🔴 +10.3 kB 🔴 +8.91 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-AvCul9tx.js (new) 39.4 kB 🔴 +39.4 kB 🔴 +9.08 kB 🔴 +7.97 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-qnBAEh29.js (removed) 39.4 kB 🟢 -39.4 kB 🟢 -9.08 kB 🟢 -7.96 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BAD_Vjc-.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.98 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CTOeaU0R.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/ComfyQueueButton-6x8ZJihh.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.21 kB
assets/ComfyQueueButton-BKQX_-lb.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.22 kB
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-VhqMWCTd.js (new) 2.16 kB 🔴 +2.16 kB 🔴 +818 B 🔴 +716 B
assets/WidgetButton-C9RSl9Jc.js (removed) 2.04 kB 🟢 -2.04 kB 🟢 -929 B 🟢 -809 B
assets/WidgetButton-DBkWxjh1.js (new) 2.04 kB 🔴 +2.04 kB 🔴 +927 B 🔴 +810 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-C-GzTNBl.js (removed) 2 kB 🟢 -2 kB 🟢 -769 B 🟢 -671 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-B4R5m1qI.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -687 B 🟢 -591 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-DRxvgpU7.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +686 B 🔴 +597 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-CIeT93Mn.js (new) 897 B 🔴 +897 B 🔴 +501 B 🔴 +463 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-DOQz2TKa.js (removed) 897 B 🟢 -897 B 🟢 -503 B 🟢 -430 B

Status: 9 added / 9 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-B2nviWj4.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.84 kB 🟢 -1.58 kB
assets/keybindingService-C16nAmNU.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/serverConfigStore-BIb40oOr.js (new) 2.83 kB 🔴 +2.83 kB 🔴 +907 B 🔴 +799 B
assets/serverConfigStore-W1zhjkBH.js (removed) 2.83 kB 🟢 -2.83 kB 🟢 -905 B 🟢 -786 B
assets/audioService-Cck4CIYU.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -822 B
assets/audioService-DnnK-U5e.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +958 B 🔴 +825 B

Status: 3 added / 3 removed

Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CLemU1LP.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -651 B 🟢 -550 B
assets/audioUtils-Ct1-piBv.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +649 B 🔴 +541 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-BZzgsWym.js (new) 3.98 MB 🔴 +3.98 MB 🔴 +843 kB 🔴 +673 kB
assets/vendor-other-DsoOPVgr.js (removed) 3.98 MB 🟢 -3.98 MB 🟢 -843 kB 🟢 -674 kB
assets/vendor-primevue-3gHexYD_.js (new) 1.96 MB 🔴 +1.96 MB 🔴 +336 kB 🔴 +202 kB
assets/vendor-primevue-CjsaCDb8.js (removed) 1.96 MB 🟢 -1.96 MB 🟢 -336 kB 🟢 -202 kB
assets/vendor-chart-BCOr5Gfm.js (removed) 452 kB 🟢 -452 kB 🟢 -99.1 kB 🟢 -81 kB
assets/vendor-chart-DWRkrNy1.js (new) 452 kB 🔴 +452 kB 🔴 +99.1 kB 🔴 +81 kB
assets/vendor-tiptap-CzjUILzD.js (removed) 232 kB 🟢 -232 kB 🟢 -45.7 kB 🟢 -37.7 kB
assets/vendor-tiptap-Dw558Ulu.js (new) 232 kB 🔴 +232 kB 🔴 +45.7 kB 🔴 +37.7 kB
assets/vendor-vue-BEWVLQIi.js (removed) 160 kB 🟢 -160 kB 🟢 -37.3 kB 🟢 -31.6 kB
assets/vendor-vue-CoO6TOrn.js (new) 160 kB 🔴 +160 kB 🔴 +37.3 kB 🔴 +31.6 kB
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-BIWoFXVl.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.24 kB 🟢 -4.63 kB
assets/WidgetRecordAudio-DzWKi7je.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.23 kB 🔴 +4.63 kB
assets/AudioPreviewPlayer-CEfgb0CB.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/AudioPreviewPlayer-CM2gyssq.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.03 kB
assets/WidgetGalleria-Cho1-wN5.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.31 kB
assets/WidgetGalleria-CkWvC9dO.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.45 kB 🟢 -1.3 kB
assets/WidgetColorPicker-B1og5nDX.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetColorPicker-Bvo7UcK8.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetMarkdown-5BKZdTcV.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.12 kB
assets/WidgetMarkdown-D8EslljL.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetAudioUI-B_WLl6OS.js (removed) 2.82 kB 🟢 -2.82 kB 🟢 -1.12 kB 🟢 -1.02 kB
assets/WidgetAudioUI-CCDd4Gjt.js (new) 2.82 kB 🔴 +2.82 kB 🔴 +1.12 kB 🔴 +1.02 kB
assets/WidgetTextarea-B3xT2P2D.js (new) 2.79 kB 🔴 +2.79 kB 🔴 +1.1 kB 🔴 +988 B
assets/WidgetTextarea-CzQlVw1i.js (removed) 2.79 kB 🟢 -2.79 kB 🟢 -1.09 kB 🟢 -992 B
assets/MediaVideoTop-_g8aBAAL.js (removed) 2.76 kB 🟢 -2.76 kB 🟢 -1.05 kB 🟢 -900 B
assets/MediaVideoTop-BpvqEylZ.js (new) 2.76 kB 🔴 +2.76 kB 🔴 +1.05 kB 🔴 +900 B
assets/WidgetChart-DsbKXC7D.js (new) 2.48 kB 🔴 +2.48 kB 🔴 +933 B 🔴 +816 B
assets/WidgetChart-f0b59iz3.js (removed) 2.48 kB 🟢 -2.48 kB 🟢 -931 B 🟢 -815 B
assets/WidgetImageCompare-65U3rWW6.js (removed) 2.21 kB 🟢 -2.21 kB 🟢 -747 B 🟢 -661 B
assets/WidgetImageCompare-nVNi67CU.js (new) 2.21 kB 🔴 +2.21 kB 🔴 +749 B 🔴 +662 B
assets/WidgetInputText-B-89DKUI.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +917 B 🔴 +841 B
assets/WidgetInputText-BL5ocFny.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -917 B 🟢 -842 B
assets/MediaImageTop-BN0aEMtg.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +842 B 🔴 +719 B
assets/MediaImageTop-Df0PRhSp.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -841 B 🟢 -718 B
assets/WidgetToggleSwitch-C53mIaDW.js (removed) 1.58 kB 🟢 -1.58 kB 🟢 -759 B 🟢 -664 B
assets/WidgetToggleSwitch-DkvdXJVp.js (new) 1.58 kB 🔴 +1.58 kB 🔴 +759 B 🔴 +671 B
assets/MediaImageBottom-_lKmARm0.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +742 B 🔴 +647 B
assets/MediaImageBottom-K6OXYdQo.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -742 B 🟢 -649 B
assets/MediaAudioBottom-DodHh1sT.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -743 B 🟢 -655 B
assets/MediaAudioBottom-YwXQ9zGH.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +743 B 🔴 +661 B
assets/MediaVideoBottom-C11bX8a8.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -739 B 🟢 -657 B
assets/MediaVideoBottom-IiQHhZc2.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +740 B 🔴 +657 B
assets/Media3DBottom-DcxxBrd6.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +731 B 🔴 +650 B
assets/Media3DBottom-jZDtGJee.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -732 B 🟢 -650 B
assets/Media3DTop-Br4Rbzc3.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -765 B 🟢 -655 B
assets/Media3DTop-k7mq84s0.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +765 B 🔴 +650 B
assets/MediaAudioTop-B_r9Y3e-.js (removed) 1.46 kB 🟢 -1.46 kB 🟢 -737 B 🟢 -612 B
assets/MediaAudioTop-DX0t5RN3.js (new) 1.46 kB 🔴 +1.46 kB 🔴 +738 B 🔴 +618 B
assets/WidgetSelect-CXSgoIA6.js (new) 655 B 🔴 +655 B 🔴 +345 B 🔴 +288 B
assets/WidgetSelect-gZbUhF1Y.js (removed) 655 B 🟢 -655 B 🟢 -345 B 🟢 -308 B
assets/WidgetInputNumber-BGkPhz88.js (removed) 595 B 🟢 -595 B 🟢 -328 B 🟢 -275 B
assets/WidgetInputNumber-BHIRk3A4.js (new) 595 B 🔴 +595 B 🔴 +330 B 🔴 +273 B
assets/Load3D-DpdCX8O8.js (removed) 424 B 🟢 -424 B 🟢 -266 B 🟢 -223 B
assets/Load3D-DYZd6ANm.js (new) 424 B 🔴 +424 B 🔴 +265 B 🔴 +225 B
assets/WidgetLegacy-BLv03K5e.js (new) 364 B 🔴 +364 B 🔴 +235 B 🔴 +229 B
assets/WidgetLegacy-DOA2unuI.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -197 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8e6QYQW0.js 283 kB 283 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-A_9dx4yn.js 304 kB 304 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BbD3HDi7.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BOJhIPft.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C-Pw33mW.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-ChLyG0UJ.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CUVPxA4l.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dx5Y4xrW.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JqO5mNmW.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 23 added / 23 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)

3-3: Align hideLayoutField injection type with provider and desired reactivity

Right now hideLayoutField is injected as a plain boolean, and the template uses v-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), hideLayoutField here will actually be an object; !hideLayoutField will then be false regardless 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 Ref automatically in the template.

Also applies to: 13-13, 20-23

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 464c9b2 and 828c836.

📒 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/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.json

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/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 run pnpm format before committing

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
src/**/*.vue

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

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

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/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.vue
  • src/components/TopMenuSection.vue
**/*.{vue,html}

📄 CodeRabbit inference engine (CLAUDE.md)

Never use dark: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce 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.vue
  • src/components/TopMenuSection.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
src/**/*.{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.vue
  • src/components/TopMenuSection.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/components/TopMenuSection.vue
src/components/**/*.vue

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

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

Files:

  • src/components/TopMenuSection.vue
src/components/**/*.{vue,css}

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

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

Files:

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

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

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

Files:

  • src/components/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 injection

Applied 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 components

Applied 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 3

Applied 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 API

Applied 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 utilities

Applied 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 API

Applied 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 logic

Applied 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 styles

Applied 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 libraries

Applied 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 Popover

Applied 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 files

Applied 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 in src/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.

Comment on lines +47 to +60
<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>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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:

  1. Recommended: Remove the aria-pressed attribute since the button's visibility already indicates state
  2. Alternative: Keep the button always visible (like the queue history button on lines 23-44) and toggle aria-pressed between 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.

Suggested change
<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).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 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

📥 Commits

Reviewing files that changed from the base of the PR and between 828c836 and d47af09.

📒 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
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.json

Files:

  • 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 run pnpm format before committing

Files:

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

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

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

Files:

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

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

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

Files:

  • src/components/rightSidePanel/parameters/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: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

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

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce 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.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

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

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

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

Files:

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

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

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

Files:

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

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

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

Files:

  • src/components/rightSidePanel/parameters/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 Drawer

Applied 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 3

Applied 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 utilities

Applied 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 state

Applied 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 styles

Applied 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>() and withDefaults, follows VueUse patterns with refDebounced, and imports the cn utility for proper class name merging.


20-28: LGTM! Proper reactive state and debouncing.

The state management correctly uses defineModel for two-way binding, ref for internal state, and refDebounced from VueUse for the 700ms debounce. The watch effectively tracks loading state by comparing the immediate and debounced values.

Comment on lines +45 to +49
void props
.searcher(debouncedSearchQuery.value, (cb) => (cleanupFn = cb))
.finally(() => {
if (!isCleanup) isQuerying.value = false
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Copy link
Collaborator

@AustinMroz AustinMroz left a 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, {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const debouncedSearchQuery = refDebounced(searchQuery, 700, {
const debouncedSearchQuery = refDebounced(searchQuery, 100, {

700 ms feels super unresponsive here. Can we lower it?

Comment on lines 9 to 13
<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"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
<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

@silveroxides
Copy link
Contributor

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.
Also a side menu like this one does not really fit the concept of a node graph editor which is that ComfyUI frontend is supposed to be.
It is better relegated to a separate overlay style UI similar to SwarmUI if that is the kind of simplicity and screen space wasting feature users want to have.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/components/rightSidePanel/parameters/TabParameters.vue (2)

31-48: Optionally skip empty widget sections and simplify mapping

Currently every node becomes a section, even when it has no visible widgets, and shownWidgets is 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 unnecessary async on searcher (and minor search behavior notes)

searcher never awaits anything, so marking it async only wraps the result in a Promise and may trigger require-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) initializing searchedWidgetsSectionDataList with the full widgetsSectionDataList so the panel isn’t empty before the first search call.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d47af09 and 56f8f29.

📒 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
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.json

Files:

  • 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 run pnpm format before committing

Files:

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

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

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

Files:

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

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

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

Files:

  • src/components/rightSidePanel/parameters/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: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

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

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce 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.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

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

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

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

Files:

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

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

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

Files:

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

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

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

Files:

  • src/components/rightSidePanel/parameters/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 panels

Applied 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 solid

SidePanelSearch and SectionWidgets are wired correctly, and the default-collapse condition cleanly distinguishes “no active search” via ref unwrapping/equality in the template; no changes needed here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/components/rightSidePanel/NodePropertiesPanel.vue (2)

98-115: Remove duplicated static classes and rely solely on cn()

The first IconButton for subgraph editing defines base classes both in class and within cn():

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 cn for class merging” guideline, drop the static class attribute and keep only the cn call:

-          <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 in panelTitle

The 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.unnamedNode to src/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 gutters

The selector :deep(.side-bar-panel[style*='display: none'] + .p-splitter-gutter) couples behavior to the exact inline style string, which is brittle to formatting changes and harder to reason about.

If feasible, prefer a class-based approach, e.g. toggling a .is-hidden class on the sidebar panel and keying the CSS off that class instead of the style attribute.

src/stores/workspace/rightSidePanelStore.ts (1)

18-41: Store API is clean; clarify togglePanel behavior w.r.t. subgraph mode

State shape and actions (openPanel, closePanel, togglePanel, setActiveTab) are well-structured and typed.

One behavioral edge case: togglePanel() flips isOpen but does not reset isEditingSubgraph, whereas closePanel() does. That means:

  • Open via openPanel('subgraph')isEditingSubgraph = true
  • Toggle to close → isOpen = false, isEditingSubgraph still true
  • 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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 NodePropertiesPanel but the source file is RightSidePanel.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 unnecessary async keyword.

The searcher function performs a synchronous assignment and doesn't use await. The async keyword 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3774b6c and d7fa9a9.

📒 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/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.json

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/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 run pnpm format before committing

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/*.vue

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

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/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.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
**/*.{vue,html}

📄 CodeRabbit inference engine (CLAUDE.md)

Never use dark: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/components/**/*.vue

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

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,css}

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

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,ts,js}

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

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

Files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphNodeWidget.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • src/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 panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • 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 Sidebar component with Drawer

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • 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 : Utilize ref and reactive for reactive state in Vue 3

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/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 guide

Applied to files:

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

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • 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 panels

Applied to files:

  • src/components/rightSidePanel/RightSidePanel.vue
  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • 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 : Follow Vue 3 style guide and naming conventions

Applied 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 templates

Applied 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 respectively

Applied to files:

  • src/components/rightSidePanel/subgraph/SubgraphEditor.vue
  • 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 InputSwitch component with ToggleSwitch

Applied 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.vue
  • 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 ref and reactive for reactive state

Applied to files:

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

Applied 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 utilities

Applied to files:

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

Applied 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 3

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/components/rightSidePanel/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 Select

Applied 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 new class prop with ClassValue type provides good flexibility. The styling uses semantic tokens appropriately.

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

82-86: LGTM!

The watchEffect correctly 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 filteredActive is appropriate for preventing rapid re-initialization of the draggable list during filtering operations.

@LittleSound LittleSound added the New Browser Test Expectations New browser test screenshot should be set by github action label Nov 30, 2025
@github-actions
Copy link

Updating Playwright Expectations

@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Nov 30, 2025
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Nov 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 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. Using useSettingStore() for Comfy.Sidebar.Location / Comfy.Sidebar.UnifiedWidth also 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 handled rightSidePanelStore.


129-135: Revisit sidebarStateKey vs splitterRefreshKey responsibilities

sidebarStateKey changes with unifiedWidth and activeSidebarTabId, while splitterRefreshKey toggles between 'main-splitter-with-right-panel' and 'main-splitter' based solely on rightSidePanelVisible.

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-key instead of using key, or
  • Using a distinct state-key when the right panel is visible and dropping key entirely, 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-key vs key if you see inconsistencies.

Also applies to: 140-144


166-170: Attribute‑selector gutter hiding is somewhat brittle but acceptable

The 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: getSplitterGutterClasses computed is a no-op that can be simplified

The computed always returns an empty string and is used for :pt:gutter="getSplitterGutterClasses". Since PrimeVue's pt:gutter does 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

📥 Commits

Reviewing files that changed from the base of the PR and between d7fa9a9 and 952f4a1.

⛔ Files ignored due to path filters (21)
  • browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png is 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
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.json

Files:

  • 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 run pnpm format before committing

Files:

  • src/components/LiteGraphCanvasSplitterOverlay.vue
src/**/*.vue

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

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

Files:

  • src/components/LiteGraphCanvasSplitterOverlay.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/components/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: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

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

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/LiteGraphCanvasSplitterOverlay.vue
src/components/**/*.vue

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

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

Files:

  • src/components/LiteGraphCanvasSplitterOverlay.vue
src/components/**/*.{vue,css}

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

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

Files:

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

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

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

Files:

  • src/components/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 Drawer

Applied 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 Popover

Applied 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 files

Applied 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 files

Applied to files:

  • src/components/LiteGraphCanvasSplitterOverlay.vue

Comment on lines 16 to 21
<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"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/components/LiteGraphCanvasSplitterOverlay.vue | head -100

Repository: 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 3

Repository: 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 2

Repository: 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 2

Repository: 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 2

Repository: 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 1

Repository: 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 -i

Repository: 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 vue

Repository: 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 -30

Repository: 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 5

Repository: 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 8

Repository: 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 ts

Repository: 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 rightSidePanelVisible to the sidebarStateKey computation so each configuration has its own persisted state, or
  • Using a separate state-key when 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.

Comment on lines +84 to +92
<!-- 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>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find src -name "LiteGraphCanvasSplitterOverlay.vue" -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 119


🏁 Script executed:

wc -l src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 123


🏁 Script executed:

cat -n src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 7416


🏁 Script executed:

head -n 220 src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 7416


🏁 Script executed:

cat src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 5988


🏁 Script executed:

sed -n '170,185p' src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 338


🏁 Script executed:

sed -n '60,180p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4310


🏁 Script executed:

sed -n '1,100p' src/components/LiteGraphCanvasSplitterOverlay.vue | tail -n 50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1545


🏁 Script executed:

grep -n "sidebarLocation" src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 613


🏁 Script executed:

sed -n '1,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2581


🏁 Script executed:

grep -n "topPositionedSidebar\|leftPositionedSidebar\|rightPositionedSidebar" src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

grep -rn "sidebarLocation.*right\|right.*sidebar" src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 377


🏁 Script executed:

sed -n '1,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2581


🏁 Script executed:

head -n 70 src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2293


🏁 Script executed:

grep -A5 -B5 "topPositionedSidebar\|leftPositionedSidebar" src/components/LiteGraphCanvasSplitterOverlay.vue | head -n 30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

sed -n '20,45p' src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 886


🏁 Script executed:

sed -n '15,50p' src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1206


🏁 Script executed:

grep -A3 "sidebarLocation" src/components/LiteGraphCanvasSplitterOverlay.vue | head -n 10

Repository: 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])
EOF

Repository: 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.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 553


🏁 Script executed:

sed -n '20,65p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1878


🏁 Script executed:

grep -rn "sidebarLocation.*=.*['\"]right" src/ --include="*.vue" --include="*.ts" | head -n 20

Repository: 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 20

Repository: 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 20

Repository: 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 20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 920


🏁 Script executed:

sed -n '60,120p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2309


🏁 Script executed:

sed -n '84,120p' src/components/LiteGraphCanvasSplitterOverlay.vue | cat -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1502


🏁 Script executed:

find src/components -name "*Sidebar*" -o -name "*sidebar*" | head -n 10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 534


🏁 Script executed:

ls -la src/components/ | grep -i sidebar

Repository: 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 40

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2044


🏁 Script executed:

grep -n "rightPositionedSidebar\|const.*sidebar\|computed.*sidebar" src/components/LiteGraphCanvasSplitterOverlay.vue

Repository: 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'.

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Dec 3, 2025
@LittleSound LittleSound added the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 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.vue but imported as NodePropertiesPanel. 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.vue

Note: The ESLint error about the unresolved path is likely a false positive if RightSidePanel.vue was added in this PR.

src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue (1)

3-11: hideLayoutField injection is clean and backward‑compatible

Using 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 typed InjectionKey<boolean> (e.g., exported from a shared injectionKeys.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

📥 Commits

Reviewing files that changed from the base of the PR and between 952f4a1 and 560339b.

📒 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 use import { cn } from '@/utils/tailwindUtil' for class merging in Vue templates

**/*.vue: Use TypeScript with Vue 3 Single File Components (.vue files)
Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/graph/GraphCanvas.vue
  • src/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.json

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/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 run pnpm format before committing

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/services/litegraphService.ts
src/**/*.vue

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

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

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/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.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/services/litegraphService.ts
**/*.{vue,html}

📄 CodeRabbit inference engine (CLAUDE.md)

Never use dark: or dark-theme: Tailwind variants - instead use semantic values from style.css theme, e.g. bg-node-component-surface

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/services/litegraphService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/services/litegraphService.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
  • src/services/litegraphService.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/graph/GraphCanvas.vue
  • src/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue
src/components/**/*.vue

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

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

Files:

  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,css}

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

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

Files:

  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,ts,js}

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

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

Files:

  • src/components/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 use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

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

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

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

Files:

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

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

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

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/services/litegraphService.ts
🧠 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 Drawer

Applied 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 respectively

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 OverlayPanel component with Popover

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 Steps component with Stepper without panels

Applied 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 panels

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 Dropdown component with Select

Applied 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 injection

Applied 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 components

Applied 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 3

Applied 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 setup

Applied 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 issues

Applied 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 files

Applied 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-panel slot is properly defined in the parent component LiteGraphCanvasSplitterOverlay.vue (lines 88-93) and is conditionally rendered based on rightSidePanelVisible from the useRightSidePanelStore(). The implementation in GraphCanvas.vue correctly uses this slot with the v-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 behavior

Guarding 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 of false, 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 behavior

Switching the callback to useRightSidePanelStore().openPanel('subgraph') is consistent with the rightSidePanelStore API and should correctly flip isOpen and isEditingSubgraph so 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'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

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.ts is 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".

@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 3, 2025
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Dec 3, 2025
Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants