-
Notifications
You must be signed in to change notification settings - Fork 429
style: update ui and design of system notification components (what's new, new release notification, help center) #6300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 11/28/2025, 07:24:29 PM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🎭 Playwright Test Results⏰ Completed at: 11/28/2025, 07:33:05 PM 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.18 MB (baseline 3.18 MB) • 🔴 +247 BMain entry bundles and manifests
Status: 3 added / 3 removed Graph Workspace — 952 kB (baseline 949 kB) • 🔴 +3.38 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 — 139 kB (baseline 139 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 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 |
d9eef91 to
f62a5e4
Compare
467de81 to
e7a6eae
Compare
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughReworks Help Center menu and release UIs (toast and Whats New popup), adds interface-menu CSS tokens, updates localization, replaces a CSS test selector with a data-testid, adds Storybook stories and unit tests, and deletes an obsolete WhatsNewPopup test file. Changes
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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/platform/updates/components/ReleaseNotificationToast.vue (1)
133-148: Add timer cleanup on component unmount.The auto-hide timer is cleared when
shouldShowbecomes false, but there's no cleanup if the component unmounts while the timer is active. This could cause a memory leak or attempt to update unmounted component state.Add cleanup in an
onUnmountedhook:+import { computed, onMounted, onUnmounted, ref, watch } from 'vue' // ... existing code ... +onUnmounted(() => { + clearAutoHide() +})src/components/helpcenter/HelpCenterMenuContent.vue (1)
524-529: Remove unusedonUpdatefunction to fix CI failure.The
onUpdatefunction is declared but never used, causing the TypeScript build to fail (TS6133). This blocks the CI pipeline.-const onUpdate = (_: ReleaseNote): void => { - openExternalLink( - buildDocsUrl('/installation/update_comfyui', { includeLocale: true }) - ) - emit('close') -}
♻️ Duplicate comments (1)
src/platform/updates/components/WhatsNewPopup.vue (1)
15-19: Verify HTML sanitization for v-html usage.Similar to the toast component, this uses
v-htmlfor rendering markdown content. The same sanitization verification applies.
🧹 Nitpick comments (6)
src/platform/updates/components/ReleaseNotificationToast.test.ts (2)
51-75: Consider extracting shared mock translations to reduce duplication.The translation map is duplicated in
vi.mock('vue-i18n')(lines 9-24) andmountComponent(lines 55-65). Extract to a shared constant for maintainability:+const mockTranslations: Record<string, string> = { + 'releaseToast.newVersionAvailable': 'New update is out!', + 'releaseToast.whatsNew': "See what's new", + 'releaseToast.skip': 'Skip', + 'releaseToast.update': 'Update', + 'releaseToast.description': + 'Check out the latest improvements and features in this update.' +} + vi.mock('vue-i18n', () => ({ useI18n: vi.fn(() => ({ locale: { value: 'en' }, - t: vi.fn((key: string) => { - const translations: Record<string, string> = { - 'releaseToast.newVersionAvailable': 'New update is out!', - ... - } - return translations[key] || key - }) + t: vi.fn((key: string) => mockTranslations[key] || key) })) }))
220-243: Timer test assertion may be flaky.The test expects
vi.getTimerCount()to be 0 after auto-hide triggers, but this depends on the component's internal implementation clearing the timer. If the component usesclearTimeouton unmount rather than after the callback executes, this assertion could fail.Consider also verifying the expected behavior (e.g., that a dismiss function was called) rather than relying solely on timer count:
// Fast-forward time to trigger auto-hide vi.advanceTimersByTime(8000) await wrapper.vm.$nextTick() - // Component should call dismissToast internally which hides it - // We can't test DOM visibility change because the component uses local state - // But we can verify the timer was set and would have triggered - expect(vi.getTimerCount()).toBe(0) // Timer should be cleared after auto-hide + // Verify the component's dismiss behavior was triggered + // The specific assertion depends on component implementationsrc/platform/updates/components/WhatsNewPopup.test.ts (1)
10-41: Same duplication pattern as ReleaseNotificationToast.test.ts.The translation mocks are duplicated in three places:
vi.mock('@/i18n'),vi.mock('vue-i18n'), andmountComponent. Consider extracting to a shared constant or even a shared test utility for the platform/updates components.Also applies to: 67-92
src/platform/updates/components/ReleaseNotificationToast.stories.ts (1)
8-67: Consider extracting shared mock data to a separate fixture file.The
mockReleasesarray is duplicated in bothReleaseNotificationToast.stories.tsandWhatsNewPopup.stories.ts. This could lead to maintenance issues if the mock data needs to be updated.Consider creating a shared fixtures file:
// src/platform/updates/components/__fixtures__/mockReleases.ts export const mockReleases: ReleaseNote[] = [/* ... */]Then import it in both story files.
src/components/helpcenter/HelpCenterMenuContent.vue (2)
34-43: Use Tailwind utilities instead of inline styles.As noted in a previous review, inline styles should be replaced with Tailwind utility classes for consistency.
<i v-if="menuItem.showExternalIcon" - class="icon-[lucide--external-link] text-primary" - style="width: 16px; height: 16px; margin-left: auto" + class="icon-[lucide--external-link] text-primary w-4 h-4 ml-auto" /> <i v-if="menuItem.key === 'more'" - class="pi pi-chevron-right" - style="margin-left: auto" + class="pi pi-chevron-right ml-auto" />
539-550: Extensive custom CSS in src/components.The coding guidelines indicate
src/components/**/*.{vue,css}should use "Tailwind CSS only for styling (no custom CSS)". While the CSS here is well-structured with semantic design tokens, it's quite extensive. Consider whether this could be migrated to Tailwind utilities in a future refactor.This is a larger refactoring effort and can be addressed in a follow-up PR if desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/components/helpcenter/HelpCenterMenuContent.vue (1)
34-43: Replace inline styles with Tailwind utility classes.The external link and chevron icons use inline styles that can be replaced with Tailwind classes for better consistency and maintainability.
Apply this diff:
<i v-if="menuItem.showExternalIcon" class="icon-[lucide--external-link] text-primary" - style="width: 16px; height: 16px; margin-left: auto" + class="ml-auto h-4 w-4" /> <i v-if="menuItem.key === 'more'" class="pi pi-chevron-right" - style="margin-left: auto" + class="ml-auto" />As per coding guidelines and past review feedback, prefer Tailwind utility classes over inline styles.
src/platform/updates/components/WhatsNewPopup.vue (1)
165-170: Consider limiting defineExpose to essential imperative operations.According to coding guidelines,
defineExposeshould be used "only for imperative operations (such as form.validate(), modal.open())". Whileshowandhideare appropriate for imperative modal control, exposinghandleCTAandclosePopupmay be unnecessary unless required for testing purposes.Based on learnings: Use defineExpose only for imperative operations (such as form.validate(), modal.open()).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/components/helpcenter/HelpCenterMenuContent.vue(13 hunks)src/locales/en/main.json(4 hunks)src/platform/updates/components/WhatsNewPopup.vue(7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/locales/en/main.json
🧰 Additional context used
📓 Path-based instructions (15)
**/*.vue
📄 CodeRabbit inference engine (.cursorrules)
**/*.vue: Use setup() function for component logic in Vue 3 Composition API
Utilize ref and reactive for reactive state in Vue 3
Implement computed properties with computed() function
Use watch and watchEffect for side effects in Vue 3
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection in Vue 3
Use Vue 3.5 style of default prop declaration with defineProps()
Organize Vue components in <script> <style> order
Use Tailwind CSS for styling Vue components
Implement responsive design with Tailwind CSS
Do not use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage). Use replacements: Select, Popover, DatePicker, ToggleSwitch, Drawer, AutoComplete, Tabs, Stepper, Message respectively
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components in Vue 3
Follow Vue 3 style guide and naming conventions
Never use deprecated PrimeVue components (Dropdown, OverlayPanel, Calendar, InputSwitch, Sidebar, Chips, TabMenu, Steps, InlineMessage)Never use
:class="[]"to merge class names - always useimport { cn } from '@/utils/tailwindUtil'for class merging in Vue templates
**/*.vue: Use TypeScript with Vue 3 Single File Components (.vuefiles)
Name Vue components in PascalCase (e.g.,MenuHamburger.vue)Files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vue🧠 Learnings (27)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-11-24T19:48:23.088Z Learning: Pull requests must include a clear description, linked issues in the format `- Fixes #123`, and screenshots/GIFs for UI changesLearnt 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 features📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/*.{ts,tsx,vue} : Sanitize HTML with DOMPurify to prevent XSS attacksApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Use Tailwind CSS for styling Vue componentsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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 Tailwind CSS only for styling (no custom CSS)Applied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`Applied to files:
src/components/helpcenter/HelpCenterMenuContent.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 vue-i18n for ALL UI stringsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panelsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3Applied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Use setup() function for component logic in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use defineExpose only for imperative operations (such as form.validate(), modal.open())Applied to files:
src/platform/updates/components/WhatsNewPopup.vue🪛 ESLint
src/components/helpcenter/HelpCenterMenuContent.vue
[error] 157-157: Unable to resolve path to module 'vue'.
(import-x/no-unresolved)
src/platform/updates/components/WhatsNewPopup.vue
[error] 55-55: Unable to resolve path to module 'primevue/button'.
(import-x/no-unresolved)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: lint-and-format
- GitHub Check: setup
- GitHub Check: test
- GitHub Check: collect
🔇 Additional comments (8)
src/components/helpcenter/HelpCenterMenuContent.vue (5)
289-308: Implementation looks good.The new feedback and help menu items are properly implemented with i18n support and appropriate icons. Both items execute the same
Comfy.ContactSupportcommand, which appears to be an intentional UX design choice to provide multiple entry points with different labeling.
184-184: Clean interface extension.The addition of the optional
showExternalIconproperty to theMenuIteminterface is well-implemented and consistently used throughout the component.
537-744: Excellent semantic token migration.The styles have been successfully migrated from hardcoded colors to semantic design tokens (
--interface-menu-surface,--interface-menu-stroke,--text-primary, etc.), which enables automatic light/dark theme support as intended in the PR objectives.Note: Line 607 retains the hardcoded
#ff3b30for the red notification dot, which is appropriate as it's a semantic alert color that should remain consistent across themes.As per coding guidelines, the component correctly uses tokens from style.css.
1-154: Well-structured template with proper accessibility.The template section demonstrates excellent practices:
- Semantic HTML elements (nav, article, section, button)
- Proper ARIA attributes for accessibility
- Consistent i18n usage via
$t()- Responsive hover and keyboard interactions
156-534: Clean Composition API implementation.The script section follows Vue 3 Composition API best practices:
- Proper use of composables and lifecycle hooks
- Well-typed TypeScript interfaces
- Clean separation of concerns with computed properties
- Proper event handling and state management
Note: The ESLint error about unresolved
vueimport (line 157) is a false positive—the component clearly functions correctly and this is a common tool configuration issue.src/platform/updates/components/WhatsNewPopup.vue (3)
55-55: ESLint import error is likely a false positive.The ESLint error "Unable to resolve path to module 'primevue/button'" is likely a false positive since PrimeVue is a core project dependency. If needed, verify that PrimeVue is properly installed and ESLint configuration includes proper resolution settings for PrimeVue imports.
185-436: Excellent use of semantic design tokens throughout!The styling consistently uses semantic design tokens from the theme system (e.g.,
var(--interface-menu-surface),var(--text-primary),var(--button-hover-surface)) with no hardcoded colors ordark:variants. This perfectly aligns with the PR objective to enable automatic light/dark theme support.As per coding guidelines: "Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme."
18-18: HTML sanitization is already properly implemented with DOMPurify.The
renderMarkdownToHtmlfunction insrc/utils/markdownRendererUtil.ts(lines 41-59) already sanitizes HTML using DOMPurify before returning. At line 56,DOMPurify.sanitize(html, {...})is called with appropriate allowed tags and attributes. The v-html directive in WhatsNewPopup.vue receives properly sanitized content, so no action is needed.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (4)
src/platform/updates/components/ReleaseNotificationToast.test.ts (2)
148-149: Avoidas anytype assertions.The coding guidelines prohibit using
as any. Since the component exposes methods viadefineExpose, consider typing the wrapper's VM properly.+// Define exposed methods type +interface ReleaseNotificationToastExposed { + handleSkip: () => void + handleLearnMore: () => void + handleUpdate: () => void +} + // In tests, use: -await (wrapper.vm as any).handleUpdate() +await (wrapper.vm as unknown as ReleaseNotificationToastExposed).handleUpdate()Alternatively, create a typed helper:
const getExposed = (w: VueWrapper) => w.vm as unknown as ReleaseNotificationToastExposed
186-203: Fragile mock re-import pattern.Using
vi.importMockafter the module is already mocked at the top of the file can lead to inconsistent behavior. The mock is already set up at lines 30-32.Consider using the existing mock directly:
- it('removes title from markdown content for toast display', async () => { - const mockMarkdownRendererModule = await vi.importMock( - '@/utils/markdownRendererUtil' - ) - const mockMarkdownRenderer = vi.mocked(mockMarkdownRendererModule) - .renderMarkdownToHtml as any - mockMarkdownRenderer.mockReturnValue('<div>Content without title</div>') + it('removes title from markdown content for toast display', async () => { + const { renderMarkdownToHtml } = await import('@/utils/markdownRendererUtil') + const mockRenderer = vi.mocked(renderMarkdownToHtml)Or clear and re-mock inline if custom return value is needed:
vi.mocked(renderMarkdownToHtml).mockReturnValue('<div>Content without title</div>')src/platform/updates/components/WhatsNewPopup.vue (2)
36-47: Consider using the Button component for consistency.The close button (lines 5-13) uses the design system Button component, but the footer action buttons use plain HTML
<button>elements. For design system consistency and maintainability, consider using the Button component throughout.Example refactor for the "Later" button:
-<button - class="action-secondary h-8 px-0 bg-transparent border-none text-sm font-normal rounded cursor-pointer" +<Button + class="action-secondary" + :label="$t('whatsNewPopup.later')" + severity="secondary" + text @click="closePopup" -\> - {{ $t('whatsNewPopup.later') }} -</button> +/>Then adjust the CSS for
.action-secondaryto work with the Button component rather than raw HTML button styling.
165-171: Consider reducing the exposed API surface.While
showandhideare appropriate imperative operations for modal control, exposinghandleCTAandclosePopupmay be unnecessary. TheclosePopupmethod is essentially a wrapper aroundhidewith additional logic, andhandleCTAis internal business logic.If tests require these methods, consider whether the tests should interact with the component through its public interface (e.g., clicking buttons) rather than calling internal methods directly.
Based on learnings: "Use defineExpose only for imperative operations (such as form.validate(), modal.open())".
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/platform/updates/components/ReleaseNotificationToast.test.ts(1 hunks)src/platform/updates/components/ReleaseNotificationToast.vue(6 hunks)src/platform/updates/components/WhatsNewPopup.vue(7 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{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/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
src/platform/updates/components/ReleaseNotificationToast.test.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/platform/updates/components/ReleaseNotificationToast.test.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/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/platform/updates/components/ReleaseNotificationToast.test.ts
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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:
src/platform/updates/components/ReleaseNotificationToast.test.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/platform/updates/components/ReleaseNotificationToast.test.tssrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/ReleaseNotificationToast.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/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.vue🧠 Learnings (17)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-11-24T19:48:23.088Z Learning: Pull requests must include a clear description, linked issues in the format `- Fixes #123`, and screenshots/GIFs for UI changes📚 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/platform/updates/components/ReleaseNotificationToast.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} : Always prefer vitest mock functions over writing verbose manual mocksApplied to files:
src/platform/updates/components/ReleaseNotificationToast.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} : Mock external dependencies in testsApplied to files:
src/platform/updates/components/ReleaseNotificationToast.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} : Follow existing test patterns in the codebaseApplied to files:
src/platform/updates/components/ReleaseNotificationToast.test.ts📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursor/rules/unit-test.mdc:0-0 Timestamp: 2025-11-24T19:48:09.318Z Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this projectApplied to files:
src/platform/updates/components/ReleaseNotificationToast.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/platform/updates/components/ReleaseNotificationToast.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: Check tests-ui/README.md for test guidelinesApplied to files:
src/platform/updates/components/ReleaseNotificationToast.test.ts📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursor/rules/unit-test.mdc:0-0 Timestamp: 2025-11-24T19:48:09.318Z Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possibleApplied to files:
src/platform/updates/components/ReleaseNotificationToast.test.ts📚 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: Use Vitest (with happy-dom) for unit and component tests, and Playwright for E2E testsApplied to files:
src/platform/updates/components/ReleaseNotificationToast.test.ts📚 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} : Test across multiple viewportsApplied to files:
src/platform/updates/components/ReleaseNotificationToast.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use defineExpose only for imperative operations (such as form.validate(), modal.open())Applied to files:
src/platform/updates/components/WhatsNewPopup.vue🧬 Code graph analysis (1)
src/platform/updates/components/ReleaseNotificationToast.test.ts (1)
src/platform/updates/common/releaseService.ts (1)
ReleaseNote(10-10)🪛 ESLint
src/platform/updates/components/ReleaseNotificationToast.test.ts
[error] 1-1: Resolve error: EACCES: permission denied, open '/sgJrlmRHQy'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at processBodyStatement (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:9:31)
at Program (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/namespace.js:100:21)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2292:15)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/namespace)
[error] 1-1: Resolve error: EACCES: permission denied, open '/FdBphMzGyV'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at importType (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/import-type.js:126:63)
at checkImportForRelativePackage (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:15:38)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:59:40
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2292:15)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-relative-packages)
[error] 1-1: Resolve error: EACCES: permission denied, open '/yDzIyaTNLn'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-unresolved.js:31:34)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2292:15)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/ZGZlDfswZk'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/no-useless-path-segments.js:58:34
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2292:15)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/no-useless-path-segments)
[error] 1-1: Resolve error: EACCES: permission denied, open '/VnVBoGlnHP'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/[email protected]/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/[email protected][email protected]_@typescript-eslin_da4796079dab5a32abf73f9910d12370/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at ExportMap.get (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/utils/export-map.js:88:22)
at checkDefault (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint[email protected]_eslint@[email protected]__d4b6b79e6f12f59d34d55ebbf27dc73f/node_modules/eslint-plugin-import-x/lib/rules/default.js:22:39)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2189:43)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2292:15)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1179:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/[email protected][email protected]/node_modules/eslint/lib/eslint/eslint-helpers.js:1320:10)(import-x/default)
[error] 2-2: Unable to resolve path to module '@vue/test-utils'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module 'vitest'.
(import-x/no-unresolved)
[error] 6-6: Unable to resolve path to module './ReleaseNotificationToast.vue'.
(import-x/no-unresolved)
src/platform/updates/components/ReleaseNotificationToast.vue
[error] 72-72: Unable to resolve path to module '@/utils/markdownRendererUtil'.
(import-x/no-unresolved)
src/platform/updates/components/WhatsNewPopup.vue
[error] 55-55: Unable to resolve path to module 'primevue/button'.
(import-x/no-unresolved)
🔇 Additional comments (4)
src/platform/updates/components/ReleaseNotificationToast.test.ts (2)
84-112: Good test coverage for basic rendering.Tests properly verify component visibility, icon presence, and version display.
228-276: Comprehensive timer behavior tests.Good coverage for auto-hide and manual dismissal timer cleanup using fake timers.
src/platform/updates/components/ReleaseNotificationToast.vue (2)
3-63: Well-structured component layout with semantic Tailwind classes.The card-like design with proper spacing, flex layout, and responsive overflow handling is clean. Good use of semantic color tokens (
bg-base-background,text-muted-foreground, etc.) aligning with the design system migration goals.
195-201: Good practice exposing methods for testing.Using
defineExposeto expose handlers enables direct testing of component behavior.
- Add proper semantic design tokens (corner-radius, blue surface) - Convert hardcoded colors to theme-aware tokens in toast and popup - Implement Figma-compliant styling with image support - Add comprehensive component tests for behavioral validation - Update translation strings for improved UI copy
- Remove temporary mock data from WhatsNewPopup component - Fix i18n mocking issues in both test suites - Fix TypeScript errors with vi.mocked calls - Update failing tests to use direct method calls instead of DOM events - Remove duplicate/outdated test file - All 22 tests now passing
…se notifications - Replace hardcoded colors with semantic design tokens (bg-primary-background-hover, bg-secondary-background) - Add proper height constraints and scrolling for long content in toast - Remove image support from toast component (design requirement) - Fix empty content handling - components don't show when no meaningful content - Add comprehensive Storybook stories for both WhatsNewPopup and ReleaseNotificationToast - Fix TypeScript errors by updating mock data with required ReleaseNote properties - Clean up redundant CSS and remove development console.log statements - Ensure proper markdown rendering with bullet points using dash syntax
…ling - Update test selectors to match new Tailwind-based template structure - Fix component behavior to show fallback content instead of disappearing - Add proper mock setup for tests requiring shouldShow state - Update button and link selectors for new component structure - Fix TypeScript error with undefined button reference Components now gracefully handle empty content by showing meaningful fallback messages instead of returning null.
Add DOMPurify sanitization to HTML content rendered via v-html in both: - ReleaseNotificationToast.vue: Sanitize all HTML output including fallback content - WhatsNewPopup.vue: Sanitize fallback and error HTML content Markdown content is already sanitized by renderMarkdownToHtml utility.
- Use t('releaseToast.description') instead of hardcoded English fallback text
- Fix rel attribute to use space-separated values (noopener noreferrer)
02bbbef to
11775ff
Compare
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/platform/updates/components/WhatsNewPopup.vue (1)
55-56: Fix incorrect Button import path.This import was flagged in a previous review. The project uses a custom design system Button component, not PrimeVue's Button directly.
Apply this diff:
-import Button from 'primevue/button' +import Button from '@/design-system/components/Button.vue'
🧹 Nitpick comments (7)
src/platform/updates/components/WhatsNewPopup.test.ts (2)
11-41: Consider consolidating duplicate translation mocks.The same translation dictionary is defined three times (lines 11-25, 27-41, and 73-82). Consider extracting to a shared constant to reduce duplication and maintenance burden.
+const mockTranslations: Record<string, string> = { + 'g.close': 'Close', + 'whatsNewPopup.later': 'Later', + 'whatsNewPopup.update': 'Update', + 'whatsNewPopup.learnMore': 'Learn More', + 'whatsNewPopup.noReleaseNotes': 'No release notes available' +} + vi.mock('@/i18n', () => ({ t: (key: string, params?: Record<string, string>) => { - const translations: Record<string, string> = { - 'g.close': 'Close', - 'whatsNewPopup.later': 'Later', - 'whatsNewPopup.update': 'Update', - 'whatsNewPopup.learnMore': 'Learn More', - 'whatsNewPopup.noReleaseNotes': 'No release notes available' - } return params - ? `${translations[key] || key}:${JSON.stringify(params)}` - : translations[key] || key + ? `${mockTranslations[key] || key}:${JSON.stringify(params)}` + : mockTranslations[key] || key }, d: (date: Date) => date.toLocaleDateString() }))
196-200: Avoidas anytype assertion.Per coding guidelines, avoid
as anytype assertions. Consider using proper typing for the mocked module.- it('processes markdown content correctly', async () => { - const mockMarkdownRendererModule = await vi.importMock( - '@/utils/markdownRendererUtil' - ) - const mockMarkdownRenderer = vi.mocked(mockMarkdownRendererModule) - .renderMarkdownToHtml as any - mockMarkdownRenderer.mockReturnValue('<h1>Processed Content</h1>') + it('processes markdown content correctly', async () => { + const mockMarkdownRendererModule = await vi.importMock< + typeof import('@/utils/markdownRendererUtil') + >('@/utils/markdownRendererUtil') + const mockMarkdownRenderer = vi.mocked( + mockMarkdownRendererModule.renderMarkdownToHtml + ) + mockMarkdownRenderer.mockReturnValue('<h1>Processed Content</h1>')src/platform/updates/components/ReleaseNotificationToast.stories.ts (2)
112-118: Use semantic color token instead of hardcoded gray.Per coding guidelines, avoid hardcoded colors in templates. Replace
bg-gray-900with a semantic token from the design system.return { template: ` - <div class="min-h-screen flex items-center justify-center bg-gray-900 p-8"> + <div class="min-h-screen flex items-center justify-center bg-base-background p-8"> <story /> </div> ` }
95-102: Object.defineProperty approach for computed property mocking is fragile.While this works for Storybook, using
Object.definePropertyto override Pinia getters can cause issues if the store is reactive. Consider using a more robust approach.- // Force the computed properties to return the values we want - Object.defineProperty(releaseStore, 'recentRelease', { - value: context.args.releaseData, - writable: true - }) - Object.defineProperty(releaseStore, 'shouldShowToast', { - value: true, - writable: true - }) + // Patch store state directly for Storybook + releaseStore.$patch({ + releases: [context.args.releaseData] + }) + // Mock getters via spyOn if needed, or rely on computed derivationNote: This depends on how the store is structured. If
recentReleaseandshouldShowToastare getters derived fromreleases, patchingreleasesshould suffice.src/components/helpcenter/HelpCenterMenuContent.vue (2)
34-43: Use Tailwind utility classes instead of inline styles.Per coding guidelines, use Tailwind CSS for styling. Replace inline styles with utility classes.
<i v-if="menuItem.showExternalIcon" - class="icon-[lucide--external-link] text-primary" - style="width: 16px; height: 16px; margin-left: auto" + class="icon-[lucide--external-link] text-primary w-4 h-4 ml-auto" /> <i v-if="menuItem.key === 'more'" - class="pi pi-chevron-right" - style="margin-left: auto" + class="pi pi-chevron-right ml-auto" />
466-490: Relative time strings are hardcoded in English.The
formatReleaseDatefunction returns hardcoded English strings like"1d ago","2w ago","now". Per coding guidelines, use vue-i18n for ALL user-facing strings.Consider using a library like
@vueuse/core'suseTimeAgoor adding i18n keys for relative time formatting.src/platform/updates/components/WhatsNewPopup.vue (1)
36-47: Consider using design system Button for footer actions.The close button uses the
Buttoncomponent, but the footer action buttons use native<button>elements with custom styles. For consistency and easier maintenance, consider using the design system Button component with appropriate severity props (secondary,primary).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
browser_tests/tests/releaseNotifications.spec.ts(7 hunks)packages/design-system/src/css/style.css(4 hunks)src/components/helpcenter/HelpCenterMenuContent.vue(14 hunks)src/locales/en/main.json(4 hunks)src/platform/updates/components/ReleaseNotificationToast.stories.ts(1 hunks)src/platform/updates/components/ReleaseNotificationToast.test.ts(1 hunks)src/platform/updates/components/ReleaseNotificationToast.vue(4 hunks)src/platform/updates/components/WhatsNewPopup.stories.ts(1 hunks)src/platform/updates/components/WhatsNewPopup.test.ts(1 hunks)src/platform/updates/components/WhatsNewPopup.vue(7 hunks)tests-ui/tests/components/helpcenter/WhatsNewPopup.test.ts(0 hunks)
💤 Files with no reviewable changes (1)
- tests-ui/tests/components/helpcenter/WhatsNewPopup.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/platform/updates/components/ReleaseNotificationToast.test.ts
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{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/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuebrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tsbrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.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/platform/updates/components/ReleaseNotificationToast.stories.tsbrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.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/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuebrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.ts
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuebrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuebrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.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:
src/platform/updates/components/ReleaseNotificationToast.stories.tsbrowser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/platform/updates/components/ReleaseNotificationToast.stories.tssrc/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.stories.tssrc/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.vue
**/*.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vuebrowser_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 viewportsFiles:
browser_tests/tests/releaseNotifications.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/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.test.tsbrowser_tests/**/*.{test,spec}.ts
📄 CodeRabbit inference engine (AGENTS.md)
Playwright E2E tests can use optional tags like
@mobileand@2xwhich are respected by the Playwright configurationFiles:
browser_tests/tests/releaseNotifications.spec.ts🧠 Learnings (46)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-11-24T19:48:23.088Z Learning: Pull requests must include a clear description, linked issues in the format `- Fixes #123`, and screenshots/GIFs for UI changesLearnt 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 features📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/*.{ts,tsx,vue} : Sanitize HTML with DOMPurify to prevent XSS attacksApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Use Tailwind CSS for styling Vue componentsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-12-01T23:45:28.610Z
Learnt from: DrJKL Repo: Comfy-Org/ComfyUI_frontend PR: 7084 File: src/renderer/extensions/vueNodes/components/SlotConnectionDot.vue:23-26 Timestamp: 2025-12-01T23:45:28.610Z Learning: Tailwind CSS supports arbitrary fractional width utilities beyond the common predefined ones. For example, `w-5/2` is valid syntax that represents 250% width (5÷2 = 2.5 = 250%). This applies to all utility variants including pseudo-elements like `after:w-5/2`.Applied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-12-01T23:42:30.894Z
Learnt from: DrJKL Repo: Comfy-Org/ComfyUI_frontend PR: 7084 File: src/renderer/extensions/vueNodes/components/SlotConnectionDot.vue:23-26 Timestamp: 2025-12-01T23:42:30.894Z Learning: In the ComfyUI frontend codebase, Tailwind CSS is configured with Preflight enabled (default), which automatically provides `content: ''` for pseudo-elements when using `after:` or `before:` variants - no need to explicitly add `after:content-['']`.Applied to files:
src/components/helpcenter/HelpCenterMenuContent.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 Tailwind CSS only for styling (no custom CSS)Applied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`Applied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.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 vue-i18n for ALL UI stringsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.{vue,ts,tsx} : Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.jsonApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.vue📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-24T19:47:02.860Z Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/ReleaseNotificationToast.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/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursorrules:0-0 Timestamp: 2025-11-24T19:46:52.279Z Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3Applied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panelsApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.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/helpcenter/HelpCenterMenuContent.vuesrc/platform/updates/components/WhatsNewPopup.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/helpcenter/HelpCenterMenuContent.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition APIApplied to files:
src/components/helpcenter/HelpCenterMenuContent.vue📚 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/releaseNotifications.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/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.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} : Follow existing test patterns in the codebaseApplied to files:
browser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.test.ts📚 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} : Follow naming conventions for browser testsApplied to files:
browser_tests/tests/releaseNotifications.spec.ts📚 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 browser_tests/**/*.{test,spec}.ts : Playwright E2E tests can use optional tags like `mobile` and `2x` which are respected by the Playwright configurationApplied to files:
browser_tests/tests/releaseNotifications.spec.ts📚 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} : Test user workflows in browser testsApplied to files:
browser_tests/tests/releaseNotifications.spec.ts📚 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: Create browser tests as appropriate after code changesApplied to files:
browser_tests/tests/releaseNotifications.spec.ts📚 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} : Check assets/ directory for test data when writing testsApplied to files:
browser_tests/tests/releaseNotifications.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} : Use existing test utilities rather than writing custom utilitiesApplied to files:
browser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.test.ts📚 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} : Test across multiple viewportsApplied to files:
browser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.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: Check tests-ui/README.md for test guidelinesApplied to files:
browser_tests/tests/releaseNotifications.spec.tssrc/platform/updates/components/WhatsNewPopup.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,css} : Use the correct tokens from style.css in the design system packageApplied to files:
packages/design-system/src/css/style.csssrc/platform/updates/components/WhatsNewPopup.vue📚 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/platform/updates/components/WhatsNewPopup.test.ts📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: .cursor/rules/unit-test.mdc:0-0 Timestamp: 2025-11-24T19:48:09.318Z Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possibleApplied to files:
src/platform/updates/components/WhatsNewPopup.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} : Always prefer vitest mock functions over writing verbose manual mocksApplied to files:
src/platform/updates/components/WhatsNewPopup.test.ts📚 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: Use Vitest (with happy-dom) for unit and component tests, and Playwright for E2E testsApplied to files:
src/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.test.tssrc/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.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/platform/updates/components/WhatsNewPopup.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Use defineExpose only for imperative operations (such as form.validate(), modal.open())Applied to files:
src/platform/updates/components/WhatsNewPopup.vue🧬 Code graph analysis (2)
src/platform/updates/components/WhatsNewPopup.stories.ts (3)
src/platform/updates/common/releaseService.ts (1)
ReleaseNote(10-10)src/platform/updates/common/releaseStore.ts (1)
useReleaseStore(16-291)src/platform/updates/components/ReleaseNotificationToast.stories.ts (5)
Default(126-130)WithImage(132-136)MajorRelease(138-142)LongContent(144-166)EmptyContent(168-179)src/platform/updates/components/WhatsNewPopup.test.ts (1)
src/platform/updates/common/releaseService.ts (1)
ReleaseNote(10-10)🔇 Additional comments (21)
browser_tests/tests/releaseNotifications.spec.ts (1)
53-53: Good migration to data-testid selectors.Switching from CSS class selectors (
.whats-new-section) togetByTestId('whats-new-section')is a best practice for E2E tests. This makes tests more resilient to styling refactors and aligns with Playwright's recommended selector strategy.Also applies to: 82-82, 128-128, 178-178, 266-266, 314-314, 365-365
src/platform/updates/components/WhatsNewPopup.test.ts (1)
64-92: Good test setup with proper mocking patterns.The test structure follows Vitest best practices with clear mock setup,
beforeEachcleanup, and a reusablemountComponenthelper. The PrimeVue and icon stubbing approach is appropriate for unit testing Vue components.packages/design-system/src/css/style.css (2)
188-189: New menu tokens are well-structured and consistent.The
--interface-menu-surfaceand--interface-menu-stroketokens follow the established naming conventions and provide appropriate values for both light and dark themes. The color choices (white/smoke-600 for light, charcoal-800/ash-800 for dark) maintain good contrast ratios.Also applies to: 310-311
427-428: Token aliases properly configured in @theme inline.The color token aliases correctly reference the base tokens, enabling Tailwind utility class usage (e.g.,
bg-interface-menu-surface).src/locales/en/main.json (3)
749-752: Localization keys properly updated for Help Center menu.The new
feedbackand renamedhelpkeys align with the component changes inHelpCenterMenuContent.vue.
766-770: Release toast strings updated with user-friendly copy.The updated strings ("New update is out!", "See what's new") are more conversational and appropriate for a toast notification. The new
descriptionkey provides fallback content when release notes are empty.
2251-2255: New help section keys added for accessibility.The
help.recentReleasesandhelp.helpCenterMenukeys properly support the aria-label attributes in the components, addressing the i18n requirements for accessibility text.src/platform/updates/components/ReleaseNotificationToast.stories.ts (1)
8-67: Good mock data coverage for different release scenarios.The mock releases cover essential edge cases: standard release, release with image, major release, and the stories include LongContent and EmptyContent variants. This provides comprehensive visual testing coverage.
src/platform/updates/components/ReleaseNotificationToast.vue (4)
106-136: Good XSS protection and i18n usage.The
formattedContentcomputed properly sanitizes all HTML output with DOMPurify, including the fallback content. The i18nt()function is correctly used for user-facing strings. This addresses the previous review concerns.
218-219: CSS selector has unnecessary comma before newline.The selector
.sidebar-left,followed by.sidebar-left.small-sidebaron line 219 is correct, but the formatting could be cleaner.
3-63: Well-structured card layout with proper semantic tokens.The template uses semantic color tokens (
bg-base-background,border-border-default,text-base-foreground,text-muted-foreground) consistently. The layout follows a clear hierarchy with proper accessibility considerations.
199-205: Good use of defineExpose for testing.Exposing
handleSkip,handleLearnMore, andhandleUpdateenables unit tests to trigger these handlers directly, which is appropriate for component testing.src/components/helpcenter/HelpCenterMenuContent.vue (3)
295-315: Feedback and Help buttons have identical actions.Both menu items call
commandStore.execute('Comfy.ContactSupport')and track the same event'help_feedback'. Is this intentional, or should they have distinct functionality?
3-5: Past review issues addressed - aria-labels now use i18n.The aria-labels for "Help Center Menu" and "Recent releases" now properly use
$t('help.helpCenterMenu')and$t('help.recentReleases')respectively.Also applies to: 99-102
573-584: Good use of new semantic design tokens.The component correctly uses the new
--interface-menu-surfaceand--interface-menu-stroketokens for consistent theming, enabling automatic light/dark mode support.src/platform/updates/components/WhatsNewPopup.vue (3)
97-133: LGTM on content sanitization and error handling.The
formattedContentcomputed correctly uses DOMPurify for HTML sanitization with proper fallback handling for edge cases (empty content, parse errors). The comment at line 123 correctly notes thatrenderMarkdownToHtmlalready sanitizes.
152-158: LGTM on CTA handler implementation.The
handleCTAcorrectly opens the update documentation URL and then closes the popup to mark the release as seen.
187-197: Good migration to semantic design tokens.The CSS correctly uses semantic tokens like
--interface-menu-surfaceand--interface-menu-strokeinstead of hardcoded colors, enabling proper light/dark theme support as intended by this PR.src/platform/updates/components/WhatsNewPopup.stories.ts (3)
86-117: LGTM on Storybook decorator setup.The decorator correctly initializes the store with mock data for each story. Using
Object.definePropertyto override computed properties is a pragmatic approach for Storybook visualization, even though it breaks reactivity—this is acceptable since stories only need static display.
123-211: Good story coverage for content scenarios.The stories cover key rendering scenarios: default content, image-first content, major releases, long content scrolling, minimal content, and empty content (testing the "No release notes available" fallback). This aligns well with the component's
formattedContentlogic.
8-67: Mock data looks good with realistic content.The mock releases provide representative content for testing different UI states. Note that the Unsplash image URLs rely on external resources; if network isolation is needed for Storybook, consider using local placeholder images.
Summary
Migrated help center and release notification components from hardcoded colors to semantic design tokens for automatic light/dark theme support.
Changes
--interface-menu-surfaceand--interface-menu-stroketokens to style.css for consistent menu theming┆Issue is synchronized with this Notion page by Unito