-
Notifications
You must be signed in to change notification settings - Fork 435
Sync Vue Nodes Right Click menu with full ContextMenu #6455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 12/02/2025, 05:38:00 AM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🎭 Playwright Test Results⏰ Completed at: 12/02/2025, 05:46:57 AM UTC 📈 Summary
📊 Test Reports by Browser
🎉 Click on the links above to view detailed test results for each browser configuration. |
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 3.19 MB (baseline 3.19 MB) • 🔴 +988 BMain entry bundles and manifests
Status: 3 added / 3 removed Graph Workspace — 932 kB (baseline 928 kB) • 🔴 +3.98 kBGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 1 added / 1 removed Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 6 added / 6 removed UI Components — 169 kB (baseline 169 kB) • ⚪ 0 BReusable component library chunks
Status: 6 added / 6 removed Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 2 added / 2 removed Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 1 added / 1 removed Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Other — 3.84 MB (baseline 3.84 MB) • ⚪ 0 BBundles that do not match a named category
Status: 17 added / 17 removed |
3d05c49 to
8e7026d
Compare
8e7026d to
52b7b5c
Compare
- Add disabled property to MenuOption and SubMenuOption interfaces - Apply semantic token styling for disabled items (text-node-icon-disabled) - Prevent interactions on disabled menu and submenu items - Use cursor-not-allowed and pointer-events-none for disabled state - Pass through disabled flag from LiteGraph menu items to Vue components
Add translation key for the Extensions section label in the context menu. This allows the Extensions category header to be properly localized.
Add support for non-clickable category labels in the context menu. Category items are displayed as uppercase labels with secondary text color and proper translation support via contextMenu namespace. This enables grouping menu items under section headers like "Extensions".
Add comprehensive menu ordering system to ensure consistent context menu layout: - Define MENU_ORDER constant with 5 logical sections - Implement automatic section-based divider insertion - Separate core items from extension items - Add blacklist for unwanted duplicate items (Colors, Shapes, Title, Mode, etc.) - Preserve Vue hardcoded options over LiteGraph items during deduplication - Add source tracking (litegraph vs vue) for precedence handling Menu structure: 1. Basic operations (Rename, Copy, Duplicate) 2. Node actions (Run Branch, Pin, Bypass, Mute) 3. Structure operations (Convert to Subgraph, Frame selection, Minimize Node) 4. Node properties (Node Info, Color) 5. Node-specific operations (Image operations) 6. Extensions section (non-core items) 7. Delete (always at bottom) The system ensures proper ordering regardless of whether items come from LiteGraph or Vue hardcoded menus, with Extensions clearly separated.
Reorder menu sections to follow the specification: 1. Basic operations: Rename, Copy, Duplicate 2. Node actions: Run Branch, Pin, Bypass, Mute (for groups) 3. Structure operations: Convert to Subgraph, Frame selection, Minimize Node 4. Node properties: Node Info, Color (Shape removed) 5. Node-specific operations: Image operations only Changes: - Add explicit dividers after each section - Remove Shape, Alignment, and Adjust Size options - Merge LiteGraph and Vue options for single node selection - Add source tracking (vue) for precedence during deduplication - Add comprehensive logging for debugging menu construction For single node selection, both LiteGraph and Vue options are merged with Vue options taking precedence, then structured via buildStructuredMenu.
Add real-time search filtering to the node context menu: - Search input with icon at the top of the menu - Case-insensitive filtering by menu item label - Auto-focus on menu open - Clear search on Escape key or menu close - Smart divider handling (removes unnecessary dividers during search) - Hides Extensions category label when searching The search provides instant feedback as users type, making it easier to find specific menu items in long context menus.
Move Resize and Clone menu items from fallback section to Section 3 (Structure operations) so they appear alongside Convert to Subgraph, Frame selection, and Minimize Node. Updated section boundaries: - Section 3 now spans indices 9-15 (was 9-13) - Section 4 now spans indices 16-17 (was 14-15) This ensures Resize and Clone appear under the same divider group as other structure-related operations.
When right-clicking near the bottom of the viewport, the context menu now docks to the bottom edge instead of floating off-screen, ensuring it remains accessible and scrollable.
Replaces simple substring matching with Fuse.js fuzzy search for better user experience. Adds 300ms debouncing to reduce processing overhead. Includes debug logging for troubleshooting.
📝 WalkthroughWalkthroughReplaces the Popover-based node options UI with a PrimeVue ContextMenu, adds a LiteGraph→Vue context-menu converter and legacy compatibility wrappers, widens LiteGraph menu typings to allow null entries, moves color‑picker positioning to inline DOM, privatizes selection‑toolbox signals, and removes submenu‑positioning composable. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Canvas as LGraphCanvas
participant Converter as contextMenuConverter
participant Store as useMoreOptionsMenu
participant CMC as NodeContextMenu
participant ColorPicker as ColorPickerMenu
User->>Canvas: right-click node
Canvas->>Canvas: getNodeMenuOptions() (may include legacy items)
Canvas->>Converter: convertContextMenuToOptions(litegraphItems)
Converter->>Converter: normalize, dedupe, capture dynamic submenus
Converter->>Store: buildStructuredMenu(merged options)
Store-->>CMC: MenuOption[] provided
User->>CMC: toggle(event)
CMC->>CMC: map MenuOption -> PrimeVue MenuItem
CMC->>User: show context menu
User->>CMC: click color option (isColorPicker)
CMC->>ColorPicker: toggle(target)
ColorPicker->>ColorPicker: compute position & show
User->>ColorPicker: select color
ColorPicker->>CMC: handleColorSelect()
CMC->>CMC: execute action, hide menus
Possibly related PRs
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/graph/selectionToolbox/MenuOptionItem.vue (1)
1-47: Category row & disabled styling look good; badge i18n keying may need tightening
- The new
option.type === 'category'branch withpointer-events-noneandt(\contextMenu.${option.label}`)` is consistent with how other context-menu labels are translated and correctly non-interactive.- The dynamic class array for the main row cleanly distinguishes disabled vs enabled states and matches the new disabled behavior elsewhere.
One small i18n concern: badge values are translated via
t(option.badge), whereoption.badgeis typically'new'or'deprecated', but the corresponding strings live under thecontextMenunamespace (contextMenu.new/contextMenu.deprecated) inmain.json. Unless you also define root-levelnew/deprecatedkeys in the messages, this will likely show the raw key instead of a localized string.You can tighten this by scoping badges to the same namespace:
- :value="t(option.badge)" + :value="t(`contextMenu.${option.badge}`)"This keeps badge translations aligned with the rest of the context-menu labels.
♻️ Duplicate comments (2)
src/components/graph/selectionToolbox/NodeOptions.vue (2)
130-189: Filtering & divider reconstruction logic looks sound, including divider/category adjacencyThe fuzzy‑search pipeline (
searchableMenuOptions→useFuse→filteredMenuOptions) correctly:
- Excludes
divider/categoryitems from search targets,- Matches by label, then rebuilds the menu in original order,
- Avoids leading/trailing dividers and collapses sequences so you never introduce multiple dividers between hits.
Since categories are skipped entirely when
queryis non‑empty, “divider + category + item” sequences in the original structured menu end up as at most a single divider before the first matching item, which answers the earlier question about adjacent dividers/categories.
226-253: DirectcssTextappend plus individual property sets
repositionPopoverupdatesoverlayEl.style.cssTextand then setstop/bottomindividually. This works but can be brittle (order/precedence) and makes it harder to reason about final styles; also, multiple style writes may cause additional layout/repaint work in some browsers. Consider computing a single style object and applying viaObject.assign(overlayEl.style, style)instead.
🧹 Nitpick comments (7)
src/components/graph/selectionToolbox/SubmenuPopover.vue (1)
89-125: Consider centralizing viewport-aware positioning with the shared utility
repositionSubmenumanually measures the overlay and docks it to the bottom of the viewport when it would overflow:const rect = overlayEl.getBoundingClientRect() const menuHeight = overlayEl.offsetHeight || overlayEl.scrollHeight const viewportHeight = window.innerHeight const menuBottom = rect.top + menuHeight const wouldOverflow = menuBottom > viewportHeight // ... overlayEl.style.position = 'fixed' overlayEl.style.bottom = '0px' overlayEl.style.top = ''This is very similar in intent to the new
calculateMenuPositionhelper you added for the main menu. To avoid drift between primary and submenu behavior (and duplicate reflow/measurement logic), it’s worth considering:
- Reusing
calculateMenuPositionhere by feeding it the submenu’s trigger rect and overlay element, or- Extracting the “dock to bottom” portion into a shared internal helper used by both.
Not urgent, but it would simplify future tweaks to overflow behavior.
src/components/graph/selectionToolbox/NodeOptions.vue (2)
76-81: Consider avoiding unused imports from@vueuse/core
breakpointsTailwind,useBreakpoints, anduseRafFnare used, but ifdebouncedRefis the only part needed for search, keep an eye that all imported symbols remain used after future refactors to avoid dead code bloat.
404-437: Search reset on show/hide is consistent, consider preserving query across brief hidesCurrently
searchQueryis cleared on bothonPopoverShowandonPopoverHide, so any transient hide (e.g. drag‑related auto‑close/restore) will always lose the query. If users often reopen the menu immediately, you might consider only clearing on true manual close, similar to howwasOpenBeforeHideis tracked.src/composables/graph/contextMenuConverter.ts (4)
23-72: Label‑driven classification is brittle under renames/localizationBoth
CORE_MENU_ITEMSandMENU_ORDERdepend on the human‑readablelabelstring (e.g.'Run Branch','Open Image') to classify and order items. This works now but is fragile if:
- Labels are localized, or
- LiteGraph/Vue options are renamed.
A more robust approach is to carry a stable identifier (e.g.
id: 'run-branch') onMenuOptionand baseCORE_MENU_ITEMS/MENU_ORDERon those ids rather than translated labels.
136-202:removeDuplicateMenuOptionspreserves ordering and Vue precedenceGrouping by
labeland choosing asource === 'vue'candidate when duplicates exist achieves the “Vue overrides LiteGraph” goal while:
- Keeping dividers/categories and unlabeled items in original order, and
- Avoiding label collisions from extension items without labels.
The two‑pass approach with
itemsWithoutLabelis a bit dense; a brief comment explaining the ordering intent would help future maintainers.
453-522: Dynamic submenu capture viaLiteGraph.ContextMenuoverride is reasonable but invasiveTemporarily replacing
LiteGraph.ContextMenuto intercept dynamic submenu construction, then restoring it in afinallyblock, is a pragmatic way to introspect items without rendering DOM. The mockContextMenureturns a minimal{ close, root }object, which should satisfy most callbacks.Given this is a global mutation, it’s important that:
- No other concurrent code depends on
LiteGraph.ContextMenuwhile a dynamic submenu is being captured, and- The target LiteGraph version doesn’t rely on special prototype behavior of
ContextMenuthat your function replacement would miss.If LiteGraph ever gains an official hook for submenu generation, migrating to that would reduce risk.
605-610: Static analysis XSS warning oninnerHTMLis a false positive in this context
stripHtmlTagsassigns totemp.innerHTMLon a detached element and only readstextContent/innerText, never inserting the element into the live DOM. That means scripts or event handlers inhtmlwill not execute, so this usage is safe against XSS.To avoid future confusion and linter noise, consider:
- Adding a comment explaining that the element is never attached to the DOM, or
- Swapping to
DOMParserfor HTML → text extraction if you want to eliminateinnerHTMLentirely.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/components/graph/selectionToolbox/MenuOptionItem.vue(3 hunks)src/components/graph/selectionToolbox/NodeOptions.vue(9 hunks)src/components/graph/selectionToolbox/SubmenuPopover.vue(4 hunks)src/composables/graph/contextMenuConverter.ts(1 hunks)src/composables/graph/useMoreOptionsMenu.ts(5 hunks)src/composables/graph/useNodeMenuOptions.ts(1 hunks)src/composables/graph/useViewportAwareMenuPositioning.ts(1 hunks)src/composables/useContextMenuTranslation.ts(2 hunks)src/locales/en/main.json(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/composables/graph/useMoreOptionsMenu.ts (5)
src/renderer/core/canvas/canvasStore.ts (1)
useCanvasStore(24-149)src/composables/graph/useImageMenuOptions.ts (1)
useImageMenuOptions(11-108)src/composables/graph/useNodeMenuOptions.ts (1)
useNodeMenuOptions(12-128)src/composables/graph/useGroupMenuOptions.ts (1)
useGroupMenuOptions(16-196)src/composables/graph/contextMenuConverter.ts (2)
convertContextMenuToOptions(358-447)buildStructuredMenu(253-349)
src/composables/graph/contextMenuConverter.ts (2)
src/composables/graph/useMoreOptionsMenu.ts (2)
MenuOption(18-29)SubMenuOption(31-37)src/lib/litegraph/src/litegraph.ts (1)
LiteGraph(17-17)
src/composables/useContextMenuTranslation.ts (2)
src/lib/litegraph/src/contextMenuCompat.ts (1)
legacyMenuCompat(148-148)src/lib/litegraph/src/interfaces.ts (1)
IContextMenuValue(405-426)
🪛 ast-grep (0.40.0)
src/composables/graph/contextMenuConverter.ts
[warning] 607-607: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: temp.innerHTML = html
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 607-607: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: temp.innerHTML = html
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
⏰ 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: collect
- GitHub Check: setup
- GitHub Check: lint-and-format
🔇 Additional comments (17)
src/locales/en/main.json (1)
127-128: New translation keys look consistent and safe
g.noResultsandcontextMenu.Extensions/contextMenu.deprecatedfit existing naming and usage patterns; JSON structure is valid and compatible with current i18n usage.Also applies to: 431-433
src/composables/graph/useNodeMenuOptions.ts (1)
92-105: Bypass option icon change is isolated and correctOnly the icon for the bypass option changes; labels, shortcut (
Ctrl+B), and action logic remain intact. Safe UI-level adjustment.src/components/graph/selectionToolbox/MenuOptionItem.vue (1)
70-75: Defensive disabled guard inhandleClickis appropriateShort-circuiting
handleClickwhenprops.option.disabledis true matches the new disabled styling and protects against any future changes that might removepointer-events-nonefrom the row.src/components/graph/selectionToolbox/SubmenuPopover.vue (1)
31-46: Submenu disabled styling and click-guard are consistent and correctThe updated class composition for
subOptionrows plus thesubOption.disabledbranch gives you:
- Visual disabled state (
cursor-not-allowed, muted text).- Non-interactive behavior (pointer-events-none).
- A defensive guard in
handleSubmenuClickto prevent accidental emissions.This keeps submenu behavior aligned with the top‑level menu items.
Also applies to: 132-137
src/composables/useContextMenuTranslation.ts (1)
61-63: Node menu legacy/extension wiring matches the canvas patternInstalling
legacyMenuCompatforgetNodeMenuOptions, then wrapping it to:
- Append items from the new
app.collectNodeMenuItems(node)API, and- Append legacy monkey‑patched items from
legacyMenuCompat.extractLegacyItems('getNodeMenuOptions', ...),and finally registering the wrapper/original pair with
legacyMenuCompat.registerWrappermirrors the existing canvas‑menu integration and keeps all sources flowing through a single, composable hook point.The sequencing (install → capture original → wrap → register) looks correct and should preserve legacy behavior while enabling extensions.
Also applies to: 79-88, 94-101
src/components/graph/selectionToolbox/NodeOptions.vue (3)
111-117: Good separation of mobile vs desktop search focusUsing
useBreakpoints(breakpointsTailwind)andisMobileViewportto skip auto‑focus on small viewports nicely avoids pulling up the keyboard on mobile when the menu opens.
266-284: Guard against detached trigger element is a good additionThe
if (!el || !el.isConnected) return falsecheck inopenPopoverprevents trying to open against a stale DOM target during drag/move or unmount scenarios, which should avoid subtle positioning errors and exceptions.
321-349: Target‑switch behavior while open is well‑handledThe
togglelogic that switches the popover to a newtargetElwithout closing, bumps the options version, clears search, repositions, and re‑focuses the input (desktop only) gives a smooth experience when quickly right‑clicking different nodes.src/composables/graph/contextMenuConverter.ts (3)
78-122: Duplicate detection is conservative but acceptable
normalizeLabelplusequivalents(color/colors, pin/unpin, delete/remove, clone/duplicate) gives a reasonable duplicate filter while avoiding over‑eager merging. The logic short‑circuits on direct normalized match and only then checks equivalence groups, which is easy to reason about and should keep unrelated items (e.g. “Delete Selection”) distinct.
253-349: Structured core/extensions menu looks correct
buildStructuredMenu:
- Dedups first, then splits into core vs extension vs Delete,
- Orders core items using
MENU_ORDERand inserts a single divider between sections,- Adds an “Extensions” category label with a divider before it,
- Forces Delete/Remove (no submenu) to the bottom with a preceding divider.
This matches the described UX and should be stable as long as core labels remain consistent with those produced by Vue/LiteGraph.
527-599: Submenu conversion correctly propagates disabled state and strips HTML
convertSubmenuToOptions:
- Skips null separators,
- Handles both string items (calling
options.callbackwhen provided) and object items via theircallback,- Uses
stripHtmlTagsso labels from HTML‑styled content don’t leak markup into the Vue menu,- Propagates
disabledtoSubMenuOption.This is a solid bridge from LiteGraph submenu definitions to Vue submenus.
src/composables/graph/useMoreOptionsMenu.ts (6)
18-37: Type extensions align with converter/renderer changesAdding
type?: 'divider' | 'category',disabled?: boolean, andsource?: 'litegraph' | 'vue'toMenuOption, plusdisabled?: booleanonSubMenuOption, matches whatcontextMenuConverterand the menu components expect and should keep the types coherent across the pipeline.
85-96:markAsVueOptionscorrectly tags only actionable itemsThe helper skips
dividerandcategoryentries and clones other options withsource: 'vue'. This pairs cleanly withremoveDuplicateMenuOptions, which prefers Vue items over LiteGraph when de‑duplicating by label.
102-117: UsinguseCanvasStorefor LiteGraph integration is appropriatePulling
canvasStore.canvashere to accessgetNodeMenuOptionskeeps the LiteGraph dependency localized to this composable, instead of leaking it into UI components. That keeps NodeOptions.vue focused on rendering rather than data sourcing.
161-178: Single‑node LiteGraph menu merge path is sensibleThe block that, for a single node and no group context, calls
canvasStore.canvas.getNodeMenuOptions(node)and runsconvertContextMenuToOptions(rawItems, node, false)gives you raw LiteGraph options without structuring, which you then merge and structure once. The try/catch with logging prevents a bad extension from breaking the whole menu.
251-262: Merge + structuring flow achieves Vue‑over‑LiteGraph precedenceMerging with
const merged = [...litegraphOptions, ...markedVueOptions]and then callingbuildStructuredMenu(merged)ensures:
- LiteGraph contributes all its items,
- Vue items override LiteGraph ones with the same label (via
source: 'vue'),- The final menu is always ordered/sectioned consistently, regardless of which side supplied a given option.
The fallback path (no LiteGraph options) that structures only Vue options keeps behavior consistent across selection types.
265-276: FilteringmenuOptionsWithSubmenubyhasSubmenu && submenuis straightforwardThe computed
menuOptionsWithSubmenuremains aligned with the updatedMenuOptionshape and will naturally pick up submenus coming from either Vue or LiteGraph sources.
…pe definitions and method signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/components/graph/selectionToolbox/NodeOptions.vue (1)
27-55: Search/filter behavior looks solid; reconsider Escape handling with PopoverThe search pipeline (
searchQuery→ debounced Fuse oversearchableMenuOptions→filteredMenuOptions) correctly:
- hides dividers and categories while filtering,
- preserves divider structure only where matched items remain, and
- exposes an empty state only when no actionable items match.
One thing to double‑check: with
@keydown.escape="clearSearch"onSearchBoxand:close-on-escape="true"on<Popover>, pressing Escape will clear the query and still close the menu, so the clear is effectively redundant and you can’t get “Escape clears first, closes on second press”. If the intended UX is “Escape clears while there’s text, otherwise closes the menu”, you’ll need to either:
- accept the
KeyboardEventinclearSearchand callevent.stopPropagation()whensearchQueryis non‑empty, or- use
.stopin the template and conditionally re‑emit only when the query is already empty.Also applies to: 81-184, 399-402, 403-416
🧹 Nitpick comments (2)
src/lib/litegraph/src/LGraphCanvas.ts (1)
711-715: Null‑aware menu typings look correct; ensure implementers handlenullentriesUpdating
getExtraMenuOptionsandgetCanvasMenuOptionsto use(IContextMenuValue | null)[]matches the actual usage ofnullas dividers in menu arrays and lines up with the compat layer. Just make sure any customgetExtraMenuOptionsimplementations and downstream consumers treat entries as nullable (skip or filter them) rather than assuming every item is a real option.Also applies to: 8012-8048
src/components/graph/selectionToolbox/NodeOptions.vue (1)
190-257: Avoid appending tostyle.cssTextevery frame inrepositionPopover
repositionPopovercurrently updates the overlay via:overlayEl.style.cssText += `; left: ${style.left}; position: ${style.position}; transform: ${style.transform};`and runs on every RAF tick while open. This continually grows the inline style string and does unnecessary work; it’s safer and cheaper to assign properties directly, e.g.:
overlayEl.style.position = style.position overlayEl.style.left = style.left overlayEl.style.transform = style.transformkeeping the existing explicit
top/bottomassignments as‑is. That avoids unboundedcssTextgrowth and makes future overrides easier to reason about.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/components/graph/selectionToolbox/MenuOptionItem.vue(3 hunks)src/components/graph/selectionToolbox/NodeOptions.vue(9 hunks)src/components/input/SearchBox.vue(1 hunks)src/composables/useContextMenuTranslation.ts(3 hunks)src/lib/litegraph/src/LGraphCanvas.ts(2 hunks)src/lib/litegraph/src/contextMenuCompat.ts(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/graph/selectionToolbox/MenuOptionItem.vue
🧰 Additional context used
🧬 Code graph analysis (3)
src/lib/litegraph/src/LGraphCanvas.ts (1)
src/lib/litegraph/src/interfaces.ts (1)
IContextMenuValue(405-426)
src/lib/litegraph/src/contextMenuCompat.ts (2)
src/lib/litegraph/src/interfaces.ts (1)
IContextMenuValue(405-426)src/lib/litegraph/src/LGraphCanvas.ts (1)
LGraphCanvas(251-8596)
src/composables/useContextMenuTranslation.ts (3)
src/lib/litegraph/src/interfaces.ts (1)
IContextMenuValue(405-426)src/lib/litegraph/src/LGraphCanvas.ts (3)
getCanvasMenuOptions(8012-8048)LGraphCanvas(251-8596)item(3492-3508)src/lib/litegraph/src/contextMenuCompat.ts (1)
legacyMenuCompat(164-164)
⏰ 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: setup
- GitHub Check: lint-and-format
- GitHub Check: test
- GitHub Check: collect
🔇 Additional comments (6)
src/components/input/SearchBox.vue (1)
65-70: ExposingfocusInputfor parent control is appropriate here
focusInputsafely guards the InputText ref and exposing it viadefineExposegives callers (e.g.NodeOptions.vue) a clean way to focus the field without leaking internals.Also applies to: 94-96
src/composables/useContextMenuTranslation.ts (1)
25-28: Node/canvas menu wrappers correctly merge extension and legacy itemsThe updated wrappers for
getCanvasMenuOptions/getNodeMenuOptionscleanly:
- call the original implementation,
- append new extension items (
collectCanvasMenuItems/collectNodeMenuItems),- then append legacy monkey‑patched items via
legacyMenuCompat.extractLegacyItems(...),
all under a unified(IContextMenuValue | null)[]return type. This preserves legacy behavior while enabling the new extension API and keepstranslateMenus’ expectations intact.Also applies to: 64-66, 73-91, 97-102
src/lib/litegraph/src/contextMenuCompat.ts (4)
10-12: Type signature correctly updated to support nullable menu items.The change from
IContextMenuValue[]to(IContextMenuValue | null)[]aligns with the broader API updates in LGraphCanvas that now support nullable menu items.
65-99: Installation logic correctly tracks monkey-patching with deprecation warnings.The method properly:
- Stores the original method
- Uses a property setter to detect monkey-patching
- Issues deprecation warnings with extension identification
- Maintains a set to avoid duplicate warnings
Note: The same type safety concerns from lines 48-55 apply to the casting at lines 72-75.
48-55: Type safety is lost through double casting; no signature validation exists.The pattern
as unknown as ContextMenuValueProvider(lines 50, 54) completely bypasses TypeScript's type checking. While this may be necessary for the compatibility layer to work with Map storage, there is no runtime signature validation. When methods are retrieved and invoked at line 143 (methodToCall.apply(context, args)), there are only identity checks (e.g.,currentMethod === registeredWrapper) but no verification that the method actually matches theContextMenuValueProvidersignature. If a caller registers a method with an incompatible signature, the code will fail at runtime without error handling.Add signature validation in
registerWrapperto verify that the provided method returns the expected type, or add a try-catch around the.apply()invocation at line 143 to gracefully handle signature mismatches.
112-161: No issues found—null entries are safely handled downstream.The
extractLegacyItemscall sites inuseContextMenuTranslation.tspush returned items (including nulls) into theresarray. Later iteration safely accesses properties using optional chaining:if (item?.content) { item.content = ... }. This pattern correctly handles null values without errors.
- Create NodeContextMenu.vue using pure PrimeVue ContextMenu - Remove custom positioning logic, let PrimeVue handle it - Delete NodeOptions.vue and MenuOptionItem.vue - Mount NodeContextMenu in SelectionToolbox - Update test stubs
- Rename SubmenuPopover.vue to ColorPickerMenu.vue - Add isColorPicker prop to MenuOption interface - Use isColorPicker flag instead of checking submenu colors - Fix onClickOutside immediate close with ignore option
- Delete useSubmenuPositioning.ts (no longer used) - Delete useViewportAwareMenuPositioning.ts (no longer used) - Remove unused exports from useSelectionToolboxPosition.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/composables/canvas/useSelectionToolboxPosition.ts (1)
23-23: Consider updating comment to reflect internal scope.The comment describes these as "Shared signals" but they're now module-private. Consider rewording to "Internal signals" or "Module-scoped signals" for clarity.
-// Shared signals for auxiliary UI (e.g., MoreOptions) to coordinate hide/restore +// Internal signals for auxiliary UI (e.g., MoreOptions) to coordinate hide/restoresrc/components/graph/NodeContextMenu.vue (2)
4-18: Add keyboard accessibility to the custom menu item anchor.The custom anchor element lacks keyboard accessibility attributes. Users navigating via keyboard won't be able to interact with color submenu items properly.
Consider adding
role="menuitem"and keyboard event handling:<a v-bind="props.action" class="flex items-center gap-2 px-3 py-1.5" + role="menuitem" @click="item.isColorSubmenu ? showColorPopover($event) : undefined" + @keydown.enter="item.isColorSubmenu ? showColorPopover($event) : undefined" >
126-136: Type assertionas MouseEventmay be unsafe.The
togglefunction accepts a genericEventbut casts it toMouseEventwhen callingshow(). Iftoggleis called with a keyboard event (e.g., Enter key), the cast would be incorrect and could cause issues withcontextMenu.value?.show(event)if it relies on mouse-specific properties.Consider handling both event types:
function toggle( event: Event, _element?: HTMLElement, _clickedFromToolbox?: boolean ) { if (isOpen.value) { hide() } else { - show(event as MouseEvent) + if (event instanceof MouseEvent) { + show(event) + } else { + // For keyboard events, show at a default position or use the target element + const target = event.target as HTMLElement + const rect = target.getBoundingClientRect() + const syntheticEvent = new MouseEvent('contextmenu', { + clientX: rect.left, + clientY: rect.bottom + }) + show(syntheticEvent) + } } }src/components/graph/selectionToolbox/ColorPickerMenu.vue (1)
84-95: Consider viewport boundary checking for the positioned menu.The
showToRightfunction positions the menu to the right of the target element but doesn't check if the menu would overflow the viewport. Per the PR objectives, viewport-aware positioning was introduced to prevent overflow.Consider adding viewport boundary checks:
const showToRight = (target: HTMLElement) => { const rect = target.getBoundingClientRect() + const menuWidth = 200 // Approximate menu width, or measure after render + const viewportWidth = window.innerWidth + + let left = rect.right + 4 + // If menu would overflow right edge, position to the left of target + if (left + menuWidth > viewportWidth) { + left = rect.left - menuWidth - 4 + } + position.value = { top: rect.top, - left: rect.right + 4 + left } isVisible.value = true justOpened = true setTimeout(() => { justOpened = false }, 0) }src/composables/graph/useMoreOptionsMenu.ts (1)
183-250: Section assembly is coherent; consider avoiding duplicate getNodeVisualOptions callsThe restructuring into explicit sections (basic selection, node/group actions, structure, properties, image) reads clearly and composes well with
buildStructuredMenu. Guards forgroupContext,hasMultipleNodes,hasImageNode, andhasOutputNodesSelectedkeep the menu context‑sensitive.One small cleanup:
getNodeVisualOptions(states, bump)is called twice when!groupContext(once for the Minimize/Expand entry and once for Shape/Color). You can compute it once and reuse to avoid duplicated work and keep the mapping between indices and semantics in one place:- if (groupContext) { - const fitGroup = getFitGroupToNodesOption(groupContext) - options.push(fitGroup) - } else { - // Add minimize/expand option only - const visualOptions = getNodeVisualOptions(states, bump) - if (visualOptions.length > 0) { - options.push(visualOptions[0]) // Minimize/Expand - } - } + let visualOptions: MenuOption[] = [] + if (groupContext) { + const fitGroup = getFitGroupToNodesOption(groupContext) + options.push(fitGroup) + } else { + // Add minimize/expand option only + visualOptions = getNodeVisualOptions(states, bump) + if (visualOptions.length > 0) { + options.push(visualOptions[0]) // Minimize/Expand + } + } @@ - if (groupContext) { + if (groupContext) { const groupColor = getGroupColorOptions(groupContext, bump) options.push(groupColor) } else { // Add shape and color options - const visualOptions = getNodeVisualOptions(states, bump) if (visualOptions.length > 1) { options.push(visualOptions[1]) // Shape (index 1) } if (visualOptions.length > 2) { options.push(visualOptions[2]) // Color (index 2) } }Purely an ergonomics/readability improvement; behavior stays the same.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/components/graph/GraphCanvas.vue(0 hunks)src/components/graph/NodeContextMenu.vue(1 hunks)src/components/graph/SelectionToolbox.test.ts(1 hunks)src/components/graph/SelectionToolbox.vue(2 hunks)src/components/graph/selectionToolbox/ColorPickerMenu.vue(4 hunks)src/components/graph/selectionToolbox/MenuOptionItem.vue(0 hunks)src/components/graph/selectionToolbox/NodeOptions.vue(0 hunks)src/composables/canvas/useSelectionToolboxPosition.ts(1 hunks)src/composables/graph/useMoreOptionsMenu.ts(5 hunks)src/composables/graph/useNodeMenuOptions.ts(2 hunks)src/composables/graph/useSubmenuPositioning.ts(0 hunks)
💤 Files with no reviewable changes (4)
- src/components/graph/GraphCanvas.vue
- src/composables/graph/useSubmenuPositioning.ts
- src/components/graph/selectionToolbox/NodeOptions.vue
- src/components/graph/selectionToolbox/MenuOptionItem.vue
🧰 Additional context used
📓 Path-based instructions (21)
**/*.{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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
src/components/graph/SelectionToolbox.test.tssrc/composables/canvas/useSelectionToolboxPosition.tssrc/composables/graph/useMoreOptionsMenu.tssrc/composables/graph/useNodeMenuOptions.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Use TypeScript for type safety
**/*.{ts,tsx}: Never useanytype - use proper TypeScript types
Never useas anytype assertions - fix the underlying type issue
Files:
src/components/graph/SelectionToolbox.test.tssrc/composables/canvas/useSelectionToolboxPosition.tssrc/composables/graph/useMoreOptionsMenu.tssrc/composables/graph/useNodeMenuOptions.ts
**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committing
Files:
src/components/graph/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.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/components/graph/SelectionToolbox.test.tssrc/composables/canvas/useSelectionToolboxPosition.tssrc/composables/graph/useMoreOptionsMenu.tssrc/composables/graph/useNodeMenuOptions.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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/graph/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
UsedefaultsByInstallVersionproperty for gradual feature rollout based on version in settings configuration
Files:
src/components/graph/SelectionToolbox.test.tssrc/composables/canvas/useSelectionToolboxPosition.tssrc/composables/graph/useMoreOptionsMenu.tssrc/composables/graph/useNodeMenuOptions.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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/graph/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/canvas/useSelectionToolboxPosition.tssrc/components/graph/SelectionToolbox.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vuesrc/composables/graph/useNodeMenuOptions.ts
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/SelectionToolbox.test.tssrc/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vue
**/*.{test,spec}.{ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Unit and component tests should be located in
tests-ui/or co-located with components assrc/components/**/*.{test,spec}.ts; E2E tests should be inbrowser_tests/
Files:
src/components/graph/SelectionToolbox.test.ts
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vuesrc/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventionsFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vuesrc/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vuesrc/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system packageFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/SelectionToolbox.vuesrc/components/graph/NodeContextMenu.vuesrc/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directlyFiles:
src/composables/canvas/useSelectionToolboxPosition.tssrc/composables/graph/useMoreOptionsMenu.tssrc/composables/graph/useNodeMenuOptions.ts🧠 Learnings (25)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverLearnt 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 panelsLearnt 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 SelectLearnt 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 DrawerLearnt 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 respectivelyLearnt 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)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 InlineMessage component with MessageLearnt 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 ToggleSwitchLearnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerLearnt 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📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/lib/litegraph/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:56.371Z Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setupApplied to files:
src/components/graph/SelectionToolbox.test.tssrc/composables/graph/useMoreOptionsMenu.ts📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: tests-ui/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:48:03.270Z Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in testsApplied to files:
src/components/graph/SelectionToolbox.test.ts📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: tests-ui/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:48:03.270Z Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new featuresApplied to files:
src/components/graph/SelectionToolbox.test.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}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursorApplied to files:
src/components/graph/SelectionToolbox.test.ts📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/lib/litegraph/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:56.371Z Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : When writing tests for subgraph-related code, always import from the barrel export at `@/lib/litegraph/src/litegraph` to avoid circular dependency issuesApplied to files:
src/components/graph/SelectionToolbox.test.ts📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: tests-ui/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:48:03.270Z Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilitiesApplied to files:
src/components/graph/SelectionToolbox.test.ts📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with SelectApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panelsApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.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/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitchApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with DrawerApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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 InlineMessage component with MessageApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabledApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listenersApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue filesApplied to files:
src/components/graph/SelectionToolbox.vue📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guideApplied to files:
src/composables/graph/useMoreOptionsMenu.tssrc/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/lib/litegraph/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:56.371Z Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriateApplied to files:
src/composables/graph/useMoreOptionsMenu.ts📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Leverage VueUse functions for performance-enhancing utilitiesApplied to files:
src/composables/graph/useMoreOptionsMenu.ts📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing stylesApplied to files:
src/composables/graph/useMoreOptionsMenu.ts📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3Applied to files:
src/composables/graph/useMoreOptionsMenu.ts📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)Applied to files:
src/components/graph/NodeContextMenu.vue🧬 Code graph analysis (1)
src/composables/graph/useMoreOptionsMenu.ts (5)
src/renderer/core/canvas/canvasStore.ts (1)
useCanvasStore(24-152)src/composables/graph/useImageMenuOptions.ts (1)
useImageMenuOptions(11-108)src/composables/graph/useNodeMenuOptions.ts (1)
useNodeMenuOptions(12-129)src/composables/graph/useGroupMenuOptions.ts (1)
useGroupMenuOptions(16-196)src/composables/graph/contextMenuConverter.ts (2)
convertContextMenuToOptions(358-447)buildStructuredMenu(253-349)🪛 ESLint
src/components/graph/selectionToolbox/ColorPickerMenu.vue
[error] 51-51: Unable to resolve path to module '@comfyorg/tailwind-utils'.
(import-x/no-unresolved)
[error] 52-52: Unable to resolve path to module '@vueuse/core'.
(import-x/no-unresolved)
src/components/graph/SelectionToolbox.vue
[error] 72-72: Unable to resolve path to module './NodeContextMenu.vue'.
(import-x/no-unresolved)
src/composables/graph/useMoreOptionsMenu.ts
[error] 5-5: Unable to resolve path to module '@/renderer/core/canvas/canvasStore'.
(import-x/no-unresolved)
[error] 6-6: Unable to resolve path to module '@/utils/litegraphUtil'.
(import-x/no-unresolved)
[error] 11-11: Unable to resolve path to module './contextMenuConverter'.
(import-x/no-unresolved)
src/components/graph/NodeContextMenu.vue
[error] 1-1: Resolve error: EACCES: permission denied, open '/saEQzionsM'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/bOzMFyGRnd'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/socnuAABhC'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 1-1: Resolve error: EACCES: permission denied, open '/IUYggMyLaY'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/ZppeldVgLu'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 32-32: Unable to resolve path to module 'primevue/contextmenu'.
(import-x/no-unresolved)
[error] 34-34: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
[error] 39-39: Unable to resolve path to module '@/composables/graph/useMoreOptionsMenu'.
(import-x/no-unresolved)
[error] 45-45: Unable to resolve path to module './selectionToolbox/ColorPickerMenu.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: setup
- GitHub Check: test
- GitHub Check: lint-and-format
- GitHub Check: collect
…e in ColorPickerMenu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/components/graph/selectionToolbox/ColorPickerMenu.vue (1)
24-27: Remove duplicate hover class.Line 26 contains
hover:bg-secondary-background-hoverwhich is already applied on line 20, making it redundant.Apply this diff:
subOption.disabled ? 'cursor-not-allowed pointer-events-none text-node-icon-disabled' - : 'hover:bg-secondary-background-hover' + : ''Note: The
dark-theme:variant usage on line 26 was already flagged in a previous review.
🧹 Nitpick comments (1)
src/components/graph/selectionToolbox/ColorPickerMenu.vue (1)
109-120: Consider more maintainable ignore selectors.The ignore selectors rely on hardcoded PrimeVue internal class names (
.p-contextmenu,.p-contextmenu-item-link). If PrimeVue changes these class names in a future version, the click-outside behavior will break.Consider using data attributes or template refs for more maintainable ignore logic:
// Option 1: Pass parent context menu ref as prop onClickOutside( popoverRef, () => { if (justOpened) { justOpened = false return } hide() }, { ignore: [props.parentMenuRef] } ) // Option 2: Use data attribute selectors { ignore: ['[data-context-menu]', '[data-context-menu-item]'] }Then add the corresponding data attributes to the parent ContextMenu component's template.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/graph/selectionToolbox/ColorPickerMenu.vue(4 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventionsFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.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/graph/selectionToolbox/ColorPickerMenu.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebaseFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.jsonFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system packageFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vuesrc/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI stringsFiles:
src/components/graph/selectionToolbox/ColorPickerMenu.vue🧠 Learnings (17)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverLearnt 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 respectivelyLearnt 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 SelectLearnt 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 panelsLearnt 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)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 DrawerLearnt 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 ToggleSwitchLearnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerLearnt 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 InlineMessage component with MessageLearnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with SelectApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panelsApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitchApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with DrawerApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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 InlineMessage component with MessageApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabledApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:14.779Z Learning: Applies to **/*.vue : Never use `:class="[]"` to merge class names - always use `import { cn } from '@/utils/tailwindUtil'` for class merging in Vue templatesApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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,css} : Use the correct tokens from style.css in the design system packageApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.vue : Use Tailwind CSS for stylingApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.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 : Implement responsive design with Tailwind CSSApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listenersApplied to files:
src/components/graph/selectionToolbox/ColorPickerMenu.vue🪛 ESLint
src/components/graph/selectionToolbox/ColorPickerMenu.vue
[error] 51-51: Unable to resolve path to module '@comfyorg/tailwind-utils'.
(import-x/no-unresolved)
[error] 52-52: Unable to resolve path to module '@vueuse/core'.
(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: setup
- GitHub Check: lint-and-format
- GitHub Check: test
- GitHub Check: collect
🔇 Additional comments (1)
src/components/graph/selectionToolbox/ColorPickerMenu.vue (1)
129-131: LGTM!The early return for disabled submenu options correctly prevents actions from being triggered on disabled items.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/graph/NodeContextMenu.vue (1)
117-120: Clarify the purpose ofbump()call.Line 118 calls
bump()before showing the context menu. While this likely refreshes the menu options, consider adding a comment to explain its purpose for future maintainers.function show(event: MouseEvent) { + // Refresh menu options before displaying bump() contextMenu.value?.show(event) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/graph/NodeContextMenu.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/graph/NodeContextMenu.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/NodeContextMenu.vue**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/components/graph/NodeContextMenu.vuesrc/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventionsFiles:
src/components/graph/NodeContextMenu.vuesrc/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/NodeContextMenu.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/graph/NodeContextMenu.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/graph/NodeContextMenu.vue**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
src/components/graph/NodeContextMenu.vuesrc/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebaseFiles:
src/components/graph/NodeContextMenu.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/graph/NodeContextMenu.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/graph/NodeContextMenu.vuesrc/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.jsonFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system packageFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI stringsFiles:
src/components/graph/NodeContextMenu.vue🧠 Learnings (11)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverLearnt 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 respectivelyLearnt 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 SelectLearnt 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 panelsLearnt 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)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 DrawerLearnt 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 ToggleSwitchLearnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerLearnt 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 InlineMessage component with MessageLearnt 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📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panelsApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with DrawerApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with SelectApplied to files:
src/components/graph/NodeContextMenu.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/NodeContextMenu.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitchApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)Applied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:48:23.088Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-11-24T19:48:23.088Z Learning: Applies to **/*.vue : Name Vue components in PascalCase (e.g., `MenuHamburger.vue`)Applied to files:
src/components/graph/NodeContextMenu.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 InlineMessage component with MessageApplied to files:
src/components/graph/NodeContextMenu.vue🪛 ESLint
src/components/graph/NodeContextMenu.vue
[error] 1-1: Resolve error: EACCES: permission denied, open '/SBDDjiZKMN'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/cFsKQTujGL'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/eRcSMJPorO'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 1-1: Resolve error: EACCES: permission denied, open '/huRjmINgMY'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/qsAqdrUujK'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 35-35: Unable to resolve path to module 'primevue/contextmenu'.
(import-x/no-unresolved)
[error] 37-37: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
[error] 42-42: Unable to resolve path to module '@/composables/graph/useMoreOptionsMenu'.
(import-x/no-unresolved)
[error] 48-48: Unable to resolve path to module './selectionToolbox/ColorPickerMenu.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). (5)
- GitHub Check: deploy-and-comment
- GitHub Check: test
- GitHub Check: setup
- GitHub Check: lint-and-format
- GitHub Check: collect
🔇 Additional comments (5)
src/components/graph/NodeContextMenu.vue (5)
50-54: LGTM!The ExtendedMenuItem interface properly extends PrimeVue's MenuItem with custom properties needed for color submenu handling and shortcuts.
73-109: LGTM!The conversion logic correctly transforms MenuOption structures into PrimeVue-compatible MenuItem objects, handling dividers, color submenus, native submenus, and action items appropriately.
123-139: LGTM!The hide and toggle functions correctly manage both the context menu and color picker states. The unused parameters in
toggleare appropriately prefixed with underscores to indicate they're present for API compatibility.
143-148: Event handling prevents default behavior for color picker.Lines 144-145 stop event propagation and prevent default behavior to enable the custom ColorPickerMenu. This is necessary for the functionality but may affect accessibility features.
Ensure this custom handling doesn't break keyboard navigation or screen reader announcements. Consider adding keyboard event handling (Enter/Space keys) to activate the color picker.
4-21: Custom click handler may interfere with keyboard navigation.Line 7 intercepts clicks on color submenu items with a custom handler. While this enables the custom ColorPickerMenu, it may bypass PrimeVue's native keyboard navigation and ARIA attributes for submenus.
Verify that keyboard users can navigate to and activate the color submenu using standard arrow keys and Enter/Space. Test with a screen reader to ensure the submenu is properly announced.
…ow and adjust submenu test interaction to hover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/components/graph/NodeContextMenu.vue (1)
171-174: Remove redundant initialization.Line 172 sets
isOpen.value = false, but the ref is already initialized tofalseon line 63. This redundant initialization can be removed.onMounted(() => { - isOpen.value = false registerNodeOptionsInstance({ toggle, hide, isOpen }) })
🧹 Nitpick comments (2)
browser_tests/tests/selectionToolboxSubmenus.spec.ts (1)
144-144: Note the timing dependency for future maintenance.The added 500ms delay suggests timing sensitivity in the menu rendering flow. While pragmatic for handling UI animations in E2E tests, consider whether explicit state checks (e.g., waiting for specific visibility conditions) could provide more robust synchronization if flakiness occurs.
src/components/graph/NodeContextMenu.vue (1)
77-114: Consider removing non-null assertion on Line 108.The condition at line 106 already guards against undefined
option.action, making the non-null assertion (!) on line 108 unnecessary. TypeScript should infer the type correctly within the conditional block.// Regular action items if (!option.hasSubmenu && option.action) { item.command = () => { - option.action!() + option.action() hide() } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
browser_tests/tests/selectionToolboxSubmenus.spec.ts(2 hunks)src/components/graph/NodeContextMenu.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (21)
**/*.{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:
browser_tests/tests/selectionToolboxSubmenus.spec.tssrc/components/graph/NodeContextMenu.vue
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Use TypeScript for type safety
**/*.{ts,tsx}: Never useanytype - use proper TypeScript types
Never useas anytype assertions - fix the underlying type issue
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committing
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.tssrc/components/graph/NodeContextMenu.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.tssrc/components/graph/NodeContextMenu.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.tssrc/components/graph/NodeContextMenu.vue
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
UsedefaultsByInstallVersionproperty for gradual feature rollout based on version in settings configuration
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (browser_tests/CLAUDE.md)
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}: Test user workflows in browser tests
Use Playwright fixtures for browser tests
Follow naming conventions for browser tests
Check assets/ directory for test data when writing tests
Prefer specific selectors in browser tests
Test across multiple viewports
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
**/*.{test,spec}.{ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Unit and component tests should be located in
tests-ui/or co-located with components assrc/components/**/*.{test,spec}.ts; E2E tests should be inbrowser_tests/
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
browser_tests/**/*.{test,spec}.ts
📄 CodeRabbit inference engine (AGENTS.md)
Playwright E2E tests can use optional tags like
@mobileand@2xwhich are respected by the Playwright configuration
Files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/graph/NodeContextMenu.vuesrc/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventionsFiles:
src/components/graph/NodeContextMenu.vuesrc/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonFiles:
src/components/graph/NodeContextMenu.vue**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/components/graph/NodeContextMenu.vuesrc/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebaseFiles:
src/components/graph/NodeContextMenu.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/graph/NodeContextMenu.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/graph/NodeContextMenu.vuesrc/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.jsonFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system packageFiles:
src/components/graph/NodeContextMenu.vuesrc/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI stringsFiles:
src/components/graph/NodeContextMenu.vue🧠 Learnings (13)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverLearnt 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 respectivelyLearnt 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 SelectLearnt 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 panelsLearnt 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)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 DrawerLearnt 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 ToggleSwitchLearnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePickerLearnt 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 InlineMessage component with MessageLearnt 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📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: browser_tests/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:22.909Z Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser testsApplied to files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: tests-ui/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:48:03.270Z Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new featuresApplied to files:
browser_tests/tests/selectionToolboxSubmenus.spec.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} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setupApplied to files:
browser_tests/tests/selectionToolboxSubmenus.spec.ts📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panelsApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with DrawerApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with SelectApplied to files:
src/components/graph/NodeContextMenu.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/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitchApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectivelyApplied to files:
src/components/graph/NodeContextMenu.vue📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)Applied to files:
src/components/graph/NodeContextMenu.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 InlineMessage component with MessageApplied to files:
src/components/graph/NodeContextMenu.vue🪛 ESLint
src/components/graph/NodeContextMenu.vue
[error] 1-1: Resolve error: EACCES: permission denied, open '/NErjAYlgqW'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/AXlBoBVYJj'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/swPdNraMfj'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 1-1: Resolve error: EACCES: permission denied, open '/nMxsMqRyaq'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/mTwechUZrS'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__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+utils@8.44.0_eslint@9.35.0_jiti@2.5.1__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.35.0_jiti@2.5.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 40-40: Unable to resolve path to module 'primevue/contextmenu'.
(import-x/no-unresolved)
[error] 42-42: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
[error] 47-47: Unable to resolve path to module '@/composables/graph/useMoreOptionsMenu'.
(import-x/no-unresolved)
[error] 53-53: Unable to resolve path to module './selectionToolbox/ColorPickerMenu.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: collect
- GitHub Check: lint-and-format
- GitHub Check: setup
- GitHub Check: test
🔇 Additional comments (9)
browser_tests/tests/selectionToolboxSubmenus.spec.ts (1)
90-90: LGTM! Hover-based submenu reveal aligned with new UI pattern.The change from
.click()to.hover()correctly reflects the updated submenu interaction model where Shape submenu options are revealed on hover rather than click.src/components/graph/NodeContextMenu.vue (8)
1-37: LGTM! Clean template structure with proper semantic styling.The template correctly uses PrimeVue ContextMenu (not deprecated) with custom item rendering, semantic Tailwind classes from the design system, and conditional ColorPickerMenu integration.
39-59: LGTM! Proper imports and type definitions.Imports are well-organized, types are properly defined, and the ExtendedMenuItem interface cleanly extends PrimeVue's MenuItem with additional properties needed for this component.
61-75: LGTM! Proper ref declarations and composable integration.Refs are correctly typed, the composable is properly integrated, and the helper functions for identifying color options are straightforward.
116-119: LGTM! Clean computed property.The menuItems computed property is concise and follows Vue 3 Composition API best practices.
121-145: LGTM! Well-structured menu control functions.The show/hide/toggle functions properly manage menu state and coordinate between the context menu and color picker. The toggle signature accommodates different calling patterns for compatibility.
147-147: LGTM! Appropriate public API exposure.defineExpose correctly exposes imperative operations (toggle, show, hide) and state (isOpen) for parent component coordination, following Vue 3 best practices.
149-160: LGTM! Proper color picker integration.Event handling correctly prevents bubbling, and the color selection flow properly executes actions and closes menus. Good separation of concerns.
162-169: LGTM! Consistent state management in event handlers.Event handlers properly maintain isOpen state and coordinate cleanup of both the context menu and color picker on hide.
… initialization in node context menu.
…and improve legacy item extraction robustness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/composables/graph/contextMenuConverter.ts (1)
397-417: Static string-based submenus still lose their parent callbacksStatic submenus with string items and a parent
options.callbackare still not wired correctly:
- In the static branch you call
convertSubmenuToOptions(item.submenu.options)(no second argument).convertSubmenuToOptionsexpects the submenuoptionsobject to be passed so it can calloptions.callbackfor string items.- Dynamic submenus correctly pass both
capturedItemsandcapturedOptions.This means static submenus defined as
submenu: { options: ['foo', 'bar'], callback (…) { … } }will render, but clicking items won’t invoke the callback.This is the same issue highlighted in the previous review, and the fix is to pass the submenu object through:
- if (item.has_submenu) { - // Static submenu with pre-defined options - if (item.submenu?.options) { - option.hasSubmenu = true - option.submenu = convertSubmenuToOptions(item.submenu.options) - } + if (item.has_submenu) { + // Static submenu with pre-defined options + if (item.submenu?.options) { + option.hasSubmenu = true + // Pass submenu options object so string items can call options.callback + option.submenu = convertSubmenuToOptions( + item.submenu.options, + item.submenu + ) + }This will align static submenu behavior with the dynamic path and ensure string-based submenu items invoke their callbacks.
Also applies to: 452-522, 527-599
🧹 Nitpick comments (4)
src/lib/litegraph/src/contextMenuCompat.ts (1)
42-58: Normalize map keys and types for wrapper/original method tracking
originalMethods,wrapperMethods,preWrapperMethods, andwrapperInstalledare keyed asMap<string, …>, but yousetwithmethodName as stringand latergetwithmethodNametyped askeyof LGraphCanvas. This works at runtime (these keys are effectively strings), but it’s a bit brittle and noisy for TypeScript.Consider normalizing the key as a string once and reusing it for both
setandget, and tightening the type to a string key:- registerWrapper<K extends keyof LGraphCanvas>( - methodName: K, + registerWrapper<K extends keyof LGraphCanvas & string>( + methodName: K, wrapperFn: LGraphCanvas[K], preWrapperFn: LGraphCanvas[K], prototype?: LGraphCanvas ) { - this.wrapperMethods.set( - methodName as string, + const key = methodName as string + this.wrapperMethods.set( - methodName as string, + key, wrapperFn as unknown as ContextMenuValueProvider ) - this.preWrapperMethods.set( - methodName as string, + this.preWrapperMethods.set( - methodName as string, + key, preWrapperFn as unknown as ContextMenuValueProvider ) const isInstalled = prototype && prototype[methodName] === wrapperFn - this.wrapperInstalled.set(methodName as string, !!isInstalled) + this.wrapperInstalled.set(key, !!isInstalled) } @@ - install<K extends keyof LGraphCanvas>( - prototype: LGraphCanvas, - methodName: K + install<K extends keyof LGraphCanvas & string>( + prototype: LGraphCanvas, + methodName: K ) { @@ - const originalMethod = prototype[methodName] - this.originalMethods.set( - methodName as string, + const key = methodName as string + const originalMethod = prototype[methodName] + this.originalMethods.set( - methodName as string, + key, originalMethod as unknown as ContextMenuValueProvider ) @@ - const originalMethod = this.originalMethods.get(methodName) + const key = methodName as string + const originalMethod = this.originalMethods.get(key) @@ - const registeredWrapper = this.wrapperMethods.get(methodName) + const registeredWrapper = this.wrapperMethods.get(key) @@ - const preWrapperMethod = this.preWrapperMethods.get(methodName) - const wrapperWasInstalled = this.wrapperInstalled.get(methodName) + const preWrapperMethod = this.preWrapperMethods.get(key) + const wrapperWasInstalled = this.wrapperInstalled.get(key)This keeps the runtime behavior identical while tightening types and avoiding accidental symbol/number keys. As per coding guidelines, ...
Also applies to: 65-76, 124-143
src/components/graph/NodeContextMenu.vue (1)
9-27: Verify interaction betweenprops.actionand color submenu click handlerFor color submenu entries you bind both:
v-bind="props.action"(PrimeVue’s internal click handling), and@click="item.isColorSubmenu ? showColorPopover($event) : undefined", whereshowColorPopovercallsstopPropagation()/preventDefault()and toggles the custom color picker.Depending on how PrimeVue wires
props.action.onClick, this could result in:
- the menu still closing when clicking the color submenu, or
- internal selection logic running in addition to
showColorPopover.Given
convertToMenuItemintentionally omitscommand/itemsforisColorSubmenu, this is probably fine, but it’s worth explicitly confirming behavior:
- Clicking the “Color” row should only open the ColorPickerMenu and not trigger any unintended selection or close the main context menu prematurely.
If you observe interference, consider centralizing the click logic (e.g., by handling color submenu via
commandinstead of an extra@click, or by overriding the click handler inprops.actionforisColorSubmenuitems).Also applies to: 84-115, 150-170
src/composables/graph/contextMenuConverter.ts (2)
253-349: Structured core vs. extensions layout is clear; consider i18n for the “Extensions” label
buildStructuredMenucleanly:
- Dedupes options,
- Buckets known core items by label with
isCoreMenuItem,- Orders them via
MENU_ORDERwith section-based dividers,- Groups everything else under a non-clickable “Extensions” category,
- Ensures Delete/Remove is always separated at the bottom.
From a UX standpoint this matches the PR’s intent and should keep menus predictable.
Given repo guidelines about i18n in composables/components, you might eventually want to pull the
'Extensions'label fromvue-i18n(or at least centralize it behind a constant keyed to translations), but that’s more of a follow-up polish than a blocker here.
358-447: Reduce newanyusage in type signatures if possibleThis composable introduces a few new
anys:
node?: anyinconvertContextMenuToOptions/captureDynamicSubmenu,capturedOptions: anyandoptions?: anyin submenu handling.Given the guidelines about avoiding
any, consider tightening these to more descriptive types, even if they’re partial LiteGraph shapes (e.g., aLiteGraphContextMenuOptionsinterface with justcallback?: …; extra?: unknown;). Where you truly can’t model the type,unknownplus narrowing at use sites is often safer thanany.Not a blocker, but it will make this bridge easier to reason about and safer to evolve.
Also applies to: 453-522, 527-599
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/components/graph/selectionToolbox/ColorPickerMenu.vue (1)
84-95: Consider viewport-aware positioning for the color picker popover
showToRightpositions the menu atrect.top/rect.right + 4with no clamping or flipping; near the right or bottom edge this can overflow the viewport and partially hide the color picker. Given this submenu can appear near screen edges, it would be safer to reuse the viewport-aware positioning utility introduced elsewhere in this PR (or add simple width/height-based clamping) so the menu always stays within visible bounds.Also applies to: 109-120
src/composables/graph/contextMenuConverter.ts (1)
400-402: Static submenu missing options object for string-based callbacks.Per the past review comment, static submenus at line 402 don't pass the parent
optionsobject toconvertSubmenuToOptions. This causes string-based submenu items to lose their callbacks sinceconvertSubmenuToOptionsat line 546 callsoptions?.callback, which would be undefined.Apply this fix to align static and dynamic submenu handling:
if (item.submenu?.options) { option.hasSubmenu = true - option.submenu = convertSubmenuToOptions(item.submenu.options) + option.submenu = convertSubmenuToOptions(item.submenu.options, item.submenu) }
🧹 Nitpick comments (5)
src/components/graph/NodeContextMenu.vue (1)
69-115: Consider decoupling color‑submenu click handling from PrimeVue’sprops.actionThe overall ContextMenu wiring and
MenuOption→ExtendedMenuItemconversion look solid, including divider handling, disabled states, and native submenus. The color submenu flow viaisColorPicker/isColorSubmenuandColorPickerMenuis also clear.For the color item specifically, you currently both:
- Spread
v-bind="props.action"on the<a>; and- Attach
@click="item.isColorSubmenu ? showColorPopover($event) : undefined".This relies on PrimeVue’s internal click handling not conflicting with your custom color popover behavior (e.g., not closing the menu before
toggleruns). To make this more robust and intention‑revealing, you could skip bindingprops.actionfor color items entirely, e.g.:- <a - v-bind="props.action" - class="flex items-center gap-2 px-3 py-1.5" - @click="item.isColorSubmenu ? showColorPopover($event) : undefined" - > + <a + v-bind="item.isColorSubmenu ? {} : props.action" + class="flex items-center gap-2 px-3 py-1.5" + @click=" + item.isColorSubmenu + ? showColorPopover($event) + : props.action?.onClick?.($event) + " + >Optionally, to align strictly with the guidance “use
defineExposeonly for imperative operations”, you might later routeisOpenthrough your central options manager instead of exposing it directly, keeping the public API method‑only.Also applies to: 123-161
browser_tests/tests/selectionToolboxSubmenus.spec.ts (1)
90-90: Tests align with new submenu UX; consider replacing raw timeoutsSwitching the Shape interaction to
hovermatches native submenu behavior in the new context menu implementation. The addedwaitForTimeout(500)helps flakiness, but you might get more stable tests by waiting on a specific condition (e.g., menu/overlay hidden or a state change) rather than a fixed delay.Also applies to: 144-145
src/composables/useContextMenuTranslation.ts (1)
64-66: Avoid the type assertion in the node-menu wrapper by typingnodeMenuFn
getNodeMenuOptionsWithExtensionscurrently relies on:const res = nodeMenuFn.apply(this, args) as (IContextMenuValue | null)[]Since
LGraphCanvas.getNodeMenuOptionsis already declared to return(IContextMenuValue | null)[], you can remove this assertion by givingnodeMenuFnan explicit function type and letting TypeScript infer the return type forres. For example:- const nodeMenuFn = LGraphCanvas.prototype.getNodeMenuOptions + const nodeMenuFn: LGraphCanvas['getNodeMenuOptions'] = + LGraphCanvas.prototype.getNodeMenuOptions const getNodeMenuOptionsWithExtensions = function ( this: LGraphCanvas, ...args: Parameters<typeof nodeMenuFn> ) { - const res = nodeMenuFn.apply(this, args) as (IContextMenuValue | null)[] + const res = nodeMenuFn.apply(this, args) // ... }This keeps the runtime behavior identical while eliminating the need for a cast and makes the wrapper’s types track any future changes to the core method.
Also applies to: 73-90, 97-102
src/lib/litegraph/src/contextMenuCompat.ts (1)
42-58: Generic typing improves safety but relies on string casts for Map storage.The generic
K extends keyof LGraphCanvasimproves call-site type safety. The casts tostringfor Map keys are necessary since TypeScript'skeyoftypes don't directly work as Map keys, but consider adding a brief comment explaining this pattern for future maintainers.src/composables/graph/contextMenuConverter.ts (1)
78-84: Normalization may cause unintended matches.The
normalizeLabelfunction strips trailing's'which could cause false positives. For example,'Process'becomes'Proces', or'Status'becomes'Statu'. Consider limiting the normalization to known plural forms or using explicit mappings.function normalizeLabel(label: string): string { - return label - .toLowerCase() - .replace(/s$/, '') // Remove trailing 's' (Colors -> Color, Shapes -> Shape) - .replace(/^un/, '') // Remove 'un' prefix (Unpin -> Pin) - .trim() + const lower = label.toLowerCase().trim() + // Only normalize known plural->singular mappings + const pluralMap: Record<string, string> = { + colors: 'color', + shapes: 'shape' + } + const unprefixMap: Record<string, string> = { + unpin: 'pin' + } + return unprefixMap[lower] ?? pluralMap[lower] ?? lower }
| const HARD_BLACKLIST = new Set([ | ||
| 'Properties', // Never include Properties submenu | ||
| 'Colors', // Use singular "Color" instead | ||
| 'Shapes', // Use singular "Shape" instead | ||
| 'Title', | ||
| 'Mode', | ||
| 'Properties Panel', | ||
| 'Copy (Clipspace)' | ||
| ]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistency between HARD_BLACKLIST and CORE_MENU_ITEMS.
HARD_BLACKLIST contains 'Colors', 'Shapes', 'Title', 'Mode', 'Properties Panel', and 'Copy (Clipspace)' which are also present in CORE_MENU_ITEMS (lines 49-53, 61). Items in the blacklist will be filtered out in convertContextMenuToOptions before they can be categorized as core items. This seems intentional (preferring singular "Color"/"Shape" over plural), but Title, Mode, Properties Panel, and Copy (Clipspace) being in both sets appears contradictory.
Consider removing from CORE_MENU_ITEMS the items that are hard-blacklisted, or add a comment explaining this design choice:
const CORE_MENU_ITEMS = new Set([
// ...
- 'Title',
- 'Properties Panel',
- // ...
- 'Mode',
- // ...
'Color',
- 'Colors',
'Shape',
- 'Shapes',
- // ...
- 'Copy (Clipspace)',
+ // Note: 'Colors', 'Shapes', 'Title', 'Mode', 'Properties Panel', 'Copy (Clipspace)'
+ // are intentionally blacklisted to prefer canonical equivalentsAlso applies to: 49-52
| function stripHtmlTags(html: string): string { | ||
| // Create a temporary element to parse HTML | ||
| const temp = document.createElement('div') | ||
| temp.innerHTML = html | ||
| return temp.textContent || temp.innerText || html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sanitize input to prevent XSS when stripping HTML tags.
Static analysis correctly flagged the innerHTML assignment. While this function processes LiteGraph menu content (trusted source), the pattern is unsafe if content ever comes from untrusted sources. As per coding guidelines, sanitize HTML with DOMPurify.
+import DOMPurify from 'dompurify'
+
function stripHtmlTags(html: string): string {
- // Create a temporary element to parse HTML
- const temp = document.createElement('div')
- temp.innerHTML = html
- return temp.textContent || temp.innerText || html
+ // Sanitize first to prevent XSS, then extract text
+ const sanitized = DOMPurify.sanitize(html, { ALLOWED_TAGS: [] })
+ return sanitized || html
}Alternatively, if DOMPurify is not desired, use a regex-based approach that doesn't involve DOM parsing:
function stripHtmlTags(html: string): string {
- const temp = document.createElement('div')
- temp.innerHTML = html
- return temp.textContent || temp.innerText || html
+ // Remove HTML tags without DOM parsing to avoid XSS risks
+ return html.replace(/<[^>]*>/g, '').trim() || html
}📝 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.
| function stripHtmlTags(html: string): string { | |
| // Create a temporary element to parse HTML | |
| const temp = document.createElement('div') | |
| temp.innerHTML = html | |
| return temp.textContent || temp.innerText || html | |
| import DOMPurify from 'dompurify' | |
| function stripHtmlTags(html: string): string { | |
| // Sanitize first to prevent XSS, then extract text | |
| const sanitized = DOMPurify.sanitize(html, { ALLOWED_TAGS: [] }) | |
| return sanitized || html | |
| } |
🧰 Tools
🪛 ast-grep (0.40.0)
[warning] 607-607: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: temp.innerHTML = html
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 607-607: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: temp.innerHTML = html
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
🤖 Prompt for AI Agents
In src/composables/graph/contextMenuConverter.ts around lines 605 to 609, the
function uses element.innerHTML to strip tags which is unsafe; replace that
DOM-parsing approach with a sanitized flow: import and use DOMPurify to sanitize
the html string first (e.g., DOMPurify.sanitize(html, {ALLOWED_TAGS: []})) then
extract textContent from a temporary element, or if you prefer not to add
DOMPurify, replace the DOM parsing with a safe regex-based stripper (e.g.,
remove tags via html.replace(/<[^>]*>/g, '') and return the result) so no
untrusted HTML is ever assigned to innerHTML.
This pull request introduces several improvements to the node context menu in the graph selection toolbox, focusing on enhanced usability, accessibility, and maintainability. The most significant changes are the addition of a search/filter feature for menu options, improved handling and display of disabled and categorized menu items, and better viewport-aware positioning for popovers and submenus.
Menu Usability & Filtering:
NodeOptions.vue,useMoreOptionsMenu.ts) [1] [2] [3] [4] [5]Menu Item Display & Accessibility:
MenuOptionItem.vue,SubmenuPopover.vue,useMoreOptionsMenu.ts) [1] [2] [3] [4] [5]categoryanddisabledflags, and added asourcefield for distinguishing between hardcoded and dynamic options. (useMoreOptionsMenu.ts) [1] [2]Popover & Submenu Positioning:
NodeOptions.vue,SubmenuPopover.vue) [1] [2]Codebase Maintenance:
NodeOptions.vue,useMoreOptionsMenu.ts) [1] [2] [3] [4]These changes collectively enhance the user experience for interacting with node options, making the menu more navigable, accessible, and robust.
Recording.2025-11-11.235411.mp4