-
Notifications
You must be signed in to change notification settings - Fork 433
refactor: rename isSubscribed for better expressiveness and avoid initializing cloud modules on local
#7127
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: 12/06/2025, 11:39:35 PM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🎭 Playwright Test Results⏰ Completed at: 12/06/2025, 11:49:20 PM UTC 📈 Summary
📊 Test Reports by Browser
🎉 Click on the links above to view detailed test results for each browser configuration. |
📝 WalkthroughWalkthroughRenamed subscription flag Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as "UI Component\n(CreditsPanel / Run Button)"
participant Sub as "useSubscription\n(composable)"
participant Dialog as "dialogService"
participant Cmd as "Core Command\n/ Queue"
User->>UI: trigger purchase/run action
UI->>UI: check isCloud
alt isCloud == true
UI->>Sub: dynamic import & get isSubscriptionRequirementMet
Sub-->>UI: isSubscriptionRequirementMet (computed)
alt isSubscriptionRequirementMet == true
UI->>Dialog: call showTopUpCreditsDialog()
Dialog-->>UI: dialog completes
UI->>Cmd: proceed with action (queue/run)
Cmd-->>UI: result
else isSubscriptionRequirementMet == false
UI-->>User: show subscription/subscribe dialog
end
else isCloud == false
UI->>Dialog: call showTopUpCreditsDialog() (no subscription gating)
Dialog-->>UI: dialog completes
UI->>Cmd: proceed with action (queue/run)
Cmd-->>UI: result
end
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (10)src/**/*.{vue,ts}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/**/*.ts📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/**/{services,composables}/**/*.{ts,tsx}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/*.{ts,tsx,vue}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/{composables,components}/**/*.{ts,tsx,vue}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/*.{vue,ts,tsx}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
src/**/{components,composables}/**/*.{ts,tsx,vue}📄 CodeRabbit inference engine (src/CLAUDE.md)
Files:
**/*.ts📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,vue}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/composables/**/use*.ts📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-11-24T19:47:34.324ZApplied to files:
🧬 Code graph analysis (1)src/platform/cloud/subscription/composables/useSubscription.ts (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🔇 Additional comments (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/composables/useCoreCommands.ts (1)
66-67: Consider gatinguseSubscription()to avoid initializing cloud logic on local buildsThe new guards using
isSubscribedOrIsNotCloud.valueandshowSubscriptionDialog()look correct and preserve the prior behavior with the renamed flag.To better match the PR objective of not initializing cloud modules on local, you could avoid calling
useSubscription()at module scope and instead gate it, for example:export function useCoreCommands(): ComfyCommand[] { // ... const subscription = isCloud /* from '@/platform/distribution/types' */ ? useSubscription() : null const isSubscribedOrIsNotCloud = subscription?.isSubscribedOrIsNotCloud const showSubscriptionDialog = subscription?.showSubscriptionDialog // use these in the queue commands, with a null check if needed }This would prevent the subscription composable (and its network activity) from being set up when running non‑cloud builds, while keeping the command guards unchanged for cloud.
Also applies to: 468-488, 491-512, 514-557
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue(2 hunks)src/components/dialog/content/setting/CreditsPanel.vue(3 hunks)src/components/topbar/CurrentUserPopover.test.ts(1 hunks)src/components/topbar/CurrentUserPopover.vue(3 hunks)src/composables/auth/useFirebaseAuthActions.ts(1 hunks)src/composables/useCoreCommands.ts(4 hunks)src/platform/cloud/subscription/components/SubscribeButton.vue(2 hunks)src/platform/cloud/subscription/components/SubscriptionPanel.vue(5 hunks)src/platform/cloud/subscription/composables/useSubscription.ts(2 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)src/scripts/app.ts(1 hunks)src/services/dialogService.ts(1 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 hunks)tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (23)
**/*.{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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vue
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscribeButton.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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscribeButton.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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/services/dialogService.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.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:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.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/cloud/subscription/components/SubscriptionPanel.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.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/cloud/subscription/components/SubscriptionPanel.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.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/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/services/dialogService.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.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/cloud/subscription/components/SubscriptionPanel.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.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/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/services/dialogService.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/services/dialogService.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.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/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safetyFiles:
src/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.tssrc/services/dialogService.tssrc/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directlyFiles:
src/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/services/dialogService.ts**/composables/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables in the format
useXyz.tsFiles:
src/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.tstests-ui/tests/composables/useCoreCommands.test.tssrc/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/topbar/CurrentUserPopover.test.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.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/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.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/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vue🧠 Learnings (9)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaksApplied to files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.test.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscribeButton.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/actionbar/ComfyRunButton/CloudRunButtonWrapper.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} : Write tests for new featuresApplied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/topbar/CurrentUserPopover.vue📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patternsApplied to files:
src/platform/cloud/subscription/components/SubscribeButton.vue🧬 Code graph analysis (6)
src/composables/useCoreCommands.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (2)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
CloudSubscriptionStatusResponse(23-28)src/platform/telemetry/types.ts (1)
TelemetryProvider(259-328)src/composables/auth/useFirebaseAuthActions.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/scripts/app.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/services/dialogService.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)🪛 ESLint
src/components/dialog/content/setting/CreditsPanel.vue
[error] 128-128: Unable to resolve path to module '@/platform/distribution/types'.
(import-x/no-unresolved)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: setup
- GitHub Check: test
- GitHub Check: collect
- GitHub Check: lint-and-format
🔇 Additional comments (19)
src/components/topbar/CurrentUserPopover.test.ts (1)
82-88: Subscription mock rename and shape look correctMocking
isSubscribedOrIsNotCloudas{ value: true }matches the composable’s ref-like API and aligns this test with the new subscription flag.src/services/dialogService.ts (1)
380-399: Cloud‑gated top‑up dialog matches new subscription flagThe new
isCloudguard plusisSubscribedOrIsNotCloudcheck correctly prevents the top‑up dialog (anduseSubscription()usage) on local builds and when cloud users aren’t eligible.tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
27-28: Watcher tests correctly updated toisSubscribedOrIsNotCloudUsing a computed based on
isActiveand passingisSubscribedOrIsNotCloudinto the watcher keeps the tests aligned with the new API and preserves the intended behavior.Also applies to: 77-83, 107-113, 129-135, 155-160
src/composables/auth/useFirebaseAuthActions.ts (1)
84-89: Cloud‑only subscription check inpurchaseCreditsis consistentWrapping the
useSubscription()access in anisCloudcheck and switching toisSubscribedOrIsNotCloud.valuecleanly aligns this flow with the new flag while avoiding cloud subscription setup on local runs.src/components/dialog/content/setting/CreditsPanel.vue (1)
18-23: Credits top‑up button now correctly respects new subscription flagThe
isSubscribedOrIsNotCloudcomputed cleanly gates the purchase button for cloud users while avoidinguseSubscription()calls on local builds; the template condition matches the new flag.Also applies to: 128-152
src/platform/cloud/subscription/composables/useSubscription.ts (1)
34-38: Renamed subscription flag is consistently wired through the composable
isSubscribedOrIsNotCloudis correctly computed, passed intouseSubscriptionCancellationWatcher, and exposed on the returned API, keeping behavior intact while giving downstream callers a clearer predicate.Also applies to: 111-118, 224-241
src/scripts/app.ts (1)
679-690: Logic correctly short-circuits to avoid cloud module initialization in non-cloud builds.The branching ensures
useSubscription()is only called whenisCloudis true, aligning with the PR's goal to prevent cloud-specific module initialization in local environments. The redundancy withshowTopUpCreditsDialog's internal check is intentional defensive layering.tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
95-127: Test updates correctly reflect the API rename.The test cases properly validate that
isSubscribedOrIsNotCloudbehaves as expected:truewhen the subscription is active,falsewhen inactive. The mockedisCloud: truecontext at line 56 ensures these tests run in the cloud environment where this distinction matters.tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (2)
9-17: Mock data correctly updated to use the renamed property.The mock structure aligns with the updated
useSubscriptionAPI, ensuring tests accurately simulate both subscribed and non-subscribed states viaisSubscribedOrIsNotCloud.
121-151: Test cases properly exercise both subscription states.Each test correctly mutates
mockSubscriptionData.isSubscribedOrIsNotCloudbefore mounting to validate the expected UI behavior for active, inactive, and cancelled subscription scenarios.src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue (1)
4-17: Component correctly updated to use the renamed subscription predicate.The template key, destructuring, and computed logic all consistently reference
isSubscribedOrIsNotCloud, maintaining the intended behavior: renderComfyQueueButtonwhen the user is subscribed or not in cloud mode, otherwise renderSubscribeToRunButton.src/platform/cloud/subscription/components/SubscribeButton.vue (2)
54-54: Destructuring updated to use the renamed property.
79-83: Polling logic correctly uses the renamed predicate.When the subscription checkout completes successfully,
isSubscribedOrIsNotCloud.valuebecomestruein cloud mode, stopping the poll and emitting thesubscribedevent. The logic is semantically unchanged.src/components/topbar/CurrentUserPopover.vue (2)
26-59: LGTM! Clear and consistent rename.The rename from
isActiveSubscriptiontoisSubscribedOrIsNotCloudsignificantly improves code clarity by explicitly conveying that the UI shows credits/top-up functionality either when the user is subscribed OR when running locally (not in cloud mode). The conditional logic for toggling between the credits UI and the subscribe button is now more self-documenting.
128-128: Consistent destructuring update.The script section correctly reflects the renamed property, maintaining consistency between the template and script logic.
src/platform/cloud/subscription/components/SubscriptionPanel.vue (2)
7-72: LGTM! Comprehensive and consistent rename across subscription UI.The rename improves clarity across multiple conditional blocks that control the subscription panel's UI state. The new name
isSubscribedOrIsNotCloudmakes it explicit that subscription features are available both for cloud subscribers and local installations.
322-330: Consistent destructuring with template usage.The script correctly destructures
isSubscribedOrIsNotCloudfromuseSubscription(), maintaining perfect alignment with all template conditional checks throughout the component.src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (2)
13-27: LGTM! Type definition and parameter consistently updated.The rename propagates correctly through the type definition and function signature, maintaining type safety and consistency with the calling code.
69-101: Proper cancellation detection logic with correct cleanup.The conditional check at line 76 correctly uses the renamed
isSubscribedOrIsNotCloudto detect when a subscription becomes inactive. The watcher properly cleans up resources viaonScopeDispose(lines 121-123), preventing memory leaks as emphasized in the project learnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
tests-ui/tests/composables/useCoreCommands.test.ts (1)
101-106: Consider aligning mocked subscription flag shape with real composableRenaming the mocked field to
isSubscribedOrIsNotCloudkeeps these tests in sync with the new API. If the realuseSubscriptionnow exposes this as aRef<boolean>, you might optionally switch the mock toisSubscribedOrIsNotCloud: ref(true)to better mirror production usage and catch future.valueaccess changes, though the current truthy function works for these tests.src/components/topbar/CurrentUserPopover.vue (1)
128-128: Consider adding cloud-aware initialization.While the renaming is correct, this component could benefit from the conditional initialization pattern used in
CreditsPanel.vue(line 148) to prevent cloud module initialization on local environments:const subscription = isCloud ? useSubscription() : null const isSubscribedOrIsNotCloud = computed(() => { if (!isCloud) return true return subscription?.isSubscribedOrIsNotCloud.value ?? false })This would align with the PR's goal to avoid initializing cloud modules on local environments.
Apply this pattern if the component can be loaded in non-cloud environments:
+import { isCloud } from '@/platform/distribution/types' + const { userDisplayName, userEmail, userPhotoUrl, handleSignOut } = useCurrentUser() const authActions = useFirebaseAuthActions() const dialogService = useDialogService() -const { isSubscribedOrIsNotCloud, fetchStatus } = useSubscription() +const subscription = isCloud ? useSubscription() : null +const isSubscribedOrIsNotCloud = computed(() => { + if (!isCloud) return true + return subscription?.isSubscribedOrIsNotCloud.value ?? false +}) +const fetchStatus = subscription?.fetchStatus ?? (() => Promise.resolve())
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue(2 hunks)src/components/dialog/content/setting/CreditsPanel.vue(3 hunks)src/components/topbar/CurrentUserPopover.test.ts(1 hunks)src/components/topbar/CurrentUserPopover.vue(3 hunks)src/composables/auth/useFirebaseAuthActions.ts(1 hunks)src/composables/useCoreCommands.ts(4 hunks)src/platform/cloud/subscription/components/SubscribeButton.vue(2 hunks)src/platform/cloud/subscription/components/SubscriptionPanel.vue(5 hunks)src/platform/cloud/subscription/composables/useSubscription.ts(2 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)src/scripts/app.ts(1 hunks)src/services/dialogService.ts(1 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 hunks)tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (23)
**/*.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/cloud/subscription/components/SubscribeButton.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.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/platform/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.ts**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (.cursorrules)
Implement proper error handling in components and services
**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in.prettierrc
Organize imports by sorting and grouping by plugin, and runpnpm formatbefore committingFiles:
src/platform/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventionsFiles:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.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/platform/cloud/subscription/components/SubscribeButton.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.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/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.ts**/*.{vue,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
dark:ordark-theme:Tailwind variants - instead use semantic values fromstyle.csstheme, e.g.bg-node-component-surfaceFiles:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.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/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebaseFiles:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/composables/useCoreCommands.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.jsonFiles:
src/platform/cloud/subscription/components/SubscribeButton.vuesrc/composables/useCoreCommands.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/scripts/app.ts**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
Use TypeScript for type safety
**/*.{ts,tsx}: Never useanytype - use proper TypeScript types
Never useas anytype assertions - fix the underlying type issueFiles:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/scripts/app.ts**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
UsedefaultsByInstallVersionproperty for gradual feature rollout based on version in settings configurationFiles:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/scripts/app.tstests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocksFiles:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.tssrc/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safetyFiles:
src/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/scripts/app.tssrc/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directlyFiles:
src/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.ts**/composables/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables in the format
useXyz.tsFiles:
src/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/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/dialog/content/setting/CreditsPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.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/dialog/content/setting/CreditsPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.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/dialog/content/setting/CreditsPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue🧠 Learnings (8)
📓 Common learnings
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:34.324Z Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaksApplied to files:
src/platform/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/composables/auth/useFirebaseAuthActions.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: tests-ui/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:48:03.270Z Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new featuresApplied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR Repo: Comfy-Org/ComfyUI_frontend PR: 0 File: src/components/CLAUDE.md:0-0 Timestamp: 2025-11-24T19:47:45.616Z Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with PopoverApplied to files:
src/components/topbar/CurrentUserPopover.vue🧬 Code graph analysis (6)
tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/composables/useCoreCommands.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/services/dialogService.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (2)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
CloudSubscriptionStatusResponse(23-28)src/platform/telemetry/types.ts (1)
TelemetryProvider(259-328)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
src/extensions/core/load3d/Load3d.ts (1)
isActive(383-391)src/composables/auth/useFirebaseAuthActions.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)🪛 ESLint
src/components/dialog/content/setting/CreditsPanel.vue
[error] 128-128: Unable to resolve path to module '@/platform/distribution/types'.
(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). (1)
- GitHub Check: merge-reports
🔇 Additional comments (13)
src/components/topbar/CurrentUserPopover.test.ts (1)
82-88: Subscription mock rename is consistent with composable APIMocking
useSubscriptionwithisSubscribedOrIsNotCloud: { value: true }aligns with the new flag name and expected ref-like shape; no behavior change in the tests.src/services/dialogService.ts (1)
380-399: Cloud-only subscription guard inshowTopUpCreditsDialogThe early
if (isCloud) { const { isSubscribedOrIsNotCloud } = useSubscription(); if (!isSubscribedOrIsNotCloud.value) return }cleanly avoids touching the subscription composable on local builds and prevents showing the top-up dialog for unsubscribed cloud users.Please just confirm that a silent no-op in the unsubscribed cloud case is intentional and that all callers already gate the top‑up entry points on subscription state, so users never click a button that does nothing.
src/platform/cloud/subscription/components/SubscribeButton.vue (1)
54-83: Polling now usesisSubscribedOrIsNotCloudconsistentlySwitching the destructured flag and the polling condition to
isSubscribedOrIsNotCloud.valuekeeps the subscribe flow semantics intact while aligning with the new API; interval and loading-state cleanup remain correct.src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue (1)
1-18: Run button wrapper correctly switched toisSubscribedOrIsNotCloudThe computed and template key now both depend on
isSubscribedOrIsNotCloudinstead of the old flag, preserving the queue/subscribe toggle behavior with the updated API.tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (1)
8-17: Tests now trackisSubscribedOrIsNotCloudfor subscription stateRenaming the mock field and all subscription-state expectations to
isSubscribedOrIsNotCloudkeeps the active/inactive and renewal/expiry test scenarios aligned with the updated composable API, with no change to asserted behavior.Also applies to: 121-152
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
23-32: Cancellation watcher tests aligned withisSubscribedOrIsNotCloudUsing a local
computedisSubscribedOrIsNotCloudand passing it intouseSubscriptionCancellationWatcherin all test setups preserves the prior behavior while matching the new option name expected by the composable.Also applies to: 77-83, 107-113, 129-135, 155-160
src/composables/auth/useFirebaseAuthActions.ts (1)
84-89: Cloud-only subscription guard added topurchaseCreditsThe new
if (isCloud) { const { isSubscribedOrIsNotCloud } = useSubscription(); if (!isSubscribedOrIsNotCloud.value) return }guard cleanly avoids initializing subscription logic on local and prevents initiating a credit purchase when the cloud user isn’t subscribed.Please double‑check that callers never invoke
purchaseCreditsfor unsubscribed cloud users (or, if they can, that a silent early return without feedback is the desired UX).tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
95-127: LGTM! Test updates align with API rename.The test correctly reflects the renamed subscription state property. The test logic and assertions remain unchanged, maintaining coverage.
src/components/dialog/content/setting/CreditsPanel.vue (1)
148-152: Excellent cloud-aware initialization pattern.This is the correct approach to prevent cloud module initialization on local environments:
- Conditionally call
useSubscription()only whenisCloudis true- The computed property correctly returns
truefor non-cloud (no subscription required)- For cloud environments, it delegates to the subscription state
This pattern should be used consistently across the codebase where subscription status is needed.
src/scripts/app.ts (1)
679-690: Cloud-aware error handling is correct.The logic properly short-circuits for non-cloud environments before initializing the subscription module. For cloud environments, the subscription is only checked when a payment error occurs.
Note: Since
useSubscription()is a shared composable (viacreateSharedComposable), calling it multiple times returns the same instance, making this pattern safe.src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
15-27: LGTM! Parameter renaming is consistent.The cancellation watcher correctly receives and uses the renamed subscription state property. No logic changes, maintaining existing behavior.
Also applies to: 76-76
src/platform/cloud/subscription/components/SubscriptionPanel.vue (1)
7-11: LGTM! Consistent renaming throughout the component.All references to the subscription state have been correctly updated to use
isSubscribedOrIsNotCloud. Since this component is in the cloud-specific path, conditional initialization is not needed here.Also applies to: 30-47, 50-72, 199-212, 323-330
src/platform/cloud/subscription/composables/useSubscription.ts (1)
34-38: LGTM! Public API renamed consistently.The core subscription composable correctly:
- Computes
isSubscribedOrIsNotCloudbased on cloud status and subscription state- Passes the renamed property to the cancellation watcher
- Exports the renamed property in the returned object
The logic correctly returns
truefor non-cloud environments, treating them as "effectively subscribed" for feature access purposes.Also applies to: 114-114, 226-226
DrJKL
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love compound logic in names like this.
Is there something more essential about the gating that we can describe without exposing what specifically goes into it right now?
Maybe subscriptionIneligible?
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 3.19 MB (baseline 3.2 MB) • 🟢 -8.94 kBMain entry bundles and manifests
Status: 4 added / 3 removed Graph Workspace — 976 kB (baseline 976 kB) • 🔴 +38 BGraph 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) • 🔴 +48 BConfiguration panels, inspectors, and settings screens
Status: 6 added / 6 removed UI Components — 186 kB (baseline 177 kB) • 🔴 +9.51 kBReusable component library chunks
Status: 9 added / 9 removed Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 3 added / 3 removed Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 1 added / 1 removed Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Status: 5 added / 5 removed Other — 3.81 MB (baseline 3.81 MB) • 🔴 +60 BBundles that do not match a named category
Status: 23 added / 23 removed |
Why's that? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/composables/useCoreCommands.ts(7 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 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:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursorrules)
Use es-toolkit for utility functions
Files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.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:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.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:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for variable and setting names in TypeScript/Vue files
Files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,vue}: Useconst settingStore = useSettingStore()andsettingStore.get('Comfy.SomeSetting')to retrieve settings in TypeScript/Vue files
Useawait settingStore.set('Comfy.SomeSetting', newValue)to update settings in TypeScript/Vue files
Check server capabilities usingapi.serverSupportsFeature('feature_name')before using enhanced features
Useapi.getServerFeature('config_name', defaultValue)to retrieve server feature configurationEnforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates
Files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
UsedefaultsByInstallVersionproperty for gradual feature rollout based on version in settings configuration
Files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks
Files:
tests-ui/tests/composables/useCoreCommands.test.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:
tests-ui/tests/composables/useCoreCommands.test.ts
**/composables/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables in the format
useXyz.ts
Files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.ts
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/composables/useCoreCommands.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/composables/useCoreCommands.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/composables/useCoreCommands.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/composables/useCoreCommands.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/composables/useCoreCommands.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/composables/useCoreCommands.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/composables/useCoreCommands.ts
🧠 Learnings (15)
📚 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 tests
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.tssrc/composables/useCoreCommands.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 mocks
Applied to files:
tests-ui/tests/composables/useCoreCommands.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 possible
Applied to files:
tests-ui/tests/composables/useCoreCommands.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 : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T19:46:52.279Z
Learning: Applies to **/*.vue : Utilize ref and reactive for reactive state in Vue 3
Applied to files:
src/composables/useCoreCommands.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 : Implement computed() for derived state in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T19:46:52.279Z
Learning: Applies to **/*.vue : Implement computed properties with computed() function
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:46:52.279Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T19:46:52.279Z
Learning: Applies to **/*.{vue,ts,tsx} : Leverage VueUse functions for performance-enhancing utilities
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.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 : Extract complex conditionals to computed properties
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:14.779Z
Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue files
Applied to files:
src/composables/useCoreCommands.ts
🧬 Code graph analysis (1)
src/composables/useCoreCommands.ts (3)
tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts (1)
isCloud(34-36)tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useComboWidget.test.ts (1)
isCloud(44-46)src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
⏰ 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 (3)
tests-ui/tests/composables/useCoreCommands.test.ts (1)
101-106: LGTM! Mock structure correctly implements ref-like API.The mock now properly returns
isSubscribedOrIsNotCloudas a ref-like object with{ value: true }, which matches how the production code accessessubscriptionState.valuein the command functions.src/composables/useCoreCommands.ts (2)
94-97: Excellent: Cloud-aware initialization successfully prevents module loading on local.The conditional pattern
isCloud ? useSubscription() : nullensures the cloud subscription module is only initialized in cloud environments, directly achieving the PR's stated goal. The fallback todefaultSubscriptionState(value: true) andnoopcorrectly bypasses subscription checks on local builds.
489-490: Consistent subscription gating across all queue commands.All three queue commands (QueuePrompt, QueuePromptFront, QueueSelectedOutputNodes) now uniformly check
subscriptionState.valueand invokesubscriptionDialog()when gated. This correctly enforces subscription requirements in cloud environments while allowing unrestricted execution locally.Also applies to: 512-513, 534-535
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (16)
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue(2 hunks)src/components/dialog/content/setting/CreditsPanel.vue(3 hunks)src/components/topbar/CurrentUserPopover.test.ts(1 hunks)src/components/topbar/CurrentUserPopover.vue(3 hunks)src/composables/auth/useFirebaseAuthActions.ts(1 hunks)src/composables/useCoreCommands.ts(7 hunks)src/platform/cloud/subscription/components/SubscribeButton.vue(2 hunks)src/platform/cloud/subscription/components/SubscriptionPanel.vue(5 hunks)src/platform/cloud/subscription/composables/useSubscription.ts(4 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)src/scripts/app.ts(1 hunks)src/services/dialogService.ts(1 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 hunks)tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.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/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/scripts/app.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vue
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript exclusively; no new JavaScript code
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/scripts/app.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.ts
**/*.{ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see.prettierrc)
Use single quotes for strings (see.prettierrc)
No trailing semicolons (see.prettierrc)
Maximum line width of 80 characters (see.prettierrc)
Sort and group imports by plugin (runpnpm formatbefore committing)
Never useanytype; use proper TypeScript types instead
Never useas anytype assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/scripts/app.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuetests-ui/tests/platform/cloud/subscription/useSubscription.test.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.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/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vue
**/composables/**/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables with
useXyz.tspattern
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/composables/auth/useFirebaseAuthActions.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.ts
**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.test.ts
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3 SFCs with Composition API only (use<script setup lang="ts">, not Options API)
Avoid using<style>blocks; use Tailwind 4 for all styling
UsedefinePropswith TypeScript style default declaration; do not usewithDefaultsor runtime props declaration
PreferuseModelover separately defining a prop and emit
Usecomputedinstead of arefandwatchif possible
Avoid usingrefif a prop would accomplish the design goals; avoid usingcomputedif arefor prop directly would work
Do not import Vue macros unnecessarily
Never use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Never use:class="[]"to merge class names; always usecn()from@/utils/tailwindUtil(e.g.,<div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />)
Leverage VueUse functions for performance-enhancing styles
Avoid new usage of PrimeVue components
Use Vue 3 Teleport component when needed
Use Vue 3 Suspense for async components
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
**/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue components in PascalCase (e.g.,
MenuHamburger.vue)
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
Write unit and component tests with Vitest using happy-dom
Files:
src/components/topbar/CurrentUserPopover.test.ts
🧠 Learnings (19)
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/components/topbar/CurrentUserPopover.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuetests-ui/tests/platform/cloud/subscription/useSubscription.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 Popover
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties
Applied to files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.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 : Implement computed() for derived state in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use `computed` instead of a `ref` and `watch` if possible
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid using `ref` if a prop would accomplish the design goals; avoid using `computed` if a `ref` or prop directly would work
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing change detector tests that just assert default values
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.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 tests
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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 codebase
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.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 possible
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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 : Prefer emit/event-name for state changes over other communication patterns
Applied to files:
src/platform/cloud/subscription/components/SubscribeButton.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} : Always prefer vitest mock functions over writing verbose manual mocks
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
🧬 Code graph analysis (6)
src/services/dialogService.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
CloudSubscriptionStatusResponse(23-28)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/scripts/app.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/composables/useCoreCommands.ts (3)
tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts (1)
isCloud(34-36)tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useComboWidget.test.ts (1)
isCloud(44-46)src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: setup
- GitHub Check: test
- GitHub Check: collect
- GitHub Check: lint-and-format
🔇 Additional comments (17)
src/components/topbar/CurrentUserPopover.test.ts (1)
85-85: LGTM! Mock correctly updated.The mock shape properly reflects the ref-like structure of
isSubscriptionRequirementMetfrom the renamed subscription API.tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (2)
10-10: LGTM! Mock data updated consistently.The subscription requirement property is correctly renamed throughout the mock data and test assertions.
123-151: LGTM! Test assertions updated correctly.All test cases properly reference
isSubscriptionRequirementMetinstead of the oldisActiveSubscriptionproperty, maintaining test coverage while aligning with the renamed API.src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue (1)
14-17: LGTM! Subscription state properly renamed.The component correctly destructures and accesses
isSubscriptionRequirementMet.valueto determine which button to render.tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (2)
27-27: LGTM! Test variable renamed consistently.The computed ref is correctly renamed to
isSubscriptionRequirementMet, matching the updated composable API.
77-83: LGTM! Watcher options updated correctly.All
initWatchercalls properly passisSubscriptionRequirementMetinstead of the old parameter name, maintaining test coverage.tests-ui/tests/composables/useCoreCommands.test.ts (1)
103-103: LGTM! Mock shape corrected.The mock now correctly provides
isSubscriptionRequirementMetas a ref-like object with avalueproperty, matching the real composable API and addressing the previous review feedback.src/platform/cloud/subscription/components/SubscribeButton.vue (2)
54-55: LGTM! Subscription state properly renamed.The destructuring correctly uses
isSubscriptionRequirementMetfrom the updated composable API.
80-80: LGTM! Polling completion check updated correctly.The condition properly references
isSubscriptionRequirementMet.valueto determine when to stop polling and emit the subscribed event.tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (2)
95-110: Tests correctly updated to useisSubscriptionRequirementMet(active case).Renaming to
isSubscriptionRequirementMetand asserting.value === truefor an active subscription matches the new composable API and semantics. No further changes needed here.
112-127: Tests correctly updated to useisSubscriptionRequirementMet(inactive case).The inactive subscription test now destructures
isSubscriptionRequirementMetand asserts.value === false, which is consistent with the new computed behavior undersubscription_required: true.src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
13-19: Rename toisSubscriptionRequirementMetis consistent and behavior‑preserving.The watcher options, destructuring, and cancellation check now consistently use
isSubscriptionRequirementMet.value. Given the caller only enables the watcher when cloud subscription is required, this keeps the previous behavior while aligning with the new API name.Also applies to: 21-27, 69-77
src/scripts/app.ts (1)
679-690: Cloud‑aware top‑up dialog gating looks correct.The new logic avoids initializing
useSubscription()on non‑cloud builds and, in cloud, only shows the Top Up Credits dialog whenisSubscriptionRequirementMet.valueis true, which aligns with the intended “only top‑up for active subscribers” behavior. This also keeps the Payment Required flow side‑effect‑free on local.src/components/dialog/content/setting/CreditsPanel.vue (1)
18-22: CreditsPanel now correctly gates on cloud subscription without initializing it on local.Using
subscription = isCloud ? useSubscription() : nullplus the computedisSubscriptionRequirementMet(true for non‑cloud, delegated to the composable in cloud) cleanly meets the PR goal: no cloud subscription initialization on local, while still hiding the purchase button when the subscription requirement isn’t met in cloud.Also applies to: 128-152
src/platform/cloud/subscription/components/SubscriptionPanel.vue (1)
6-10: SubscriptionPanel correctly migrated toisSubscriptionRequirementMet.All title, detail, and button conditions now depend on
isSubscriptionRequirementMet, and the script setup destructuring matches the updateduseSubscriptionAPI. The subscribed vs unsubscribed UI flows remain intact under the new flag name.Also applies to: 30-51, 189-212, 322-330
src/composables/useCoreCommands.ts (1)
1-2: Cloud‑aware subscription gating for core commands is well factored.The
defaultSubscriptionState/noophelpers plussubscription = isCloud ? useSubscription() : nullandsubscriptionState/subscriptionDialoggive you:
- No subscription initialization or gating in non‑cloud builds.
- Centralized, readable gating for all queue commands in cloud (
QueuePrompt,QueuePromptFront,QueueSelectedOutputNodes).Using
computed(() => true)for the default state is also a nice, type‑safe improvement over the previous manual object.Also applies to: 52-52, 69-71, 92-96, 486-490, 509-513, 531-535
src/platform/cloud/subscription/composables/useSubscription.ts (1)
34-38:useSubscription’s newisSubscriptionRequirementMetflag cleanly encodes environment‑aware gating.The computed correctly short‑circuits to
truewhen not in cloud or whensubscription_requiredis disabled, and otherwise reflectssubscriptionStatus.is_active. Wiring this intouseSubscriptionCancellationWatcher,requireActiveSubscription, and the returned state object keeps downstream consumers consistent with the renamed, more expressive flag without changing cloud behavior where subscription is enforced.Also applies to: 108-115, 125-131, 224-231
9614a5d to
490e7ea
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (1)
8-17: AlignisSubscriptionRequirementMetmock with ref/computed APIIn this suite,
mockSubscriptionData.isSubscriptionRequirementMetis a bare boolean, but elsewhereisSubscriptionRequirementMetis treated as a ref/computed (.valueis read in components likeSubscribeButton.vueand related composables). Using a plain boolean here risks the tests drifting from the real API ifSubscriptionPanel.vueever starts reading.value.To keep the mock shape consistent and future-proof the tests, consider making it ref-like and updating the mutations:
const mockSubscriptionData = { - isSubscriptionRequirementMet: false, + isSubscriptionRequirementMet: { value: false }, isCancelled: false, formattedRenewalDate: '2024-12-31', formattedEndDate: '2024-12-31', formattedMonthlyPrice: '$9.99', manageSubscription: vi.fn(), handleInvoiceHistory: vi.fn() } @@ describe('subscription state functionality', () => { it('shows correct UI for active subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = true @@ it('shows correct UI for inactive subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = false + mockSubscriptionData.isSubscriptionRequirementMet.value = false @@ it('shows renewal date for active non-cancelled subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = true @@ it('shows expiry date for cancelled subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = trueThis keeps the tests closely aligned with the production composable while preserving the existing scenarios.
Also applies to: 123-123, 130-130, 140-140, 147-147
src/scripts/app.ts (1)
46-47: Avoid duplicating subscription gating and staticuseSubscriptionimport inapp.tsThe new
execution_errorbranch correctly gates the Top Up dialog onisSubscriptionRequirementMetin cloud, butshowTopUpCreditsDialogalready encapsulates that same cloud-aware check (including a lazyimportofuseSubscription). Doing the check again here:
- Duplicates logic and checks the same flag twice in cloud builds.
- Forces a static
import { useSubscription }inapp.ts, which works against the goal of keeping cloud-only modules out of local builds where possible.You can simplify and better support tree-shaking by delegating to the dialog service and removing the direct
useSubscriptiondependency:-import { useDialogService } from '@/services/dialogService' -import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription' +import { useDialogService } from '@/services/dialogService' @@ - } else if ( + } else if ( detail.exception_message?.includes( 'Payment Required: Please add credits to your account to use this node.' ) ) { - if (!isCloud) { - useDialogService().showTopUpCreditsDialog({ - isInsufficientCredits: true - }) - } else { - const { isSubscriptionRequirementMet } = useSubscription() - if (isSubscriptionRequirementMet.value) { - useDialogService().showTopUpCreditsDialog({ - isInsufficientCredits: true - }) - } - } + useDialogService().showTopUpCreditsDialog({ + isInsufficientCredits: true + }) } else {Since
showTopUpCreditsDialogalready handles theisCloud+isSubscriptionRequirementMetgating internally, this preserves behavior while keeping the cloud-specific composable out ofapp.ts.Also applies to: 666-691
src/services/dialogService.ts (1)
379-401: Update all non-awaited call sites to handle asyncshowTopUpCreditsDialogThe function is now
async, but three of four call sites do notawaitit:
- src/scripts/app.ts:680, 686: Called in error handler without
await. The early return on!isSubscriptionRequirementMetwill not prevent the dialog call.- src/components/topbar/CurrentUserPopover.vue:151: Called in synchronous
handleTopUp()withoutawait.- src/components/dialog/content/setting/CreditsPanel.vue:176: Called in synchronous
handlePurchaseCreditsClick()withoutawait.Only src/platform/cloud/subscription/composables/useSubscriptionActions.ts:40 properly awaits the function in an async context.
The cloud-gating logic (early return when
isCloud && !isSubscriptionRequirementMet) will not work as intended for non-awaited call sites. Either addawaitto each call site (and make the containing functionasync), or remove the early return and handle the gating at the call site.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (17)
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue(2 hunks)src/components/dialog/content/setting/CreditsPanel.vue(3 hunks)src/components/topbar/CurrentUserPopover.test.ts(1 hunks)src/components/topbar/CurrentUserPopover.vue(4 hunks)src/composables/auth/useFirebaseAuthActions.ts(1 hunks)src/composables/useCoreCommands.ts(7 hunks)src/platform/cloud/subscription/components/SubscribeButton.vue(2 hunks)src/platform/cloud/subscription/components/SubscriptionPanel.vue(5 hunks)src/platform/cloud/subscription/composables/useSubscription.ts(4 hunks)src/platform/cloud/subscription/composables/useSubscriptionActions.ts(1 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)src/scripts/app.ts(1 hunks)src/services/dialogService.ts(1 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 hunks)tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
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/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.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/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript exclusively; no new JavaScript code
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/composables/useCoreCommands.tssrc/services/dialogService.tstests-ui/tests/composables/useCoreCommands.test.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
**/*.{ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see.prettierrc)
Use single quotes for strings (see.prettierrc)
No trailing semicolons (see.prettierrc)
Maximum line width of 80 characters (see.prettierrc)
Sort and group imports by plugin (runpnpm formatbefore committing)
Never useanytype; use proper TypeScript types instead
Never useas anytype assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/scripts/app.ts
**/composables/**/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables with
useXyz.tspattern
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tstests-ui/tests/composables/useCoreCommands.test.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.test.ts
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3 SFCs with Composition API only (use<script setup lang="ts">, not Options API)
Avoid using<style>blocks; use Tailwind 4 for all styling
UsedefinePropswith TypeScript style default declaration; do not usewithDefaultsor runtime props declaration
PreferuseModelover separately defining a prop and emit
Usecomputedinstead of arefandwatchif possible
Avoid usingrefif a prop would accomplish the design goals; avoid usingcomputedif arefor prop directly would work
Do not import Vue macros unnecessarily
Never use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Never use:class="[]"to merge class names; always usecn()from@/utils/tailwindUtil(e.g.,<div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />)
Leverage VueUse functions for performance-enhancing styles
Avoid new usage of PrimeVue components
Use Vue 3 Teleport component when needed
Use Vue 3 Suspense for async components
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
**/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue components in PascalCase (e.g.,
MenuHamburger.vue)
Files:
src/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.ts
**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests
Files:
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/components/topbar/CurrentUserPopover.test.ts
src/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
Write unit and component tests with Vitest using happy-dom
Files:
src/components/topbar/CurrentUserPopover.test.ts
🧠 Learnings (29)
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/components/topbar/CurrentUserPopover.vuetests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tssrc/composables/useCoreCommands.tssrc/services/dialogService.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/composables/useCoreCommands.test.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/platform/cloud/subscription/composables/useSubscription.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 Popover
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Applied to files:
src/components/topbar/CurrentUserPopover.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 API
Applied to files:
src/components/topbar/CurrentUserPopover.vuesrc/composables/useCoreCommands.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 Steps component with Stepper without panels
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API
Applied to files:
src/components/topbar/CurrentUserPopover.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} : Write tests for new features
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing change detector tests that just assert default values
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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 tests
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tssrc/components/topbar/CurrentUserPopover.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 possible
Applied to files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.tssrc/components/topbar/CurrentUserPopover.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 : Extract complex conditionals to computed properties
Applied to files:
src/components/dialog/content/setting/CreditsPanel.vuesrc/composables/useCoreCommands.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use `computed` instead of a `ref` and `watch` if possible
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid using `ref` if a prop would accomplish the design goals; avoid using `computed` if a `ref` or prop directly would work
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.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 : Prefer emit/event-name for state changes over other communication patterns
Applied to files:
src/platform/cloud/subscription/components/SubscribeButton.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} : Always prefer vitest mock functions over writing verbose manual mocks
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{services,composables}/**/*.{ts,tsx} : Use `api.fileURL()` for static file access instead of constructing URLs directly
Applied to files:
src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Implement proper error handling
Applied to files:
src/composables/auth/useFirebaseAuthActions.ts
🧬 Code graph analysis (5)
src/composables/useCoreCommands.ts (3)
tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts (1)
isCloud(34-36)tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useComboWidget.test.ts (1)
isCloud(44-46)src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/services/dialogService.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/scripts/app.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: test
- GitHub Check: setup
- GitHub Check: lint-and-format
🔇 Additional comments (19)
src/components/topbar/CurrentUserPopover.test.ts (1)
81-88: Ref-likeisSubscriptionRequirementMetmock matches composable APIMocking
isSubscriptionRequirementMetas{ value: true }aligns with a ref/computed-style API and avoids.valueaccess issues in the component under test. This is consistent with the other updated tests.tests-ui/tests/composables/useCoreCommands.test.ts (1)
101-106: Correct ref-like mock forisSubscriptionRequirementMetReturning
isSubscriptionRequirementMetas{ value: true }fixes the earlier mismatch with the real composable (which is read via.value) and keeps the guard logic inuseCoreCommandsbehaving as in production.tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
27-27: ComputedisSubscriptionRequirementMetcorrectly mirrors active stateDeriving
isSubscriptionRequirementMetviacomputed(() => isActive.value)and passing it intouseSubscriptionCancellationWatcherkeeps the tests aligned with the new API while preserving behavior of all scenarios (cancellation detection, focus-triggered checks, max attempts, and guard failures).Also applies to: 77-83, 107-113, 129-135, 155-160
src/platform/cloud/subscription/composables/useSubscriptionActions.ts (1)
39-41: AsynchandleAddApiCreditscorrectly mirrors async dialog behaviorMaking
handleAddApiCreditsasyncand awaitingdialogService.showTopUpCreditsDialog()matches the dialog’s new async, gated behavior and keeps the action’s completion semantics clear. Call sites using it as a click handler continue to work as before.src/platform/cloud/subscription/components/SubscribeButton.vue (1)
54-55: Correct use ofisSubscriptionRequirementMetref in subscribe pollingDestructuring
isSubscriptionRequirementMetfromuseSubscription()and checkingisSubscriptionRequirementMet.valueinside the polling loop preserves the previous behavior while aligning with the new flag name and ref-like API.Also applies to: 80-84
src/composables/auth/useFirebaseAuthActions.ts (1)
84-90: LGTM! Dynamic import pattern correctly enables tree-shaking for local builds.The
useSubscriptioncomposable is now lazily imported within theisCloudguard, ensuring cloud modules won't be bundled in local environments. The subscription requirement check properly gates the purchase flow.src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
13-23: LGTM! Consistent rename of subscription state property.The
isActiveSubscription→isSubscriptionRequirementMetrename is correctly applied in the type definition, parameter destructuring, and all usages. The cleanup logic viaonScopeDisposeproperly prevents memory leaks.src/components/topbar/CurrentUserPopover.vue (2)
128-131: LGTM! Cloud-aware subscription initialization with proper fallbacks.The conditional
useSubscription()call with fallbacks for non-cloud environments is correctly implemented. TheisSubscriptionRequirementMetdefaults totrueandfetchStatusto a no-op when not in cloud context.Note: Same tree-shaking consideration as
CreditsPanel.vueapplies here regarding the static import. If tree-shaking is critical, dynamic import could be used, but this may be acceptable if the popover is primarily used in cloud environments.
26-29: Template bindings correctly updated to use renamed property.The conditional rendering based on
isSubscriptionRequirementMetproperly gates the credits section and plan settings button, showing the subscribe button when the requirement is not met.src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue (1)
12-17: No action needed—this component is properly guarded byisCloud.CloudRunButtonWrapper is only imported when
isCloud && window.__CONFIG__?.subscription_requiredis true (insrc/components/actionbar/ComfyRunButton/index.ts), so the directuseSubscription()call is safe and will not initialize cloud modules in local environments.src/components/dialog/content/setting/CreditsPanel.vue (1)
127-152: Code pattern is correct and tree-shakeable; no changes needed.The current implementation properly supports tree-shaking. The
isCloudconstant is a build-time value (DISTRIBUTION === 'cloud'), enabling the bundler to eliminate the unused branch in local builds. The pattern of static import with conditional call (isCloud ? useSubscription() : null) is consistent with the codebase and allows dead-code elimination at build time. Additionally, CreditsPanel itself is already dynamically imported inuseSettingUI.ts, making it a lazy-loaded component that won't be included in local builds.tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
95-127: LGTM!Test descriptions and assertions are correctly updated to reference
isSubscriptionRequirementMet. The test logic properly validates both active and inactive subscription scenarios.src/composables/useCoreCommands.ts (2)
69-96: Cloud-aware subscription initialization pattern looks correct.The implementation properly defers
useSubscription()initialization to cloud environments only, achieving the PR's goal of avoiding cloud module initialization on local. The fallback pattern withcomputed(() => true)andnoopensures non-cloud environments bypass subscription gating seamlessly.
487-490: LGTM!Subscription gating correctly checks
subscriptionState.valueand shows the dialog with early return when the requirement is not met. This pattern is consistently applied across all queue commands.src/platform/cloud/subscription/components/SubscriptionPanel.vue (2)
7-10: LGTM!Template correctly uses the renamed
isSubscriptionRequirementMetproperty for conditional rendering of subscription-related UI elements.
322-330: LGTM!Script setup correctly destructures
isSubscriptionRequirementMetfromuseSubscription(), maintaining alignment with the composable's updated API.src/platform/cloud/subscription/composables/useSubscription.ts (3)
34-38: LGTM!The renamed
isSubscriptionRequirementMetcomputed property accurately reflects the semantic: the requirement is met when either (1) not running on cloud, (2) subscription is not required by config, or (3) subscription is active. This is more expressive than the previousisActiveSubscriptionname.
111-118: LGTM!Cancellation watcher correctly receives the renamed
isSubscriptionRequirementMetcomputed property.
224-241: LGTM!The return object correctly exposes the renamed
isSubscriptionRequirementMetproperty. All consumers in the PR have been updated to consume this renamed API.
| import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore' | ||
| import { useSubgraphStore } from '@/stores/subgraphStore' | ||
| import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore' | ||
| import { isCloud } from '@/platform/distribution/types' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Import placement breaks alphabetical grouping.
The isCloud import is inserted between unrelated imports, breaking the alphabetical ordering within the import group. This should be placed with other platform imports or sorted according to the project's import conventions.
-import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
-import { isCloud } from '@/platform/distribution/types'
-import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
+import { isCloud } from '@/platform/distribution/types'
+import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
+import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'Note: Run pnpm format to auto-sort imports per the coding guidelines.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/composables/useCoreCommands.ts around line 52, the import "isCloud" was
inserted between unrelated imports and breaks the file's alphabetical/grouping
convention; move the import into the existing platform/distribution import block
(or next to other platform imports) and reorder imports alphabetically per
project conventions, then run "pnpm format" to auto-sort and apply formatting.
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 (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
112-120:legacyIsActiveSubscriptionargument mirrors an unused option in the watcherYou’re passing
legacyIsActiveSubscription: isActiveSubscriptionhere, butuseSubscriptionCancellationWatchernever reads that option—onlyisSubscriptionRequirementMet. This mirrors the dead field in the watcher options and doesn’t currently change behavior.Recommend either removing this property from the call or updating the watcher to actually consume it, depending on whether you truly need a legacy path.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/platform/cloud/subscription/composables/useSubscription.ts(4 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
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/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.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/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript exclusively; no new JavaScript code
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
**/*.{ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see.prettierrc)
Use single quotes for strings (see.prettierrc)
No trailing semicolons (see.prettierrc)
Maximum line width of 80 characters (see.prettierrc)
Sort and group imports by plugin (runpnpm formatbefore committing)
Never useanytype; use proper TypeScript types instead
Never useas anytype assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
**/composables/**/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables with
useXyz.tspattern
Files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
🧠 Learnings (1)
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.tssrc/platform/cloud/subscription/composables/useSubscription.ts
🧬 Code graph analysis (1)
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (2)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
CloudSubscriptionStatusResponse(23-28)src/platform/telemetry/types.ts (1)
TelemetryProvider(259-328)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: deploy-and-comment
- GitHub Check: setup
- GitHub Check: collect
- GitHub Check: lint-and-format
- GitHub Check: test
🔇 Additional comments (3)
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
70-102: Switch toisSubscriptionRequirementMetin cancellation check looks correctUsing
!isSubscriptionRequirementMet.valuehere matches the new “subscription required & active” semantics, and the watcher still correctly stops the timer and detaches thefocuslistener viastopCancellationWatcher, avoiding leaks. Based on learnings, this aligns with the subscription cleanup guidance.src/platform/cloud/subscription/composables/useSubscription.ts (2)
34-40:isSubscriptionRequirementMetcomputed + aliasing viaisActiveSubscriptionlook soundThe computed correctly short-circuits to
truefor non‑cloud or non‑subscription‑required configs and falls back tosubscriptionStatus.value?.is_activeotherwise. Reusing the same computed instance forisActiveSubscriptionis a clean way to keep older call sites working without duplicating state.
226-231: Exposing bothisSubscriptionRequirementMetandisActiveSubscriptionis a reasonable transition pathReturning the new flag plus the alias (with an inline deprecation note) gives callers time to migrate without breaking changes, while ensuring both names reflect the same underlying state.
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
Show resolved
Hide resolved
4b58fd3 to
1ebdab9
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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (1)
10-17: AlignisSubscriptionRequirementMetmock with ref-like APIElsewhere
useSubscriptionexposesisSubscriptionRequirementMetas a ref/computed, and other tests mock it as{ value: boolean }. Here it’s a plain boolean and reassigned directly, which can diverge from production behavior ifSubscriptionPanel.vueever reads.value.To keep mocks consistent and future‑proof, consider updating the shape:
const mockSubscriptionData = { - isSubscriptionRequirementMet: false, + isSubscriptionRequirementMet: { value: false }, isCancelled: false, formattedRenewalDate: '2024-12-31', formattedEndDate: '2024-12-31', formattedMonthlyPrice: '$9.99', manageSubscription: vi.fn(), handleInvoiceHistory: vi.fn() }And in the tests:
it('shows correct UI for active subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = true const wrapper = createWrapper() expect(wrapper.text()).toContain('Manage Subscription') expect(wrapper.text()).toContain('Add Credits') }) it('shows correct UI for inactive subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = false + mockSubscriptionData.isSubscriptionRequirementMet.value = false const wrapper = createWrapper() … }) it('shows renewal date for active non-cancelled subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = true mockSubscriptionData.isCancelled = false … }) it('shows expiry date for cancelled subscription', () => { - mockSubscriptionData.isSubscriptionRequirementMet = true + mockSubscriptionData.isSubscriptionRequirementMet.value = true mockSubscriptionData.isCancelled = true … })This keeps the test double structurally compatible with the real composable.
Also applies to: 123-152
♻️ Duplicate comments (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
125-131: Consider early‑returning inrequireActiveSubscriptionwhen subscription isn’t required
requireActiveSubscriptionstill callsfetchSubscriptionStatus()even whenisSubscriptionRequirementMetwill always betrue(e.g., non‑cloud builds or whensubscription_requiredis false), which means unnecessary network calls and side‑effects in cases where gating is effectively disabled.You can short‑circuit before fetching to better match the PR goal of avoiding cloud side‑effects locally:
- const requireActiveSubscription = async (): Promise<void> => { - await fetchSubscriptionStatus() - - if (!isSubscriptionRequirementMet.value) { - showSubscriptionDialog() - } - } + const requireActiveSubscription = async (): Promise<void> => { + // Skip remote status checks when subscription gating is not enforced + if (!isCloud || !window.__CONFIG__?.subscription_required) { + return + } + + await fetchSubscriptionStatus() + + if (!isSubscriptionRequirementMet.value) { + showSubscriptionDialog() + } + }This preserves behavior for cloud builds while avoiding unnecessary initialization and network calls when the subscription requirement is disabled.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (18)
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue(2 hunks)src/components/dialog/content/setting/CreditsPanel.vue(3 hunks)src/components/topbar/CurrentUserPopover.test.ts(1 hunks)src/components/topbar/CurrentUserPopover.vue(4 hunks)src/composables/auth/useFirebaseAuthActions.ts(1 hunks)src/composables/useCoreCommands.ts(7 hunks)src/extensions/core/cloudRemoteConfig.ts(1 hunks)src/platform/cloud/subscription/components/SubscribeButton.vue(2 hunks)src/platform/cloud/subscription/components/SubscriptionPanel.vue(5 hunks)src/platform/cloud/subscription/composables/useSubscription.ts(4 hunks)src/platform/cloud/subscription/composables/useSubscriptionActions.ts(1 hunks)src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts(2 hunks)src/scripts/app.ts(1 hunks)src/services/dialogService.ts(1 hunks)tests-ui/tests/composables/useCoreCommands.test.ts(1 hunks)tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts(3 hunks)tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/scripts/app.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vue
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript exclusively; no new JavaScript code
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/scripts/app.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
**/*.{ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see.prettierrc)
Use single quotes for strings (see.prettierrc)
No trailing semicolons (see.prettierrc)
Maximum line width of 80 characters (see.prettierrc)
Sort and group imports by plugin (runpnpm formatbefore committing)
Never useanytype; use proper TypeScript types instead
Never useas anytype assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions
Files:
src/components/topbar/CurrentUserPopover.test.tssrc/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/scripts/app.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tstests-ui/tests/composables/useCoreCommands.test.tssrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
src/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
Write unit and component tests with Vitest using happy-dom
Files:
src/components/topbar/CurrentUserPopover.test.ts
**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests
Files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components
Files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3 SFCs with Composition API only (use<script setup lang="ts">, not Options API)
Avoid using<style>blocks; use Tailwind 4 for all styling
UsedefinePropswith TypeScript style default declaration; do not usewithDefaultsor runtime props declaration
PreferuseModelover separately defining a prop and emit
Usecomputedinstead of arefandwatchif possible
Avoid usingrefif a prop would accomplish the design goals; avoid usingcomputedif arefor prop directly would work
Do not import Vue macros unnecessarily
Never use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Never use:class="[]"to merge class names; always usecn()from@/utils/tailwindUtil(e.g.,<div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />)
Leverage VueUse functions for performance-enhancing styles
Avoid new usage of PrimeVue components
Use Vue 3 Teleport component when needed
Use Vue 3 Suspense for async components
Files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
**/components/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue components in PascalCase (e.g.,
MenuHamburger.vue)
Files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/components/topbar/CurrentUserPopover.vuesrc/components/dialog/content/setting/CreditsPanel.vuesrc/platform/cloud/subscription/components/SubscriptionPanel.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)
tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks
Files:
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tstests-ui/tests/composables/useCoreCommands.test.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/services/dialogService.tssrc/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/composables/auth/useFirebaseAuthActions.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
**/composables/**/use*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables with
useXyz.tspattern
Files:
src/platform/cloud/subscription/composables/useSubscriptionActions.tssrc/composables/useCoreCommands.tssrc/composables/auth/useFirebaseAuthActions.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/composables/useSubscription.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts
🧠 Learnings (33)
📚 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 tests
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.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 possible
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing change detector tests that just assert default values
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup
Applied to files:
src/components/topbar/CurrentUserPopover.test.tstests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuetests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.tstests-ui/tests/platform/cloud/subscription/useSubscription.test.tssrc/platform/cloud/subscription/components/SubscribeButton.vuesrc/services/dialogService.tssrc/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vuesrc/composables/auth/useFirebaseAuthActions.tssrc/extensions/core/cloudRemoteConfig.tstests-ui/tests/composables/useCoreCommands.test.tssrc/platform/cloud/subscription/components/SubscriptionPanel.vuesrc/platform/cloud/subscription/composables/useSubscription.tstests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.tssrc/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.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 : Extract complex conditionals to computed properties
Applied to files:
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vuesrc/composables/useCoreCommands.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 : Prefer emit/event-name for state changes over other communication patterns
Applied to files:
src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use `computed` instead of a `ref` and `watch` if possible
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Sort and group imports by plugin (run `pnpm format` before committing)
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/composables/useCoreCommands.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Applied to files:
src/composables/useCoreCommands.tssrc/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.
Applied to files:
src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API
Applied to files:
src/components/topbar/CurrentUserPopover.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/**/{services,composables}/**/*.{ts,tsx} : Use `api.fileURL()` for static file access instead of constructing URLs directly
Applied to files:
src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Implement proper error handling
Applied to files:
src/composables/auth/useFirebaseAuthActions.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 mocks
Applied to files:
tests-ui/tests/composables/useCoreCommands.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 utilities
Applied to files:
tests-ui/tests/composables/useCoreCommands.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 codebase
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions
Applied to files:
tests-ui/tests/composables/useCoreCommands.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/composables/**/use*.ts : Name composables with `useXyz.ts` pattern
Applied to files:
src/platform/cloud/subscription/composables/useSubscription.ts
🧬 Code graph analysis (8)
src/scripts/app.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/services/dialogService.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/composables/useCoreCommands.ts (3)
tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts (1)
isCloud(34-36)tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useComboWidget.test.ts (1)
isCloud(44-46)src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
src/extensions/core/cloudRemoteConfig.ts (1)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
useSubscription(244-244)
tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
src/extensions/core/load3d/Load3d.ts (1)
isActive(383-391)
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (2)
src/platform/cloud/subscription/composables/useSubscription.ts (1)
CloudSubscriptionStatusResponse(23-28)src/platform/telemetry/types.ts (1)
TelemetryProvider(259-328)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: test
- GitHub Check: setup
- GitHub Check: collect
- GitHub Check: lint-and-format
🔇 Additional comments (15)
src/components/topbar/CurrentUserPopover.test.ts (1)
81-88: Mock shape forisSubscriptionRequirementMetis correctReturning
{ value: true }keeps the mock ref‑like and aligned with the realuseSubscriptionAPI, soisSubscriptionRequirementMet.valueusage in the component will behave as expected.tests-ui/tests/composables/useCoreCommands.test.ts (1)
101-106:useSubscriptionmock now matches ref-like contractMocking
isSubscriptionRequirementMetas{ value: true }aligns with the composable’s ref/computed API and fixes the earlier mismatch where a function was returned.tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts (1)
27-36: Watcher tests correctly adapted toisSubscriptionRequirementMetWrapping
isActivein a computedisSubscriptionRequirementMetand passing it intouseSubscriptionCancellationWatcherkeeps the tests reactive while matching the new option name and shape.Also applies to: 77-83, 107-113, 129-135, 153-160
src/extensions/core/cloudRemoteConfig.ts (1)
16-27: Remote config watcher correctly tracks new subscription flagUsing
{ isSubscriptionRequirementMet } = useSubscription()and adding it to thewatchDebouncedsources keeps the logic functionally the same (guarding onisLoggedIn) while ensuring remote config refreshes when subscription state changes.src/scripts/app.ts (1)
668-691: Payment‑required handling correctly gated by environment and subscriptionThe new branch:
- Keeps local behavior unchanged (
!isCloudalways shows the Top Up dialog).- In cloud, only shows the Top Up dialog when
isSubscriptionRequirementMet.valueis true, avoiding offering credits when the subscription requirement isn’t met.This is consistent with the updated subscription semantics and cloud‑aware gating elsewhere in the codebase.
src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue (1)
2-5: Cloud run button wrapper correctly migrated toisSubscriptionRequirementMetUsing
isSubscriptionRequirementMetfor both thekeyandcurrentButtonselection cleanly switches between queue vs subscribe buttons while preserving reactivity (.valuein script, unwrapped in template).Also applies to: 14-18
src/platform/cloud/subscription/components/SubscribeButton.vue (1)
54-55: Subscription flag rename is correctly wired into polling flowUsing
isSubscriptionRequirementMetfromuseSubscription()and checking it in the polling loop preserves the previous semantics while aligning with the new API; stop, telemetry, andsubscribedemission all remain correctly gated on the requirement being met.Also applies to: 80-84
src/composables/auth/useFirebaseAuthActions.ts (1)
83-90: Dynamic cloud‑scoped subscription check before credit purchaseMoving
useSubscriptioninto anisCloud‑guarded dynamic import and short‑circuiting when!isSubscriptionRequirementMet.valuecleanly enforces subscription requirements for credit purchases while avoiding initialization of the subscription composable in local builds; non‑cloud behavior remains unchanged.src/components/dialog/content/setting/CreditsPanel.vue (1)
18-23: Computed cloud‑awareisSubscriptionRequirementMetcleanly gates the purchase buttonDeriving
subscriptiononly whenisCloudand using a computedisSubscriptionRequirementMet(true for non‑cloud, otherwise mirroring the composable’s flag) ensures the “Purchase credits” button is only shown when the subscription requirement is satisfied, while keeping local environments unaffected and avoiding unnecessary subscription initialization.Also applies to: 128-152
src/platform/cloud/subscription/composables/useSubscriptionCancellationWatcher.ts (1)
13-19: Cancellation watcher correctly switched toisSubscriptionRequirementMetUpdating the options type, destructuring, and cancellation condition to use
isSubscriptionRequirementMetkeeps the watcher behavior consistent with the composable’s renamed API and removes the earlier unused legacy flag from the surface.Also applies to: 21-27, 76-88
src/components/topbar/CurrentUserPopover.vue (1)
26-55: Cloud‑aware subscription gating in popover is consistent and safeGuarding
useSubscription()behindisCloudand exposingisSubscriptionRequirementMetwith a computed true fallback ensures the popover only initializes subscription logic in cloud builds, cleanly switches between credits UI andSubscribeButton, and keepshandleSubscribedsafe via a noopfetchStatuswhen subscription is unavailable.Also applies to: 73-75, 124-132
tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts (1)
95-110: Tests correctly validateisSubscriptionRequirementMetfor active vs inactive statesSwitching the expectations to
isSubscriptionRequirementMet.valuein both the active and inactive scenarios preserves the intent of the tests and keeps them aligned with the updateduseSubscriptionAPI.Also applies to: 112-127
src/composables/useCoreCommands.ts (1)
1-2: Subscription gating for queue commands viasubscriptionState/subscriptionDialogis well-structuredUsing
isCloud ? useSubscription() : nullwith adefaultSubscriptionState = computed(() => true)and anoopdialog cleanly avoids initializing the shared subscription composable on local builds, while the newsubscriptionState.valuechecks in the three queue commands correctly gate execution and invoke the subscription dialog when requirements aren’t met.Also applies to: 24-25, 51-52, 69-71, 92-96, 477-497, 500-521, 523-566
src/platform/cloud/subscription/components/SubscriptionPanel.vue (1)
7-10:isSubscriptionRequirementMetrename is correctly propagated through the panelAll subscription‑gated template branches and the
useSubscriptiondestructuring have been updated to useisSubscriptionRequirementMet, keeping the UI logic consistent with the composable’s new API without altering behavior.Also applies to: 30-47, 50-71, 199-212, 322-330
src/platform/cloud/subscription/composables/useSubscription.ts (1)
34-38: NewisSubscriptionRequirementMetcomputed cleanly models “required or already subscribed”The computed correctly returns
truewhen subscription checks don’t apply (non‑cloud orsubscription_requiredis falsy) and mirrors the previous semantics when they do. Wiring it intouseSubscriptionCancellationWatcherand exposing it in the returned state keeps internal logic and public API aligned with the rename.Also applies to: 111-118, 224-241
| const handleAddApiCredits = async () => { | ||
| await dialogService.showTopUpCreditsDialog() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider adding error handling around async top‑up dialog
Making handleAddApiCredits async and awaiting showTopUpCreditsDialog is fine for click handlers, but unlike handleMessageSupport/handleRefresh it doesn’t guard against rejections. For consistency and robustness you could wrap it:
- const handleAddApiCredits = async () => {
- await dialogService.showTopUpCreditsDialog()
- }
+ const handleAddApiCredits = async () => {
+ try {
+ await dialogService.showTopUpCreditsDialog()
+ } catch (error) {
+ console.error(
+ '[useSubscriptionActions] Error opening top-up dialog:',
+ error
+ )
+ }
+ }Not required for correctness, but aligns with the rest of this composable’s error‑handling pattern.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleAddApiCredits = async () => { | |
| await dialogService.showTopUpCreditsDialog() | |
| } | |
| const handleAddApiCredits = async () => { | |
| try { | |
| await dialogService.showTopUpCreditsDialog() | |
| } catch (error) { | |
| console.error( | |
| '[useSubscriptionActions] Error opening top-up dialog:', | |
| error | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/platform/cloud/subscription/composables/useSubscriptionActions.ts around
lines 39 to 41, handleAddApiCredits calls and awaits
dialogService.showTopUpCreditsDialog but lacks error handling; wrap the await in
a try/catch (matching the pattern used by handleMessageSupport/handleRefresh),
log the error or surface it to dialogService/processLogger as appropriate, and
ensure any caught error resets any local state or rethrows if needed to preserve
existing behavior.
| async function showTopUpCreditsDialog(options?: { | ||
| isInsufficientCredits?: boolean | ||
| }) { | ||
| const { isActiveSubscription } = useSubscription() | ||
| if (!isActiveSubscription.value) return | ||
| if (isCloud) { | ||
| const { useSubscription } = await import( | ||
| '@/platform/cloud/subscription/composables/useSubscription' | ||
| ) | ||
| const { isSubscriptionRequirementMet } = useSubscription() | ||
| if (!isSubscriptionRequirementMet.value) return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
rg -n "showTopUpCreditsDialog" srcRepository: Comfy-Org/ComfyUI_frontend
Length of output: 999
🏁 Script executed:
# Check app.ts context around lines 680, 686
sed -n '675,695n' src/scripts/app.ts
# Check CurrentUserPopover.vue context around line 151
sed -n '145,160n' src/components/topbar/CurrentUserPopover.vue
# Check CreditsPanel.vue context around line 176
sed -n '170,185n' src/components/dialog/content/setting/CreditsPanel.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Check app.ts around lines 680, 686
cat -n src/scripts/app.ts | sed -n '675,695p'
# Check CurrentUserPopover.vue around line 151
cat -n src/components/topbar/CurrentUserPopover.vue | sed -n '145,160p'
# Check CreditsPanel.vue around line 176
cat -n src/components/dialog/content/setting/CreditsPanel.vue | sed -n '170,185p'Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1916
🏁 Script executed:
# Read the full showTopUpCreditsDialog function from dialogService.ts
sed -n '379,430p' src/services/dialogService.ts | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2060
🏁 Script executed:
# Find dialogStore and its showDialog method
rg -n "showDialog" src/stores/dialogStore.ts -A 5 | head -40Repository: Comfy-Org/ComfyUI_frontend
Length of output: 442
🏁 Script executed:
# Check the full showDialog implementation
sed -n '212,245p' src/stores/dialogStore.ts | cat -nRepository: Comfy-Org/ComfyUI_frontend
Length of output: 1404
Add await to showTopUpCreditsDialog calls to ensure subscription requirement check completes before dialog opens
The function is now async with a subscription requirement check in the cloud path (lines 384-387), but four call sites invoke it without await: lines 680 and 686 in src/scripts/app.ts, line 151 in src/components/topbar/CurrentUserPopover.vue, and line 176 in src/components/dialog/content/setting/CreditsPanel.vue. Without awaiting, the subscription requirement check may not complete before the dialog opens, bypassing the intended gate for cloud users. Update these fire-and-forget calls to await dialogService.showTopUpCreditsDialog() (line 40 in src/platform/cloud/subscription/composables/useSubscriptionActions.ts already does this correctly).
Renames the shared subscription state export to keep the descriptive name
isSubscribedOrIsNotCloud. Previously it was justisSubscribedwhich led to some misunderstandings and could lieIn some call sites, short-circuit on
isCloudearlier, to avoid initializing a cloud-specific module (which can have non-breaking but inadvertant side-effects like network requests) on local. We want that all to be tree-shaken on local┆Issue is synchronized with this Notion page by Unito