Skip to content

Conversation

@Yourz
Copy link
Collaborator

@Yourz Yourz commented Dec 16, 2025

Summary

Discussion here: https://comfy-organization.slack.com/archives/C0A0XANFJRE/p1764899027465379

Implement: Subscription tier query parameter for direct checkout flow

Example button link: /cloud/subscribe?tier=standard

tier could be standard, creator or pro

Changes

  • What:

    • Add a landing page called CloudSubscriptionRedirectView.vue to handling the subscription tier button link parameter
    • Extract subscription handling logic from PriceTable.vue
  • Breaking:

    • Code change touched PriceTable.vue
  • Dependencies:

Review Focus

  • link will redirect to login url, when cloud app not login
  • after login, the cloud app will redirect to CloudSubscriptionRedirect page
  • wait for several seconds, the cloud app will be redirected to checkout page

Screenshots (if applicable)

Kapture 2025-12-16 at 18 43 28

┆Issue is synchronized with this Notion page by Unito

@Yourz Yourz requested a review from a team as a code owner December 16, 2025 10:43
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

Preserves and validates previous navigation when redirecting to cloud auth, centralizes subscription checkout, adds a subscribe redirect view and route, exposes subscription initialization state, and extends billing-portal action to support in-tab navigation. Also adds tests, utils, and lint-staged config.

Changes

Cohort / File(s) Summary
Onboarding Path Preservation
src/router.ts, src/platform/cloud/onboarding/CloudLoginView.vue, src/platform/cloud/onboarding/CloudSignupView.vue
Compute and attach previousFullPath to login redirects; onSuccess handlers now read and safely redirect to previousFullPath when present. navigateToSignup/navigateToLogin made async to await router navigation.
Path Safety Utilities
src/platform/cloud/onboarding/utils/previousFullPath.ts, src/platform/cloud/onboarding/utils/previousFullPath.test.ts
New getSafePreviousFullPath(query) exports decoding and validation (rejects protocol-relative/external/malformed values); accompanying unit tests added.
Subscription Checkout Centralization
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts, src/platform/cloud/subscription/components/PricingTable.vue
New performSubscriptionCheckout(tierKey, billingCycle, openInNewTab?) encapsulates auth/header, POST checkout request, response normalization, and navigation; PricingTable delegates to this util and drops in-file fetch/auth logic.
Subscription Redirect Flow
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue, src/platform/cloud/onboarding/onboardingCloudRoutes.ts, src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
New route cloud-subscribe and component parse/validate tier & cycle, await subscription init, then either open billing portal or call checkout (with loading state and skip link); test suite covers validation, checkout, portal, and UI states.
Subscription State & Actions
src/platform/cloud/subscription/composables/useSubscription.ts, src/composables/auth/useFirebaseAuthActions.ts
useSubscriptionInternal now exposes isInitialized to signal readiness; accessBillingPortal signature extended to openInNewTab?: boolean and supports in-tab navigation when false.
Component & Global Updates
src/platform/cloud/onboarding/UserCheckView.vue, src/locales/en/main.json
Swap window.location.hrefglobalThis.location.href; add i18n key cloudOnboarding.skipToCloudApp.
Linting Configuration
lint-staged.config.mjs
New lint-staged config with format+eslint handlers and a typecheck step for TS/Vue files.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Router
    participant CloudLogin as CloudLoginView
    participant Auth as FirebaseAuth
    participant CloudCheck as UserCheckView

    User->>Router: Attempt protected route
    Router->>Router: Compute encoded previousFullPath (if not '/')
    Router->>CloudLogin: Redirect to cloud-login with previousFullPath query
    User->>CloudLogin: Submit credentials
    CloudLogin->>Auth: authenticateWithEmail(...)
    Auth-->>CloudLogin: Success
    CloudLogin->>CloudLogin: getSafePreviousFullPath(route.query)
    alt previousFullPath present and safe
        CloudLogin->>Router: router.replace(previousFullPath)
        Router-->>User: Navigate back to previous path
    else no previousFullPath
        CloudLogin->>CloudCheck: router.push(cloud-user-check)
        CloudCheck->>Auth: fetch subscription / user data
        Auth-->>CloudCheck: subscription response
        CloudCheck-->>User: Continue onboarding flow
    end
Loading
sequenceDiagram
    participant User
    participant Router
    participant SubRedirect as CloudSubscriptionRedirectView
    participant SubComposable as useSubscription
    participant Firebase as FirebaseAuthActions
    participant Checkout as performSubscriptionCheckout
    participant BillingAPI as Billing Portal / Checkout API

    User->>Router: Visit /subscribe?tier=pro&cycle=yearly
    Router->>SubRedirect: Load with query params
    SubRedirect->>SubRedirect: Validate tier & cycle (default monthly)
    SubRedirect->>SubComposable: await isInitialized
    SubComposable->>Firebase: ensure subscription status fetched
    Firebase-->>SubComposable: subscription state ready
    alt active subscription exists
        SubRedirect->>Firebase: accessBillingPortal(targetTier, openInNewTab=true)
        Firebase->>BillingAPI: request portal URL
        BillingAPI-->>Firebase: returns portal URL
        Firebase-->>SubRedirect: returns URL
        SubRedirect-->>User: open URL in new tab
    else no active subscription
        SubRedirect->>Checkout: performSubscriptionCheckout(tier, cycle, openInNewTab=false)
        Checkout->>Firebase: get auth header
        Checkout->>BillingAPI: POST /customers/cloud-subscription-checkout/{checkoutTier}
        BillingAPI-->>Checkout: { checkout_url }
        Checkout-->>SubRedirect: returns URL
        SubRedirect-->>User: navigate current tab to checkout_url
    end
Loading

Possibly related PRs

  • #7572: Overlapping changes to PricingTable.vue and checkout-tier logic; likely interacts with the centralized checkout refactor.
  • #7356: Modifies the same useSubscription composable public API (adds properties); directly related to isInitialized addition.
  • #7419: Changes accessBillingPortal usage and UI for managing subscriptions; touches the same billing-portal action signature.

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.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/08/2026, 01:55:43 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 01/08/2026, 02:01:05 AM UTC

📈 Summary

  • Total Tests: 512
  • Passed: 502 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 8 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 492 / ❌ 0 / ⚠️ 1 / ⏭️ 8
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 7 / ❌ 0 / ⚠️ 1 / ⏭️ 0

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

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

Bundle Size Report

Summary

  • Raw size: 17.6 MB baseline 17.6 MB — 🔴 +335 B
  • Gzip: 3.6 MB baseline 3.6 MB — 🔴 +36 B
  • Brotli: 2.74 MB baseline 2.74 MB — 🔴 +230 B
  • Bundles: 94 current • 94 baseline • 38 added / 38 removed

Category Glance
App Entry Points 🔴 +365 B (3.25 MB) · Other 🟢 -30 B (3.6 MB) · Vendor & Third-Party ⚪ 0 B (9.19 MB) · Graph Workspace ⚪ 0 B (1.01 MB) · Panels & Settings ⚪ 0 B (300 kB) · UI Components ⚪ 0 B (197 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.25 MB (baseline 3.25 MB) • 🔴 +365 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-JV66lZWP.js (new) 3.05 MB 🔴 +3.05 MB 🔴 +641 kB 🔴 +486 kB
assets/index-gYQAm80W.js (removed) 3.05 MB 🟢 -3.05 MB 🟢 -641 kB 🟢 -486 kB
assets/index-DiNiJe7O.js (new) 194 kB 🔴 +194 kB 🔴 +42.3 kB 🔴 +35.1 kB
assets/index-eO9Az83o.js (removed) 194 kB 🟢 -194 kB 🟢 -42.3 kB 🟢 -35.1 kB
assets/index-D0CkTxUD.js (new) 345 B 🔴 +345 B 🔴 +246 B 🔴 +232 B
assets/index-D9M4Xt_I.js (removed) 345 B 🟢 -345 B 🟢 -247 B 🟢 -232 B

Status: 3 added / 3 removed

Graph Workspace — 1.01 MB (baseline 1.01 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-B6sZsCha.js (new) 1.01 MB 🔴 +1.01 MB 🔴 +197 kB 🔴 +150 kB
assets/GraphView-CgiUX0kp.js (removed) 1.01 MB 🟢 -1.01 MB 🟢 -197 kB 🟢 -150 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-0uDEhMUA.js (new) 6.63 kB 🔴 +6.63 kB 🔴 +2.14 kB 🔴 +1.9 kB
assets/UserSelectView-BSBz1Ocp.js (removed) 6.63 kB 🟢 -6.63 kB 🟢 -2.14 kB 🟢 -1.9 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-BkkR5Gl5.js (removed) 22.7 kB 🟢 -22.7 kB 🟢 -5.25 kB 🟢 -4.6 kB
assets/LegacyCreditsPanel-CSWU5tpQ.js (new) 22.7 kB 🔴 +22.7 kB 🔴 +5.25 kB 🔴 +4.6 kB
assets/KeybindingPanel-hDJpOiXI.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -3.57 kB 🟢 -3.13 kB
assets/KeybindingPanel-iwl7kUNC.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +3.57 kB 🔴 +3.12 kB
assets/ExtensionPanel-B90TrLfl.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.61 kB 🔴 +2.29 kB
assets/ExtensionPanel-ZNnKpCNF.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.61 kB 🟢 -2.29 kB
assets/AboutPanel-CAnrIZmB.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/AboutPanel-D9UAHqe-.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/ServerConfigPanel-D9VohxSL.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +2.04 kB 🔴 +1.8 kB
assets/ServerConfigPanel-r63GhbRW.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -2.04 kB 🟢 -1.8 kB
assets/UserPanel-D29frx9J.js (removed) 6.88 kB 🟢 -6.88 kB 🟢 -1.79 kB 🟢 -1.56 kB
assets/UserPanel-NPZ20ktH.js (new) 6.88 kB 🔴 +6.88 kB 🔴 +1.79 kB 🔴 +1.56 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BIdKi-OT.js 26.2 kB 26.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Bu3OR-lX.js 24.6 kB 24.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-ByL6gy5c.js 25.4 kB 25.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CjlRFMdL.js 32.8 kB 32.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DkGwvylK.js 26.9 kB 26.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Dyd027Dx.js 24.7 kB 24.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-MzsBgiwB.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-wwBxqLH5.js 21.3 kB 21.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-xx2Yb6R2.js 23.8 kB 23.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 197 kB (baseline 197 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LazyImage.vue_vue_type_script_setup_true_lang-Bx3QMK-N.js (removed) 63 kB 🟢 -63 kB 🟢 -12.9 kB 🟢 -11.2 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-wpRUmp2m.js (new) 63 kB 🔴 +63 kB 🔴 +12.9 kB 🔴 +11.2 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-nLkpFaQi.js (removed) 56 kB 🟢 -56 kB 🟢 -8.76 kB 🟢 -7.52 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-Vl-ZPHqw.js (new) 56 kB 🔴 +56 kB 🔴 +8.76 kB 🔴 +7.51 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-B49zCIb9.js (removed) 49 kB 🟢 -49 kB 🟢 -10.5 kB 🟢 -9.13 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-BlMMH98R.js (new) 49 kB 🔴 +49 kB 🔴 +10.5 kB 🔴 +9.14 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-C2O8jKVN.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +2.89 kB 🔴 +2.55 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CWmEhlg7.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -2.9 kB 🟢 -2.56 kB
assets/ComfyQueueButton-ChBBH6z1.js (new) 8.83 kB 🔴 +8.83 kB 🔴 +2.57 kB 🔴 +2.29 kB
assets/ComfyQueueButton-CwWJBufg.js (removed) 8.83 kB 🟢 -8.83 kB 🟢 -2.58 kB 🟢 -2.3 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-Bqp5s_xY.js (new) 3.72 kB 🔴 +3.72 kB 🔴 +1.45 kB 🔴 +1.32 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-jGAWGCA7.js (removed) 3.72 kB 🟢 -3.72 kB 🟢 -1.45 kB 🟢 -1.32 kB
assets/WidgetButton-Bmyln6K9.js (removed) 2.21 kB 🟢 -2.21 kB 🟢 -995 B 🟢 -894 B
assets/WidgetButton-DSUUdunT.js (new) 2.21 kB 🔴 +2.21 kB 🔴 +994 B 🔴 +891 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-C-_wOzeP.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +888 B 🔴 +770 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-DKFoU8v6.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -891 B 🟢 -770 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-PtsQiccS.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 removed

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

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-CbpOkqCW.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.57 kB
assets/keybindingService-CnigPIeI.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/audioService-B9JQDo4_.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -963 B 🟢 -821 B
assets/audioService-BhjqrC1b.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +962 B 🔴 +821 B
assets/serverConfigStore-C7L6OKtS.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-BM30wuLm.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +552 B
assets/audioUtils-C63Y1dF0.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -651 B 🟢 -547 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-CAFSFyru.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-CtqoBnhc.js 3.9 MB 3.9 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-B1YbLmDP.js 1.95 MB 1.95 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-gKB3jfCi.js 2.08 MB 2.08 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DxCePpNw.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Btw3Hy_q.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.6 MB (baseline 3.6 MB) • 🟢 -30 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-41UVPNmj.js (removed) 29.3 kB 🟢 -29.3 kB 🟢 -6.51 kB 🟢 -5.64 kB
assets/SubscriptionRequiredDialogContent-CBx7sjyw.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.49 kB 🔴 +5.64 kB
assets/WidgetRecordAudio-BjBPd3hH.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.64 kB
assets/WidgetRecordAudio-Crjx2Ayr.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.23 kB 🔴 +4.63 kB
assets/AudioPreviewPlayer-B984wSIK.js (new) 13.3 kB 🔴 +13.3 kB 🔴 +3.35 kB 🔴 +3 kB
assets/AudioPreviewPlayer-DpjiZlZT.js (removed) 13.3 kB 🟢 -13.3 kB 🟢 -3.35 kB 🟢 -3 kB
assets/ValueControlPopover-BzfkU_Yz.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.7 kB 🔴 +1.52 kB
assets/ValueControlPopover-CUAcP9FH.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.7 kB 🟢 -1.52 kB
assets/WidgetGalleria-DqSSEqOK.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.31 kB
assets/WidgetGalleria-fZuIR_zq.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetColorPicker-CBgKcJdF.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-kF4f48a-.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetTextarea-CKEU2F2X.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.22 kB 🟢 -1.08 kB
assets/WidgetTextarea-nClebHfE.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.21 kB 🔴 +1.08 kB
assets/WidgetMarkdown-CtURI45j.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.12 kB
assets/WidgetMarkdown-UKd22F1E.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.13 kB
assets/WidgetAudioUI-BdYlWtit.js (removed) 2.89 kB 🟢 -2.89 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/WidgetAudioUI-BgXpxJpb.js (new) 2.89 kB 🔴 +2.89 kB 🔴 +1.17 kB 🔴 +1.06 kB
assets/WidgetInputText-CJgivmc0.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -920 B 🟢 -860 B
assets/WidgetInputText-D88FZOLk.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +919 B 🔴 +854 B
assets/WidgetToggleSwitch-AYrd0tNF.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +832 B 🔴 +732 B
assets/WidgetToggleSwitch-B4Xgw4b3.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -834 B 🟢 -732 B
assets/Media3DTop-D38gFe26.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +766 B 🔴 +651 B
assets/Media3DTop-HNYsrqgV.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -762 B 🟢 -653 B
assets/WidgetSelect-Cds-YLf1.js (new) 733 B 🔴 +733 B 🔴 +359 B 🔴 +329 B
assets/WidgetSelect-CYtdEUK8.js (removed) 733 B 🟢 -733 B 🟢 -362 B 🟢 -334 B
assets/WidgetInputNumber-Cj40hX2q.js (new) 673 B 🔴 +673 B 🔴 +347 B 🔴 +295 B
assets/WidgetInputNumber-o40htIfx.js (removed) 673 B 🟢 -673 B 🟢 -348 B 🟢 -311 B
assets/Load3D-CUngvliH.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +222 B
assets/Load3D-DolrICpk.js (removed) 424 B 🟢 -424 B 🟢 -265 B 🟢 -222 B
assets/WidgetLegacy-BgCgoHkf.js (new) 364 B 🔴 +364 B 🔴 +235 B 🔴 +196 B
assets/WidgetLegacy-KWX8sZSL.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -196 B
assets/commands-bTEY9Mp6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CcfGaui5.js 14.4 kB 14.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CisfgZf5.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CkU12Foh.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CoH2DJa6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COSt-Bjx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DalfIW5f.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DfTl0eCm.js 13.5 kB 13.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwSJL865.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bdc58rJq.js 97.1 kB 97.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C9ZJBRdI.js 81.5 kB 81.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CAL83XT3.js 84.6 kB 84.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CHLLfvpG.js 82.4 kB 82.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DDqR5EuX.js 71.3 kB 71.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DLHyaEcz.js 92.1 kB 92.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-JzWMbEh0.js 91.2 kB 91.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-O7KfJeMO.js 79.9 kB 79.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-OzGsrlqJ.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-Cig_KuEt.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-CceP_k47.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-Bm4APiyx.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-aW9En70v.js 260 kB 260 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BDbge6_f.js 279 kB 279 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BIckSVgU.js 273 kB 273 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BiYpVi7D.js 263 kB 263 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CCEXtYfM.js 243 kB 243 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CvmVDWYd.js 323 kB 323 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D_wreoPJ.js 267 kB 267 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dz-0ZIBN.js 297 kB 297 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-VZsNmhG7.js 264 kB 264 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-Bpup_F4s.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-gJXsKU9X.js 3.18 kB 3.18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 16 added / 16 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d1bf6d and 92998fa.

📒 Files selected for processing (8)
  • src/platform/cloud/onboarding/CloudLoginView.vue (1 hunks)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/onboarding/UserCheckView.vue (3 hunks)
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (2 hunks)
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1 hunks)
  • src/router.ts (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
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/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
src/**/*.ts

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

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

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.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/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.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/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/cloud/subscription/components/PricingTable.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/components/PricingTable.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.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/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (29)
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.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/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Be judicious with addition of new refs or other state: prefer props, avoid redundant `computed`, and prefer `computed` over `watch`

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.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/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement proper error handling in Vue components

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

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

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

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

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.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/platform/cloud/onboarding/UserCheckView.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/platform/cloud/onboarding/UserCheckView.vue
🧬 Code graph analysis (1)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)
src/stores/firebaseAuthStore.ts (2)
  • useFirebaseAuthStore (53-473)
  • FirebaseAuthStoreError (46-51)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (9)
src/platform/cloud/onboarding/CloudLoginView.vue (1)

108-108: LGTM!

Preserving route query parameters when navigating to cloud-user-check ensures the subscription flow and previousFullPath redirect logic work correctly after login.

src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1)

68-75: LGTM!

The new subscription-redirect route follows the existing patterns, uses lazy loading, and correctly requires authentication via meta.requiresAuth.

src/router.ts (2)

152-162: LGTM!

The previousFullPath query parameter preservation is well-implemented. Encoding with encodeURIComponent ensures URL-safety, and excluding the root path prevents unnecessary query pollution for standard navigation.


175-178: Consistent query preservation for web login redirects.

Reusing the same query object ensures consistent behavior across both authentication redirect paths.

src/platform/cloud/onboarding/UserCheckView.vue (1)

44-47: LGTM!

Standard handling for vue-router query parameters that can be either string or array.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

66-88: LGTM!

The template follows project guidelines: semantic Tailwind classes (bg-comfy-menu-secondary-bg), proper i18n integration, and accessible alt text for the logo.

src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)

49-69: Error handling is thorough.

The nested try-catch pattern handles multiple failure modes (network error reading text, JSON parse failure, missing message field) with appropriate fallbacks. This defensive approach aligns with existing patterns in firebaseAuthStore.ts.


82-88: LGTM!

The URL handling correctly supports both new-tab (window.open) and same-tab (globalThis.location.href) scenarios. Using globalThis for the redirect is a good choice for broader environment compatibility.

src/platform/cloud/subscription/components/PricingTable.vue (1)

285-285: The call to performSubscriptionCheckout(tierKey) at line 285 is correct. The function signature specifies openInNewTab: boolean = true, making the parameter optional with an appropriate default. Using the default behavior (opening checkout in a new tab) is the intended design for the pricing table context, as evidenced by the alternative call in CloudSubscriptionRedirectView.vue which explicitly passes false to redirect the current page instead.

Comment on lines 64 to 77
if (previousFullPath.value) {
try {
const decodedPath = decodeURIComponent(previousFullPath.value)
// Only allow relative paths (internal redirects)
if (decodedPath.startsWith('/') && !decodedPath.startsWith('//')) {
router.replace(decodedPath)
return
}
// If invalid, fall through to normal onboarding flow
} catch (error) {
// Malformed URI, fall through to normal onboarding flow
console.warn('Invalid previousFullPath parameter:', error)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Read the UserCheckView.vue file
cat -n src/platform/cloud/onboarding/UserCheckView.vue | head -80

# Search for other redirect/URL validation patterns
rg -n 'router\.(replace|push)' --type=vue --type=ts -B2 -A2 | head -50

# Search for any URL validation utilities
fd -e ts -e js | xargs grep -l 'startsWith.*\/\/' 2>/dev/null | head -10

# Check if there are any URL validation utilities in utils directory
find src -name '*url*' -o -name '*route*' -o -name '*redirect*' | grep -E '\.(ts|js)$'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3508


Security validation for internal redirects is correct and prevents protocol-relative attacks.

The check at line 68 correctly prevents //evil.com style attacks, and error handling properly falls through on decode failures. However, note that decodeURIComponent() at line 66 is redundant since Vue Router 4 already decodes query parameters—consider removing this call and directly using the previousFullPath value.

🤖 Prompt for AI Agents
In src/platform/cloud/onboarding/UserCheckView.vue around lines 64 to 77, the
call to decodeURIComponent on previousFullPath.value is redundant because Vue
Router already decodes query params; remove the decodeURIComponent call and use
previousFullPath.value directly in the validation, keep the existing checks to
ensure it starts with '/' and not with '//' and remove or simplify the try/catch
used solely for decode errors so malformed-URI handling is not needed while
preserving the security validation and the fallback to the normal onboarding
flow.

Comment on lines 28 to 35
export async function performSubscriptionCheckout(
tierKey: TierKey,
openInNewTab: boolean = true
): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there are existing or planned tests for subscriptionCheckoutUtil

echo "=== Search for test files referencing subscriptionCheckoutUtil ==="
rg -l 'subscriptionCheckoutUtil|performSubscriptionCheckout' --type=ts -g '*.test.ts' -g '*.spec.ts' 2>/dev/null || echo "No test files found with these references"

echo ""
echo "=== Check for any test file in the same directory ==="
fd -type f -path '*subscription*' -name '*.test.ts' -o -name '*.spec.ts'

echo ""
echo "=== Check if CloudSubscriptionRedirectView tests exist ==="
fd -type f -name '*CloudSubscriptionRedirectView*' | head -20

echo ""
echo "=== Search for mocking of performSubscriptionCheckout ==="
rg 'mock.*performSubscriptionCheckout|performSubscriptionCheckout.*mock' --type=ts 2>/dev/null || echo "No mocking found"

echo ""
echo "=== Search for any vitest/jest mock setup of this function ==="
rg 'vi\.mock.*subscriptionCheckoutUtil|jest\.mock.*subscriptionCheckoutUtil' --type=ts 2>/dev/null || echo "No mocks found"

echo ""
echo "=== List all test files in tests-ui directory ==="
fd -type f -name '*.test.ts' -o -name '*.test.js' | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1029


🏁 Script executed:

#!/bin/bash
# Corrected script to check for tests

echo "=== Search for test files referencing the function ==="
rg 'performSubscriptionCheckout' --type ts -g '*.test.ts' 2>/dev/null | head -20 || echo "No matches in test files"

echo ""
echo "=== Search broadly for all test files ==="
fd '\.test\.ts$' | head -30

echo ""
echo "=== Check tests-ui directory ==="
ls -la tests-ui/ 2>/dev/null | head -20 || echo "tests-ui directory not found"

echo ""
echo "=== Search for CloudSubscriptionRedirectView across all ts/js files ==="
rg 'CloudSubscriptionRedirectView' --type ts --type js 2>/dev/null | head -10 || echo "Not found"

echo ""
echo "=== Check subscription-related test files ==="
fd 'subscription' | grep -E '\.(test|spec)\.(ts|js)$'

echo ""
echo "=== Get overall structure of tests ==="
find . -maxdepth 2 -type d -name 'test*' -o -name '__test*' -o -name 'spec*' 2>/dev/null | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3927


🏁 Script executed:

#!/bin/bash
# Check the CloudSubscriptionRedirectView test file for mocks

echo "=== Content of CloudSubscriptionRedirectView.test.ts ==="
cat tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts

echo ""
echo "=== Search for performSubscriptionCheckout in all subscription test files ==="
rg 'performSubscriptionCheckout' tests-ui/tests/platform/cloud/subscription/ 2>/dev/null || echo "Not found in subscription tests"

echo ""
echo "=== Check if subscriptionCheckoutUtil is imported in test files ==="
rg 'subscriptionCheckoutUtil' tests-ui/tests/ 2>/dev/null || echo "Not found"

echo ""
echo "=== Check if there's a test file in the utils directory ==="
find tests-ui/tests/platform/cloud/subscription -name '*util*' -o -name '*checkout*'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2991


🏁 Script executed:

#!/bin/bash
# Check the subscriptionCheckoutUtil file to understand what it does

echo "=== Content of subscriptionCheckoutUtil.ts ==="
cat src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts

echo ""
echo "=== Search for imports and usages of performSubscriptionCheckout ==="
rg 'performSubscriptionCheckout' src/ --type ts -B 2 -A 2

echo ""
echo "=== Check if this function is called from CloudSubscriptionRedirectView ==="
rg 'performSubscriptionCheckout' src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue 2>/dev/null || echo "Not found in CloudSubscriptionRedirectView"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3343


Add dedicated unit tests for the subscription checkout utility.

This utility handles critical checkout logic including authentication validation, HTTP error handling with multiple fallback paths, JSON response parsing, and window navigation—none of which are tested directly. While CloudSubscriptionRedirectView uses this function, its tests do not cover the utility's edge cases. Consider adding tests for: auth failures, HTTP error responses with various formats, JSON parsing failures, and both navigation modes (new tab vs. redirect).

🤖 Prompt for AI Agents
In src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts around
lines 28 to 31, add dedicated unit tests that exercise all edge cases of
performSubscriptionCheckout: write tests that (1) simulate authentication
failure by mocking the auth/token provider to throw or return invalid
credentials and assert the function rejects or handles it as expected, (2) mock
fetch to return HTTP error responses with different payloads (plain text, JSON
with message field, empty body) and assert the error handling/fallback messages,
(3) mock fetch to return malformed JSON to verify JSON parsing failure paths are
handled, and (4) test both navigation modes by stubbing window.open and
window.location.assign (or window.location.href) to ensure new-tab and redirect
behaviors are executed correctly; use spies/mocks to assert calls and expected
side effects. Ensure each test isolates network/auth via dependency injection or
jest.spyOn/global.fetch mock and restores globals after tests.

Comment on lines 41 to 53
const response = await fetch(
`${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${tierKey}`,
{
method: 'POST',
headers: { ...authHeader, 'Content-Type': 'application/json' }
}
)
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider removing unnecessary Content-Type header.

The POST request has no body, so the Content-Type: application/json header is unnecessary and could potentially cause issues with some servers that validate content type against body presence.

   const response = await fetch(
     `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${tierKey}`,
     {
       method: 'POST',
-      headers: { ...authHeader, 'Content-Type': 'application/json' }
+      headers: { ...authHeader }
     }
   )
🤖 Prompt for AI Agents
In src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts around
lines 41 to 47, the POST fetch includes a 'Content-Type: application/json'
header despite having no request body; remove that header (only send authHeader)
so the request doesn't advertise a JSON body it doesn't send and avoid potential
server validation issues.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92998fa and 0df9c60.

📒 Files selected for processing (3)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/components/PricingTable.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/components/PricingTable.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/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (30)
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Unit/component test files must be named `**/*.test.ts` or in `tests-ui/` directory

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Favor pure functions, especially testable ones

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
⏰ 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: test
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (4)
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

91-147: LGTM - Comprehensive test coverage for the redirect component.

The test suite properly covers all key scenarios: missing/invalid subscription types redirecting home, valid types triggering checkout, active subscriptions opening billing portal, and array query parameter handling. Good use of vi.hoisted() for mock setup and proper async handling with flushPromises.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

69-91: Template implementation looks good.

The template is clean with proper i18n integration, accessible alt text for the logo, and conditional rendering. Uses Tailwind classes appropriately per guidelines.

src/platform/cloud/subscription/components/PricingTable.vue (2)

175-176: Good refactor: imports TierKey from the centralized utility.

This addresses the previous review feedback to avoid type duplication. The type import is properly separated with import type.


275-291: Clean delegation to centralized checkout utility.

The handleSubscribe function properly delegates to performSubscriptionCheckout while maintaining local loading state management and the existing billing portal flow for active subscriptions. Error handling remains intact via wrapWithErrorHandlingAsync.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0df9c60 and 4e7c0ce.

📒 Files selected for processing (3)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/subscription/composables/useSubscription.ts (3 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
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/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/component test files must be named **/*.test.ts or in tests-ui/ directory
Do not write change detector tests that just assert default values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing; do not write redundant tests; see composable tests approach
Follow 'Don't Mock What You Don't Own' principle - avoid mocking external dependencies
Do not write tests that just test the mocks; ensure tests fail when code behaves unexpectedly
Leverage Vitest's mocking utilities where possible for test mocking
Keep module mocks contained in test files; do not use global mutable state within test files; use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.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/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.ts

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

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

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/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/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/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/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧠 Learnings (28)
📚 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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Leverage Vitest's mocking utilities where possible for test mocking

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Unit/component test files must be named `**/*.test.ts` or in `tests-ui/` directory

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Keep module mocks contained in test files; do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Favor pure functions, especially testable ones

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
🔇 Additional comments (3)
src/platform/cloud/subscription/composables/useSubscription.ts (1)

39-39: LGTM! Initialization flag properly guards subscription state.

The isInitialized flag correctly tracks subscription status initialization across all code paths. The try/finally block ensures the flag is set to true even when fetchSubscriptionStatus fails, preventing components from waiting indefinitely. The immediate: true watcher guarantees initialization runs on composable setup.

Also applies to: 197-201, 205-205, 246-246

tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

1-150: LGTM! Comprehensive test coverage with clean mocking.

The test suite effectively covers the subscription redirect flow:

  • Validates handling of missing, invalid, and valid query parameters
  • Verifies active subscription branches to billing portal instead of checkout
  • Tests array-type query parameter extraction
  • Mocking patterns follow Vitest best practices with vi.hoisted() and proper cleanup
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

33-96: LGTM! Robust redirect flow with proper initialization handling.

The component correctly:

  • Extracts and validates subscriptionType from query parameters (handles both string and array)
  • Awaits subscription initialization with until(isInitialized).toBe(true) to prevent race conditions
  • Branches appropriately between billing portal (active subscription) and checkout flow
  • Wraps async logic with error handling
  • Uses i18n for all user-facing strings

@Yourz Yourz enabled auto-merge (squash) December 16, 2025 15:28
@Yourz Yourz force-pushed the feat--subscription-tier-button branch from 4e7c0ce to 127ade7 Compare December 18, 2025 11:57
@Yourz Yourz requested review from a team, KarryCharon, Yorha4D and shinshin86 as code owners December 18, 2025 11:57
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Dec 18, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1)

1-87: Overall structure is sound, but past review comments remain unaddressed.

The checkout utility provides a clean abstraction for subscription checkout logic. However, two previously raised concerns from past reviews have not been addressed:

  1. Missing unit tests (lines 31-35): The function handles critical flows including authentication, HTTP errors with multiple fallback paths, JSON parsing failures, and navigation—none of which are directly tested.

  2. Unnecessary Content-Type header (line 51): The POST request includes 'Content-Type': application/json' despite having no request body.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7c0ce and 127ade7.

📒 Files selected for processing (14)
  • lint-staged.config.mjs (1 hunks)
  • src/locales/en/main.json (1 hunks)
  • src/platform/cloud/onboarding/CloudLoginView.vue (2 hunks)
  • src/platform/cloud/onboarding/CloudSignupView.vue (3 hunks)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1 hunks)
  • src/platform/cloud/onboarding/UserCheckView.vue (1 hunks)
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1 hunks)
  • src/platform/cloud/onboarding/utils/previousFullPath.ts (1 hunks)
  • src/platform/cloud/subscription/components/PricingTable.vue (3 hunks)
  • src/platform/cloud/subscription/composables/useSubscription.ts (3 hunks)
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (1 hunks)
  • src/router.ts (2 hunks)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
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

src/**/*.{vue,ts}: Avoid using ref and watch together - use computed instead if possible
Do not add ref if a prop would suffice; do not add computed if the ref/prop directly would work; use watch only when computed won't accomplish the goal
Leverage VueUse functions for performance-enhancing styles

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.ts

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

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

src/**/*.ts: Extract complex type definitions that are inlined in multiple related places - name them for reuse
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.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

src/**/*.{ts,tsx,vue}: ESLint rules: Vue + TS rules, no floating promises, unused imports disallowed, i18n raw text restrictions in templates
Use es-toolkit for utility functions
Avoid mutable state - prefer immutability and assignment at point of declaration
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{js,ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively - no new JavaScript files

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx,vue,js}: Indent with 2 spaces, use single quotes, no trailing semicolons, line width 80 - see .prettierrc
Sort and group imports by plugin, run pnpm format before committing

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not use function expressions - use function declarations instead when possible

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.vue

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

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

src/**/*.vue: Vue 3 SFCs must use Composition API only - no Options API
Use <script setup lang="ts"> for component logic
Use Tailwind 4 utility classes for styling - avoid <style> blocks
Use cn() utility from @/utils/tailwindUtil to merge Tailwind class names - never use :class="[]" syntax
Never use the dark: Tailwind variant - use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use Vue 3.5+ TypeScript style default prop declaration with reactive destructuring - prefer useModel to prop/emit pairs, do not use withDefaults
Do not import Vue macros unnecessarily
Use vue-i18n in composition API for string literals - place translation entries in src/locales/en/main.json
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Avoid new usage of PrimeVue components

Files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.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/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
tests-ui/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

tests-ui/**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/Component test files must use pattern **/*.test.ts
Do not write change detector tests - do not just assert that defaults are certain values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing - do not write redundant tests
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
For mocking, leverage Vitest's utilities where possible
Keep module mocks contained - do not use global mutable state within test files, use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧠 Learnings (52)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 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/useSubscription.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue,js} : Sort and group imports by plugin, run `pnpm format` before committing

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : ESLint rules: Vue + TS rules, no floating promises, unused imports disallowed, i18n raw text restrictions in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue,js} : Indent with 2 spaces, use single quotes, no trailing semicolons, line width 80 - see `.prettierrc`

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{js,ts,tsx,vue} : Use TypeScript exclusively - no new JavaScript files

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Unit/Component test files must use pattern `**/*.test.ts`

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Quality gates must pass: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and relevant tests

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{vue,ts} : Do not add `ref` if a prop would suffice; do not add `computed` if the ref/prop directly would work; use `watch` only when `computed` won't accomplish the goal

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{vue,ts} : Avoid using `ref` and `watch` together - use `computed` instead if possible

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 computed properties with computed()

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Aim for behavioral coverage of critical and new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For mocking, leverage Vitest's utilities where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.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/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files, use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.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/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write change detector tests - do not just assert that defaults are certain values

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.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:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.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} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧬 Code graph analysis (2)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)
src/stores/firebaseAuthStore.ts (1)
  • FirebaseAuthStoreError (46-51)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1)
src/platform/cloud/onboarding/utils/previousFullPath.ts (1)
  • getSafePreviousFullPath (16-27)
🔇 Additional comments (21)
lint-staged.config.mjs (2)

1-2: LGTM!

The Node.js path module import uses the modern node: protocol prefix, which is the recommended approach.


3-10: LGTM! Typecheck runs on entire project.

The configuration correctly separates JavaScript and TypeScript/Vue file handling. Note that pnpm typecheck (line 8) runs on the entire project rather than just staged files, which is necessary since TypeScript type-checking requires full project context. This may add latency when staging many files, but is standard practice.

src/platform/cloud/onboarding/UserCheckView.vue (1)

84-84: LGTM: Consistent use of globalThis for location.

The change from window.location.href to globalThis.location.href aligns with the environment-agnostic pattern used elsewhere in this PR's onboarding views.

src/locales/en/main.json (1)

2101-2101: LGTM: Clear localization key for cloud navigation.

The new skipToCloudApp key provides user-facing text for quick navigation within cloud onboarding flows. The key name and value are clear and follow existing conventions.

src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1)

69-75: LGTM: Well-formed route for subscription redirect.

The new cloud-subscribe route is properly configured with authentication guard (requiresAuth: true) and lazy-loads the CloudSubscriptionRedirectView component. The route definition follows the existing patterns in the file.

tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1)

1-38: LGTM: Comprehensive test coverage for path safety.

The test suite provides excellent behavioral coverage of getSafePreviousFullPath, verifying:

  • Null return for missing values
  • Proper decoding of valid internal paths
  • Security: rejection of protocol-relative URLs (//evil.com)
  • Security: rejection of absolute external URLs
  • Error handling: rejection of malformed encodings

Test names are descriptive and follow vitest conventions.

src/router.ts (1)

152-178: LGTM: Clean previousFullPath preservation for post-login redirects.

The router now captures and encodes the current path before redirecting to cloud-login, enabling proper restoration after authentication. The root path ('/') is explicitly excluded from this mechanism, which is appropriate as it's the default landing page.

The implementation consistently applies the query object to both requiresAuth and general authentication checks, ensuring uniform redirect behavior.

src/platform/cloud/onboarding/CloudSignupView.vue (4)

103-103: LGTM: Import aligns with safe redirect functionality.

The import of getSafePreviousFullPath enables the component to safely restore the user's previous path after sign-up, integrating with the broader previousFullPath redirect mechanism introduced in this PR.


114-114: LGTM: Consistent globalThis usage.

Replacing window.isSecureContext with globalThis.isSecureContext maintains consistency with other onboarding views in this PR.


119-121: LGTM: Proper async navigation.

Making navigateToLogin async and awaiting router.push ensures navigation completes before control returns, which is the correct pattern for programmatic routing.


130-137: LGTM: Smart post-signup redirect with fallback.

The updated onSuccess flow now checks for a safe previous path and redirects there if available, falling back to the root. This improves UX by returning users to their intended destination (e.g., the subscription page they were visiting before being prompted to sign up).

src/platform/cloud/subscription/composables/useSubscription.ts (3)

39-39: LGTM: Initialization flag tracks subscription data readiness.

Adding isInitialized provides a clear signal to consumers about when subscription data has been fetched, enabling proper loading states and conditional rendering.


197-206: LGTM: Robust initialization tracking with try/finally.

The try/finally ensures isInitialized is set to true regardless of fetch success or failure, preventing indefinite loading states. Both login and logout paths properly update the flag.


246-246: LGTM: Exposing initialization state to consumers.

Adding isInitialized to the public API allows components to gate subscription-related UI until data is ready, improving user experience and preventing race conditions.

src/platform/cloud/onboarding/utils/previousFullPath.ts (1)

3-27: LGTM! Solid security implementation for redirect path validation.

The utility correctly prevents open redirect vulnerabilities by:

  • Safely decoding URI components with error handling
  • Rejecting protocol-relative URLs (//evil.com)
  • Validating that paths are relative and in-app only
  • Handling both string and array query parameters

The implementation follows security best practices for redirect validation.

src/platform/cloud/onboarding/CloudLoginView.vue (1)

87-114: LGTM! Clean integration of safe redirect logic.

The changes correctly integrate the previousFullPath utility:

  • Uses globalThis.isSecureContext for better portability than window
  • Properly awaits router operations
  • Conditionally redirects to the safe previous path when available
  • Falls back to the default cloud-user-check route when no previous path exists

The implementation enhances the post-login navigation flow without breaking existing behavior.

tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

1-150: LGTM! Comprehensive test coverage following best practices.

The test suite effectively covers all critical scenarios:

  • Invalid/missing tier redirects to home
  • Valid tier displays correct copy and initiates checkout
  • Active subscription opens billing portal instead of checkout
  • Array query parameter handling uses the first value

The implementation:

  • Uses Vitest utilities properly with vi.hoisted() for contained mocks
  • Tests behavioral outcomes rather than implementation details
  • Includes proper setup/teardown in beforeEach
  • Avoids redundant or change-detector tests

Based on coding guidelines for test files.

src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (2)

67-67: Hardcoded billing cycle should be configurable or use a constant.

The billing cycle is hardcoded to 'monthly' when calling performSubscriptionCheckout. This might be intentional for the initial redirect flow, but consider:

  1. If this should always be monthly, extract it as a named constant (e.g., const DEFAULT_BILLING_CYCLE: BillingCycle = 'monthly') for clarity
  2. If it should be configurable, consider reading from route query params or component props

Could you clarify whether the monthly billing cycle is the intended default for subscription redirects, or should this be configurable?


60-68: LGTM! Race condition properly addressed.

The subscription initialization check correctly prevents the race condition flagged in previous reviews. The component now waits for isInitialized before checking isActiveSubscription.value, ensuring users with existing subscriptions are properly directed to the billing portal instead of checkout.

src/platform/cloud/subscription/components/PricingTable.vue (2)

255-259: LGTM! Clean refactoring to centralized checkout utility.

The component successfully:

  • Imports shared types (TierKey, BillingCycle) from the utility, eliminating duplication
  • Delegates checkout logic to performSubscriptionCheckout
  • Maintains existing functionality while improving code reuse

This addresses the previous review comment about importing the shared TierKey type.


363-369: Good use of function declaration style.

The block-style function declaration for getButtonSeverity follows the repository's coding guidelines that prefer function declarations over function expressions for pure functions.

Based on learnings about preferring function declarations.

Comment on lines +3 to +4
import Button from 'primevue/button'
import ProgressSpinner from 'primevue/progressspinner'
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using custom button components instead of PrimeVue.

The coding guidelines specify "Avoid new usage of PrimeVue components" for Vue files. Consider using the repository's custom button components from @/components/button/ (such as TextButton.vue) instead of PrimeVue's Button component for consistency with the design system.

Note: ProgressSpinner might be acceptable if no custom alternative exists, but the skip button at Line 101-107 could use a custom component.

As per coding guidelines for src/**/*.vue files.

🤖 Prompt for AI Agents
In src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
3 to 4 and the skip button usage at lines 101 to 107, replace the PrimeVue
Button import/usage with the repository's custom button component (eg. import
TextButton from '@/components/button/TextButton.vue' or the appropriate export)
and update the template to use that component in place of <Button>, mapping
props/events to the custom component's API; keep ProgressSpinner if no custom
spinner exists and remove the unused PrimeVue Button import. Ensure the custom
button preserves the same styling/behavior (click handler, disabled state,
classes) as the current skip button.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 127ade7 and 2bb3723.

📒 Files selected for processing (1)
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
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/onboarding/CloudSubscriptionRedirectView.test.ts
tests-ui/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

tests-ui/**/*.test.ts: Write tests for all changes, especially bug fixes to catch future regressions
Unit/Component test files must use pattern **/*.test.ts
Do not write change detector tests - do not just assert that defaults are certain values
Do not write tests dependent on non-behavioral features like utility classes or styles
Be parsimonious in testing - do not write redundant tests
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
For mocking, leverage Vitest's utilities where possible
Keep module mocks contained - do not use global mutable state within test files, use vi.hoisted() if necessary
For Component testing, use Vue Test Utils and follow advice about making components easy to test
Aim for behavioral coverage of critical and new features

Files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (24)
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For Component testing, use Vue Test Utils and follow advice about making components easy to test

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : For mocking, leverage Vitest's utilities where possible

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Aim for behavioral coverage of critical and new features

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files, use `vi.hoisted()` if necessary

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Unit/Component test files must use pattern `**/*.test.ts`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Do not write change detector tests - do not just assert that defaults are certain values

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
⏰ 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 (5)
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (5)

1-7: LGTM!

Imports and the flushPromises utility follow standard patterns for Vue component testing with Vitest.


9-20: LGTM!

Router mocks are properly structured. The module-level mockQuery is reset in beforeEach, keeping test isolation intact.


22-55: LGTM!

Good use of vi.hoisted() for mocks that need hoisting. The mock patterns are clean and follow Vitest best practices per the coding guidelines.


57-93: LGTM!

The createI18nInstance provides focused minimal translations. The mountView helper is clean and properly awaits promise resolution.


139-147: LGTM!

Good test for the active subscription edge case—verifies billing portal is opened instead of checkout.

Comment on lines +115 to +137
test('shows subscription copy when subscriptionType is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })

// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')

// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')

// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)

// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Good behavioral coverage, but test name is inconsistent with implementation.

The test body correctly uses tier but the test name says "subscriptionType". Consider updating the test name for consistency.

🔎 Suggested fix:
-  test('shows subscription copy when subscriptionType is valid', async () => {
+  test('shows subscription copy when tier is valid', async () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('shows subscription copy when subscriptionType is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })
// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')
// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
test('shows subscription copy when tier is valid', async () => {
const { wrapper } = await mountView({ tier: 'creator' })
// Should not redirect to home
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
// Shows copy under logo
expect(wrapper.text()).toContain('Subscribe to Creator')
// Triggers checkout flow
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
// Shows loading affordances
expect(wrapper.findComponent({ name: 'ProgressSpinner' }).exists()).toBe(
true
)
const skipLink = wrapper.get('a[href="/"]')
expect(skipLink.text()).toContain('Skip to the cloud app')
})
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
around lines 115 to 137 the test title says "shows subscription copy when
subscriptionType is valid" but the implementation uses the prop `tier`; update
the test name to match the implementation — e.g., change the description string
to "shows subscription copy when tier is valid" (or similar wording that
references "tier" instead of "subscriptionType") so the test name accurately
reflects what it's testing.

Comment on lines +149 to +161
test('uses first value when subscriptionType is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})

expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Test name inconsistency with implementation.

The test body correctly uses tier but the test name says "subscriptionType". For consistency with the actual query parameter used:

🔎 Suggested fix:
-  test('uses first value when subscriptionType is an array', async () => {
+  test('uses first value when tier is an array', async () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('uses first value when subscriptionType is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
test('uses first value when tier is an array', async () => {
const { wrapper } = await mountView({
tier: ['creator', 'pro']
})
expect(mockRouterPush).not.toHaveBeenCalledWith('/')
expect(wrapper.text()).toContain('Subscribe to Creator')
expect(mockPerformSubscriptionCheckout).toHaveBeenCalledWith(
'creator',
'monthly',
false
)
})
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
around lines 149 to 161, the test name references "subscriptionType" but the
test uses the query parameter `tier`; update the test name to reflect the actual
parameter (e.g., "uses first value when tier is an array") so the description
matches the implementation and run the tests to confirm no other name mismatches
exist.

@Yourz Yourz force-pushed the feat--subscription-tier-button branch from 2bb3723 to fa582e7 Compare December 24, 2025 16:02
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (7)
lint-staged.config.mjs (1)

12-21: Function implementation is sound; shell escaping addressed in prior review.

The path handling and command construction are well-implemented. The use of path.relative() ensures ESLint resolves paths correctly, and the --cache flags optimize performance.

The shell escaping concern on line 15 has already been thoroughly addressed in the existing review comment above, which provides a detailed solution using proper shell-escape utilities.

src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)

47-53: Consider removing unnecessary Content-Type header.

The POST request has no body, so the Content-Type: application/json header is unnecessary and could potentially cause issues with some servers that validate content type against body presence.

🔎 Proposed fix
   const response = await fetch(
     `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${checkoutTier}`,
     {
       method: 'POST',
-      headers: { ...authHeader, 'Content-Type': 'application/json' }
+      headers: { ...authHeader }
     }
   )

31-87: Add dedicated unit tests for the subscription checkout utility.

This utility handles critical checkout logic including authentication validation, HTTP error handling with multiple fallback paths, JSON response parsing, and window navigation—none of which are tested directly. While CloudSubscriptionRedirectView uses this function, its tests do not cover the utility's edge cases. Consider adding tests for: auth failures, HTTP error responses with various formats, JSON parsing failures, and both navigation modes (new tab vs. redirect).

Based on learnings: Write tests for new features, follow existing test patterns, use Vitest mock functions.

tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (3)

109-113: Incorrect query parameter name persists.

This test still uses subscriptionType instead of tier, despite a past review comment (marked as addressed in commit 0df9c60). The component reads route.query.tier (line 37 of CloudSubscriptionRedirectView.vue), so this test is checking the wrong parameter.

🔎 Apply this fix:
   test('redirects to home when subscriptionType is invalid', async () => {
-    await mountView({ subscriptionType: 'invalid' })
+    await mountView({ tier: 'invalid' })

     expect(mockRouterPush).toHaveBeenCalledWith('/')
   })

115-137: Test name inconsistency with implementation.

The test name references "subscriptionType" but the test body correctly uses tier. This naming inconsistency persists despite being flagged in a previous review.

🔎 Suggested fix:
-  test('shows subscription copy when subscriptionType is valid', async () => {
+  test('shows subscription copy when tier is valid', async () => {

149-161: Test name inconsistency with implementation.

The test name references "subscriptionType" but the test correctly uses tier. Same naming issue as other tests.

🔎 Suggested fix:
-  test('uses first value when subscriptionType is an array', async () => {
+  test('uses first value when tier is an array', async () => {
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

3-3: Consider using custom button component.

As per coding guidelines, new usage of PrimeVue components should be avoided. The Button import on line 3 (used in template at lines 102-108) should be replaced with a custom button component from @/components/button/ (e.g., TextButton.vue).

Based on coding guidelines for src/**/*.vue.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bb3723 and fa582e7.

📒 Files selected for processing (14)
  • lint-staged.config.mjs
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧰 Additional context used
📓 Path-based instructions (15)
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/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/UserCheckView.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/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.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/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/UserCheckView.vue
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.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/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Use unit/component tests in tests-ui/ or src/**/*.test.ts with Vitest framework
For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files
Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧠 Learnings (61)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/router.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/UserCheckView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 computed properties with computed()

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue,js,jsx,json,css} : Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue} : Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Run quality gates before committing: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and ensure relevant tests pass; never use `--no-verify` to bypass

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-11T12:25:24.164Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:24.164Z
Learning: The project has CI automation that handles code formatting (pnpm format) automatically, so manual formatting suggestions should not be provided in code reviews for the Comfy-Org/ComfyUI_frontend repository.

Applied to files:

  • lint-staged.config.mjs
📚 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} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue} : Use sorted and grouped imports organized by plugin/source

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue} : Use TypeScript exclusively; do not write new JavaScript code

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx} : Minimize the surface area (exported values) of each module and composable

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • lint-staged.config.mjs
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.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/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions instead of other utility libraries

Applied to files:

  • lint-staged.config.mjs
📚 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/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.test.ts : Use unit/component tests in `tests-ui/` or `src/**/*.test.ts` with Vitest framework

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.test.ts : For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-22T21:36:38.905Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:38.905Z
Learning: In tests-ui feature tests, do not stub primitive UI components or customized primitives (e.g., Button). Instead, import and register the real components in the test setup so tests reflect production behavior and component API usage. This improves test reliability and fidelity. If a test must avoid rendering the full component, justify the approach and consider higher-level mocks or integration tests rather than replacing the primitive itself.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
🧬 Code graph analysis (2)
tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts (1)
src/platform/cloud/onboarding/utils/previousFullPath.ts (1)
  • getSafePreviousFullPath (16-27)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (3)
src/platform/cloud/subscription/constants/tierPricing.ts (1)
  • TierKey (5-5)
src/stores/firebaseAuthStore.ts (2)
  • useFirebaseAuthStore (58-480)
  • FirebaseAuthStoreError (51-56)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
⏰ 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: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect

@Yourz Yourz force-pushed the feat--subscription-tier-button branch from 09eb4fa to a83a7fd Compare January 5, 2026 16:13
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Fix all issues with AI Agents 🤖
In @src/platform/cloud/onboarding/CloudSignupView.vue:
- Around line 130-137: The navigation call uses incorrect syntax: router.push({
name: '/' }) treats '/' as a route name but it's a path; replace that call in
the CloudSignupView.vue flow (after the previousFullPath check) with a correct
push using the path or a real route name—e.g. call router.push('/') to navigate
to the root path, or use router.push({ name: 'ActualRouteName' }) if a named
root route exists; keep the surrounding logic (getSafePreviousFullPath,
router.replace) unchanged.

In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue:
- Around line 25-34: getTierDisplayName includes a 'founder' entry but the flow
intentionally excludes founder via validTierKeys; remove 'founder' from the
names mapping in getTierDisplayName (and any corresponding translation key
usage) so display names match allowed tiers, or if founder should be selectable
here, add 'founder' to the validTierKeys array and update pricing/selection
logic accordingly; update the getTierDisplayName function (and related
translation strings) or validTierKeys to make the set of supported tiers
consistent.

In @src/platform/cloud/subscription/components/PricingTable.vue:
- Around line 377-383: The function getButtonSeverity was converted to a
block-bodied function but should be an arrow function for consistency; replace
its declaration with a concise arrow form that returns 'secondary' when
isCurrentPlan(tier.key) is true, 'primary' when tier.key === 'creator', and
'secondary' otherwise, keeping the same type signature (tier:
PricingTierConfig): 'primary' | 'secondary' and preserving references to
isCurrentPlan and the 'creator' key.
♻️ Duplicate comments (5)
lint-staged.config.mjs (1)

12-21: Shell escaping concern already documented.

The defensive coding suggestion regarding shell escaping special characters in file paths has been comprehensively addressed in the previous review comment.

src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (2)

31-35: Add unit tests for the subscription checkout utility.

This utility handles critical checkout logic including authentication validation, HTTP error handling with multiple fallback paths, JSON response parsing, and window navigation—none of which are tested directly. Consider adding tests for:

  • Authentication failures (missing auth header)
  • HTTP error responses with various formats (JSON with message, plain text, empty body)
  • JSON parsing failures
  • Both navigation modes (new tab vs. redirect)

Run the following script to check if tests exist:

#!/bin/bash
# Description: Check for test coverage of subscriptionCheckoutUtil

echo "=== Search for test files referencing subscriptionCheckoutUtil ==="
rg -l 'subscriptionCheckoutUtil|performSubscriptionCheckout' --type=ts -g '*.test.ts' -g '*.spec.ts'

echo ""
echo "=== Check subscription test directory ==="
fd -t f '\.test\.ts$' src/platform/cloud/subscription/

Based on learnings, aim for behavioral coverage of critical and new features in unit tests.


47-53: Consider removing unnecessary Content-Type header.

The POST request includes Content-Type: application/json header (line 51) but has no request body. This header is unnecessary and could potentially cause validation issues with servers that check content type against body presence.

🔎 Proposed fix
   const response = await fetch(
     `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${checkoutTier}`,
     {
       method: 'POST',
-      headers: { ...authHeader, 'Content-Type': 'application/json' }
+      headers: { ...authHeader }
     }
   )
tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts (1)

109-113: Incorrect query parameter: test validates wrong behavior.

This test uses subscriptionType instead of tier, which means it passes because there's no valid tier present (not because it's testing invalid tier handling). The component reads route.query.tier, so the test should use that parameter name.

🔎 Fix the query parameter name
   test('redirects to home when subscriptionType is invalid', async () => {
-    await mountView({ subscriptionType: 'invalid' })
+    await mountView({ tier: 'invalid' })

     expect(mockRouterPush).toHaveBeenCalledWith('/')
   })
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

3-4: Consider replacing PrimeVue Button with custom component.

The coding guidelines specify avoiding new usage of PrimeVue components. Consider using the repository's custom button components from @/components/button/ (such as TextButton.vue) for consistency with the design system. ProgressSpinner may be acceptable if no custom alternative exists.

As per coding guidelines for src/**/*.vue files.

Also applies to: 102-108

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09eb4fa and a83a7fd.

📒 Files selected for processing (15)
  • lint-staged.config.mjs
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
🧰 Additional context used
📓 Path-based instructions (15)
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/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Use unit/component tests in tests-ui/ or src/**/*.test.ts with Vitest framework
For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files
Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.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/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.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/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.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/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.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/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.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/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.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/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
🧠 Learnings (66)
📓 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: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} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • lint-staged.config.mjs
📚 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/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Use unit/component tests in `tests-ui/` or `src/**/*.test.ts` with Vitest framework

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • lint-staged.config.mjs
📚 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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 mocks

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-22T21:36:38.905Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:38.905Z
Learning: In tests-ui feature tests, do not stub primitive UI components or customized primitives (e.g., Button). Instead, import and register the real components in the test setup so tests reflect production behavior and component API usage. This improves test reliability and fidelity. If a test must avoid rendering the full component, justify the approach and consider higher-level mocks or integration tests rather than replacing the primitive itself.

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/previousFullPath.test.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue,js,jsx,json,css} : Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Run quality gates before committing: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and ensure relevant tests pass; never use `--no-verify` to bypass

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-11T12:25:24.164Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:24.164Z
Learning: The project has CI automation that handles code formatting (pnpm format) automatically, so manual formatting suggestions should not be provided in code reviews for the Comfy-Org/ComfyUI_frontend repository.

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use sorted and grouped imports organized by plugin/source

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use TypeScript exclusively; do not write new JavaScript code

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx} : Minimize the surface area (exported values) of each module and composable

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions instead of other utility libraries

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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 computed properties with computed()

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.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: Check tests-ui/README.md for test guidelines

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.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:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/tests/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
🧬 Code graph analysis (1)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/stores/firebaseAuthStore.ts (1)
  • BillingPortalTargetTier (45-49)
⏰ 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: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect

Comment on lines 25 to 34
const getTierDisplayName = (tierKey: TierKey | null): string => {
if (!tierKey) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name'),
founder: t('subscription.tiers.founder.name')
}
return names[tierKey]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3243


🏁 Script executed:

cat src/platform/cloud/subscription/constants/tierPricing.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1695


🏁 Script executed:

rg -n "founder" src/platform/cloud/subscription/ --type=ts --type=vue -C 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

rg -n "founder" src/platform/cloud/subscription/ --type ts -C 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4575


🏁 Script executed:

rg -n "validTierKeys" src/platform/cloud/ --type ts -C 3

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

rg -n "validTierKeys" src/ --type ts -C 3

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

rg -n "founder" src/platform/cloud/onboarding/ --type ts -C 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


Remove 'founder' tier from display names or add to validTierKeys.

'founder' has a display name in getTierDisplayName() (line 31) but is excluded from the validTierKeys validation array (line 51). The tier is intentionally special—it's excluded from pricing tiers, tier ranking, and plan selection logic—indicating it should not be purchasable via this flow. Remove the 'founder' entry from lines 28-31 and its translation key to resolve the inconsistency, or document why it appears in the display names.

🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
25-34, getTierDisplayName includes a 'founder' entry but the flow intentionally
excludes founder via validTierKeys; remove 'founder' from the names mapping in
getTierDisplayName (and any corresponding translation key usage) so display
names match allowed tiers, or if founder should be selectable here, add
'founder' to the validTierKeys array and update pricing/selection logic
accordingly; update the getTierDisplayName function (and related translation
strings) or validTierKeys to make the set of supported tiers consistent.

Comment on lines +377 to +388
const getButtonSeverity = (
tier: PricingTierConfig
): 'primary' | 'secondary' => {
if (isCurrentPlan(tier.key)) return 'secondary'
if (tier.key === 'creator') return 'primary'
return 'secondary'
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using arrow function for consistency.

The getButtonSeverity function was changed from an arrow function to a block-bodied function declaration. While both work correctly, the arrow function form is more concise for simple ternary logic. However, if there's a codebase-wide preference for function declarations (as per coding guidelines), this change is acceptable.

💡 Alternative with arrow function (if preferred)
-const getButtonSeverity = (
-  tier: PricingTierConfig
-): 'primary' | 'secondary' => {
-  if (isCurrentPlan(tier.key)) return 'secondary'
-  if (tier.key === 'creator') return 'primary'
-  return 'secondary'
-}
+const getButtonSeverity = (tier: PricingTierConfig): 'primary' | 'secondary' =>
+  isCurrentPlan(tier.key) || tier.key !== 'creator' ? 'secondary' : 'primary'
🤖 Prompt for AI Agents
In @src/platform/cloud/subscription/components/PricingTable.vue around lines
377-383, The function getButtonSeverity was converted to a block-bodied function
but should be an arrow function for consistency; replace its declaration with a
concise arrow form that returns 'secondary' when isCurrentPlan(tier.key) is
true, 'primary' when tier.key === 'creator', and 'secondary' otherwise, keeping
the same type signature (tier: PricingTierConfig): 'primary' | 'secondary' and
preserving references to isCurrentPlan and the 'creator' key.

@Yourz Yourz force-pushed the feat--subscription-tier-button branch from a83a7fd to 19f24ff Compare January 6, 2026 12:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

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/onboarding/UserCheckView.vue (1)

87-102: Use vue-i18n for error messages instead of hardcoded strings.

The error messages at lines 94, 98, and 101 are hardcoded English strings. Per the coding guidelines, all string literals should use vue-i18n with the Composition API.

🔎 Proposed refactor to use i18n

First, add translation keys to src/locales/en/main.json:

{
  "cloudOnboarding": {
    "errors": {
      "network": "Connection problem. Please check your internet connection.",
      "timeout": "Request timed out. Please try again.",
      "generic": "Unable to check account status. Please try again."
    }
  }
}

Then update the computed property:

 const errorMessage = computed(() => {
   if (!error.value) return ''
 
   // Provide user-friendly error messages
   const errorStr = error.value.toString().toLowerCase()
 
   if (errorStr.includes('network') || errorStr.includes('fetch')) {
-    return 'Connection problem. Please check your internet connection.'
+    return $t('cloudOnboarding.errors.network')
   }
 
   if (errorStr.includes('timeout')) {
-    return 'Request timed out. Please try again.'
+    return $t('cloudOnboarding.errors.timeout')
   }
 
-  return 'Unable to check account status. Please try again.'
+  return $t('cloudOnboarding.errors.generic')
 })

As per coding guidelines, use vue-i18n in composition API for string literals.

🤖 Fix all issues with AI Agents
In @lint-staged.config.mjs:
- Around line 3-10: Update the lint-staged file patterns to include .jsx, .json,
and .css so they get Prettier/formatting on commit: extend the existing glob
entries referencing the current handlers (the function formatAndEslint used for
JS/TS/TSX/VUE files) to also match .jsx files, and add separate patterns for
.json and .css that run only the formatting step (not ESLint) to avoid running
linters that don't apply; ensure you reference the same formatAndEslint symbol
for applicable globs and only the formatter for JSON/CSS.

In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue:
- Around line 102-108: Replace the PrimeVue <Button> usage with the project's
custom text button component (e.g., TextButton) to follow the design system:
import TextButton from "@/components/button/TextButton.vue" in the component
script, change the template element from Button to TextButton, keep the
v-if="selectedTierKey" and the link behavior (pass href="/" or an equivalent
prop or attribute accepted by TextButton), and bind the displayed text using
t('cloudOnboarding.skipToCloudApp') so the button appearance and behavior match
the repo's standard.
- Line 68: The call to performSubscriptionCheckout currently hardcodes the
billing cycle as 'monthly'; parse the optional query parameter named "cycle"
(e.g., route.query.cycle or window.location.search) into a variable (e.g.,
cycle) and validate it against allowed values ('monthly'|'yearly'), defaulting
to 'yearly' if absent/invalid, then pass that variable instead of the hardcoded
'monthly' when calling performSubscriptionCheckout(tierKey, cycle, false).

In @src/platform/cloud/onboarding/UserCheckView.vue:
- Line 81: UserCheckView currently redirects unconditionally using
globalThis.location.href = '/' and uses hardcoded error messages; update the
redirect to respect any previousFullPath by using
getSafePreviousFullPath(route.query) (same pattern as
CloudLoginView/CloudSignupView) and navigate to that result instead of
hardcoding '/', and replace the three literal strings at the error handling
sites with i18n lookups via this.$t(...) using keys added to
src/locales/en/main.json (map the messages to sensible keys like
onboarding.connectionProblem, onboarding.requestTimeout,
onboarding.unableToCheckAccount) so the component uses this.$t('...') where the
current literals appear.

In @src/platform/cloud/onboarding/utils/previousFullPath.ts:
- Around line 3-9: Convert the file's arrow-function definitions to named
function declarations for consistency: replace the arrow function
decodeQueryParam with a function declaration function decodeQueryParam(...) {
... }, do the same for isSafeInternalRedirectPath and the third arrow function
in the file, and update exports to export the functions (e.g., export function
decodeQueryParam...) instead of exporting arrow constants.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a83a7fd and 19f24ff.

📒 Files selected for processing (13)
  • lint-staged.config.mjs
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
🧰 Additional context used
📓 Path-based instructions (13)
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/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.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/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/composables/auth/useFirebaseAuthActions.ts
  • src/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/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.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/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
🧠 Learnings (57)
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/router.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.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/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue,js,jsx,json,css} : Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Run quality gates before committing: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and ensure relevant tests pass; never use `--no-verify` to bypass

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-11T12:25:24.164Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:24.164Z
Learning: The project has CI automation that handles code formatting (pnpm format) automatically, so manual formatting suggestions should not be provided in code reviews for the Comfy-Org/ComfyUI_frontend repository.

Applied to files:

  • lint-staged.config.mjs
📚 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} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • lint-staged.config.mjs
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use sorted and grouped imports organized by plugin/source

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use TypeScript exclusively; do not write new JavaScript code

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx} : Minimize the surface area (exported values) of each module and composable

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions instead of other utility libraries

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.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/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Use unit/component tests in `tests-ui/` or `src/**/*.test.ts` with Vitest framework

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-13T05:34:22.209Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:22.209Z
Learning: In Playwright tests in the Comfy-Org/ComfyUI_frontend repository, the `toPass()` assertion method implements incremental backoff during retries, so increasing the timeout value (e.g., to 5000ms) is sufficient for handling async operations without being overly aggressive.

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting and follow the arrow anti-pattern

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-17T00:40:17.361Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:17.361Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, prefer pure function declarations (e.g., `function foo() { ... }`) over function expressions (e.g., `const foo = () => { ... }`) for pure functions, as function declarations are considered more functional than function expressions.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use function declarations instead of function expressions when possible

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
🧬 Code graph analysis (2)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/stores/firebaseAuthStore.ts (1)
  • BillingPortalTargetTier (45-49)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (3)
src/platform/cloud/subscription/constants/tierPricing.ts (1)
  • TierKey (5-5)
src/stores/firebaseAuthStore.ts (1)
  • FirebaseAuthStoreError (51-56)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
⏰ 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: lint-and-format
  • GitHub Check: collect
  • GitHub Check: test
🔇 Additional comments (21)
lint-staged.config.mjs (2)

1-10: LGTM! Clean configuration structure.

The lint-staged configuration follows best practices with appropriate tool ordering (prettier → oxlint → eslint) and logical separation between JavaScript and TypeScript files.


12-21: Function implementation is solid.

The path handling correctly uses path.relative for cross-platform compatibility, and the command structure appropriately chains prettier → oxlint → eslint with caching enabled for performance.

Note: The shell escaping consideration on line 15 has already been addressed in a previous review comment.

src/platform/cloud/subscription/composables/useSubscription.ts (2)

31-31: LGTM! Initialization tracking properly implemented.

The addition of isInitialized follows a solid pattern: it's set to true in the finally block after attempting to fetch subscription status (ensuring it's always set regardless of success/failure) and also on logout. This allows consumers to reliably know when the initial subscription check is complete.

Also applies to: 200-208, 249-249


81-81: Minor modernization: using globalThis instead of window.

This change from window.location.href to globalThis.location.href is a modern improvement for portability across JavaScript environments. In the browser context of Vue components, both work identically, so this is a safe, forward-looking change.

src/locales/en/main.json (1)

2123-2123: LGTM! Localization key properly added.

The new skipToCloudApp key follows the existing naming conventions and is correctly placed under the cloudOnboarding section. As per coding guidelines, using vue-i18n for all user-facing strings is the right approach.

src/platform/cloud/onboarding/onboardingCloudRoutes.ts (1)

69-75: LGTM! Subscription redirect route properly configured.

The new /cloud/subscribe route is well-structured:

  • Follows the existing naming pattern (cloud-subscribe)
  • Uses lazy loading for the component
  • Correctly applies requiresAuth: true meta guard
  • Integrates cleanly with the existing route hierarchy
src/router.ts (1)

152-178: LGTM! Clean implementation of previousFullPath preservation.

The query parameter logic correctly:

  • Excludes the root path to avoid redundant parameters
  • Encodes the full path using encodeURIComponent for safe transport
  • Applies consistently to both protected-route and web-based login redirects
  • Integrates with the getSafePreviousFullPath utility for safe decoding downstream

This enables users to return to their intended destination after authentication.

src/platform/cloud/onboarding/utils/previousFullPath.ts (2)

11-14: Security check effectively prevents protocol-relative URLs.

The validation path.startsWith('/') && !path.startsWith('//') correctly blocks protocol-relative URLs (e.g., //evil.com) while allowing valid in-app relative paths. This is appropriate for internal navigation after authentication.


16-27: Robust implementation with proper validation pipeline.

The function correctly:

  • Handles both single string and array query parameter values
  • Safely decodes with error handling
  • Validates before returning
  • Returns null for all failure cases, providing clear semantics
src/platform/cloud/onboarding/CloudLoginView.vue (4)

87-87: Clean integration of the previousFullPath utility.

The import correctly references the new utility function for safe path extraction.


95-95: Good update to use globalThis for broader compatibility.

Using globalThis.isSecureContext instead of window.isSecureContext is more portable and aligns with modern JavaScript standards.


99-101: Correctly preserves navigation context through signup flow.

Making the function async and preserving route.query ensures that the previousFullPath parameter is maintained if the user navigates to signup, enabling them to return to their intended destination after completing registration.


103-117: Well-structured redirect logic with safe fallback.

The onSuccess flow correctly:

  • Shows a success toast first
  • Attempts to restore the previous navigation target using the safe utility
  • Returns early after redirecting to prevent double navigation
  • Falls back to the standard cloud-user-check flow when no previous path exists

This provides a seamless user experience while maintaining security.

src/platform/cloud/subscription/components/PricingTable.vue (3)

377-383: Function declaration aligns with coding guidelines.

Converting to a function declaration follows the repository's preference for function declarations over arrow functions for pure functions. The logic remains correct and the change improves consistency.

Based on learnings, as per coding guidelines.


399-429: Excellent refactor to centralized subscription checkout.

Delegating to performSubscriptionCheckout reduces code duplication and centralizes the checkout flow. The error handling via wrapWithErrorHandlingAsync is maintained, and the parameters are correctly passed.


252-260: No action needed. TierKey has a single source of truth in src/platform/cloud/subscription/constants/tierPricing.ts and the current import from tierPricing constants is correct. The subscriptionCheckoutUtil file imports TierKey rather than exporting it, so there is no duplication or type drift risk.

Likely an incorrect or invalid review comment.

src/composables/auth/useFirebaseAuthActions.ts (2)

106-109: Non-breaking API enhancement with sensible default.

Adding the optional openInNewTab parameter with a default value of true maintains backward compatibility while enabling in-tab navigation when needed. The type signature correctly reflects the updated parameters.


118-122: Clean conditional navigation implementation.

The logic correctly:

  • Opens a new tab when openInNewTab is true (existing behavior)
  • Navigates in the current tab when false (new option)
  • Uses appropriate APIs: window.open for new tabs, globalThis.location.href for current tab navigation
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (3)

55-76: LGTM: Comprehensive error handling.

The error handling logic properly attempts JSON parsing first, falls back to text extraction, and finally uses HTTP status details. This graceful degradation ensures users receive meaningful error messages regardless of response format.


80-86: LGTM: Proper navigation handling.

The navigation logic correctly handles both new tab (window.open) and same-window redirect (globalThis.location.href) modes based on the openInNewTab parameter. Using globalThis.location.href is appropriate for the redirect case.


51-51: Remove unnecessary Content-Type header.

The POST request has no body, so the Content-Type: application/json header is unnecessary. Some servers may validate content type against body presence, potentially causing issues.

Proposed fix
   const response = await fetch(
     `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${checkoutTier}`,
     {
       method: 'POST',
-      headers: { ...authHeader, 'Content-Type': 'application/json' }
+      headers: { ...authHeader }
     }
   )

Likely an incorrect or invalid review comment.

Comment on lines +3 to +10
export default {
'./**/*.js': (stagedFiles) => formatAndEslint(stagedFiles),

'./**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
...formatAndEslint(stagedFiles),
'pnpm typecheck'
]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding handlers for .jsx, .json, and .css files.

Based on project conventions, Prettier formatting should apply to .jsx, .json, and .css files, but these aren't currently covered by the lint-staged configuration. If your project uses these file types, they won't be automatically formatted on commit.

🔎 Proposed configuration with additional file types
 export default {
   './**/*.js': (stagedFiles) => formatAndEslint(stagedFiles),
 
+  './**/*.jsx': (stagedFiles) => formatAndEslint(stagedFiles),
+
+  './**/*.{json,css}': (stagedFiles) => {
+    const relativePaths = stagedFiles.map((f) => path.relative(process.cwd(), f))
+    const joinedPaths = relativePaths.map((p) => `"${p}"`).join(' ')
+    return `pnpm exec prettier --cache --write ${joinedPaths}`
+  },
+
   './**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
     ...formatAndEslint(stagedFiles),
     'pnpm typecheck'
   ]
 }

Note: JSON and CSS files typically only need Prettier formatting, not ESLint/oxlint.

Based on learnings, the project's formatting standards should cover these file types.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default {
'./**/*.js': (stagedFiles) => formatAndEslint(stagedFiles),
'./**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
...formatAndEslint(stagedFiles),
'pnpm typecheck'
]
}
export default {
'./**/*.js': (stagedFiles) => formatAndEslint(stagedFiles),
'./**/*.jsx': (stagedFiles) => formatAndEslint(stagedFiles),
'./**/*.{json,css}': (stagedFiles) => {
const relativePaths = stagedFiles.map((f) => path.relative(process.cwd(), f))
const joinedPaths = relativePaths.map((p) => `"${p}"`).join(' ')
return `pnpm exec prettier --cache --write ${joinedPaths}`
},
'./**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
...formatAndEslint(stagedFiles),
'pnpm typecheck'
]
}
🤖 Prompt for AI Agents
In @lint-staged.config.mjs around lines 3 - 10, Update the lint-staged file
patterns to include .jsx, .json, and .css so they get Prettier/formatting on
commit: extend the existing glob entries referencing the current handlers (the
function formatAndEslint used for JS/TS/TSX/VUE files) to also match .jsx files,
and add separate patterns for .json and .css that run only the formatting step
(not ESLint) to avoid running linters that don't apply; ensure you reference the
same formatAndEslint symbol for applicable globs and only the formatter for
JSON/CSS.

Comment on lines +6 to +9
'./**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
...formatAndEslint(stagedFiles),
'pnpm typecheck'
]
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider the performance impact of project-wide typecheck.

The pnpm typecheck command runs on the entire project whenever any TypeScript/Vue file is staged, rather than checking only the staged files. For large codebases, this could slow down the commit process.

However, this is likely intentional since TypeScript type checking often requires full project context to catch type errors that might arise from changes. If typecheck performance becomes an issue, you could explore alternatives like tsc --incremental or checking only affected files, but the current approach is safer for correctness.

if (isActiveSubscription.value) {
await accessBillingPortal(undefined, false)
} else {
await performSubscriptionCheckout(tierKey, 'monthly', false)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3750


🏁 Script executed:

rg -n "performSubscriptionCheckout" src/platform/cloud/ --type ts --type vue -A 2 -B 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

rg -n "yearly\|annual" src/platform/cloud/ --type ts --type vue | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

fd "CloudSubscriptionRedirectView" src/

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 133


🏁 Script executed:

cat -n src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3279


🏁 Script executed:

rg "performSubscriptionCheckout|'yearly'|\"yearly\"" src/platform/cloud/ -A 1 -B 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 6437


🏁 Script executed:

cat -n src/platform/cloud/subscription/constants/tierPricing.ts | head -50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1903


🏁 Script executed:

cat -n src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue | grep -A 5 -B 5 "monthly"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 371


🏁 Script executed:

rg -n "CloudSubscriptionRedirectView" src/ --type vue -A 10 -B 2 | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

rg "CloudSubscriptionRedirectView" src/ -A 5 -B 2 | head -50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 707


🏁 Script executed:

rg "cloud-subscription-redirect" src/ -A 2 -B 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

cat -n src/platform/cloud/subscription/components/PricingTable.vue | sed -n '1,150p'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 6958


Add billing cycle query parameter support to enable yearly subscriptions.

The billing cycle is hardcoded as 'monthly' when calling performSubscriptionCheckout. Since yearly subscriptions are fully supported by the system (with 20% pricing discount) and preferred elsewhere (PricingTable defaults to yearly), this prevents users from accessing better pricing through this entry point. Parse an optional cycle query parameter (e.g., ?tier=pro&cycle=yearly) and pass it to the checkout function, or default to 'yearly' to match the primary pricing interface.

🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue at line 68,
The call to performSubscriptionCheckout currently hardcodes the billing cycle as
'monthly'; parse the optional query parameter named "cycle" (e.g.,
route.query.cycle or window.location.search) into a variable (e.g., cycle) and
validate it against allowed values ('monthly'|'yearly'), defaulting to 'yearly'
if absent/invalid, then pass that variable instead of the hardcoded 'monthly'
when calling performSubscriptionCheckout(tierKey, cycle, false).

// User is fully onboarded (active or whitelist check disabled)
window.location.href = '/'
globalThis.location.href = '/'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for getSafePreviousFullPath usage in onboarding views
echo "=== getSafePreviousFullPath usage ==="
rg -n 'getSafePreviousFullPath' --type=vue --type=ts -C3

# Search for previousFullPath query parameter handling
echo -e "\n=== previousFullPath query parameter handling ==="
rg -n 'previousFullPath' src/platform/cloud/onboarding/ --type=vue --type=ts -C3

# Check CloudLoginView and CloudSignupView navigation logic
echo -e "\n=== CloudLoginView.vue navigation logic ==="
rg -n 'location\.href|router\.(push|replace)' src/platform/cloud/onboarding/CloudLoginView.vue -C2

echo -e "\n=== CloudSignupView.vue navigation logic ==="
rg -n 'location\.href|router\.(push|replace)' src/platform/cloud/onboarding/CloudSignupView.vue -C2

# Check UserCheckView.vue for error messages and navigation
echo -e "\n=== UserCheckView.vue full content ==="
cat -n src/platform/cloud/onboarding/UserCheckView.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 5120


🏁 Script executed:

rg -n 'getSafePreviousFullPath' -C5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 8917


🏁 Script executed:

head -n 50 src/platform/cloud/onboarding/UserCheckView.vue | grep -E "import|useRoute|route"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 629


🏁 Script executed:

# Also check where UserCheckView is navigated to from
rg -n "cloud-user-check" src/platform/cloud/onboarding/ --type=vue --type=ts -B2 -A2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

# Check where UserCheckView is navigated to from
rg -n "cloud-user-check" src/platform/cloud/onboarding/ -B2 -A2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3012


🏁 Script executed:

# Check how CloudLoginView passes query parameters to cloud-user-check
rg -n "cloud-user-check" src/platform/cloud/onboarding/CloudLoginView.vue -B5 -A5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 359


🏁 Script executed:

# Check if previousFullPath should be passed through to UserCheckView
rg -n "previousFullPath.*query" src/platform/cloud/onboarding/ -C3

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1151


Consider whether UserCheckView should check for previousFullPath query parameter to align with other onboarding views.

CloudLoginView and CloudSignupView both check getSafePreviousFullPath(route.query) to restore user navigation context. However, UserCheckView navigates to '/' without checking for this parameter. This is technically consistent with the current navigation flow (CloudLoginView doesn't pass the query when navigating to 'cloud-user-check'), but it's worth verifying whether the final onboarding completion should preserve the user's original destination if one was passed through the authentication flow.

Additionally, hardcoded error messages at lines 94, 98, and 101 violate the i18n guideline. These strings should use $t() with keys in src/locales/en/main.json:

  • 'Connection problem. Please check your internet connection.'
  • 'Request timed out. Please try again.'
  • 'Unable to check account status. Please try again.'
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/UserCheckView.vue at line 81, UserCheckView
currently redirects unconditionally using globalThis.location.href = '/' and
uses hardcoded error messages; update the redirect to respect any
previousFullPath by using getSafePreviousFullPath(route.query) (same pattern as
CloudLoginView/CloudSignupView) and navigate to that result instead of
hardcoding '/', and replace the three literal strings at the error handling
sites with i18n lookups via this.$t(...) using keys added to
src/locales/en/main.json (map the messages to sensible keys like
onboarding.connectionProblem, onboarding.requestTimeout,
onboarding.unableToCheckAccount) so the component uses this.$t('...') where the
current literals appear.

Comment on lines +3 to +9
const decodeQueryParam = (value: string): string | null => {
try {
return decodeURIComponent(value)
} catch {
return null
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using function declaration for consistency.

Per coding guidelines, prefer function declarations over arrow functions for pure functions. This applies to all three functions in this file.

🔎 Optional refactor to function declarations
-const decodeQueryParam = (value: string): string | null => {
+function decodeQueryParam(value: string): string | null {
   try {
     return decodeURIComponent(value)
   } catch {
     return null
   }
 }

Apply similarly to isSafeInternalRedirectPath and update the export syntax:

-const isSafeInternalRedirectPath = (path: string): boolean => {
+function isSafeInternalRedirectPath(path: string): boolean {
   return path.startsWith('/') && !path.startsWith('//')
 }

-export const getSafePreviousFullPath = (
+export function getSafePreviousFullPath(
   query: LocationQuery
 ): string | null {
   const raw = query.previousFullPath
   const value = Array.isArray(raw) ? raw[0] : raw
   if (!value) return null

   const decoded = decodeQueryParam(value)
   if (!decoded) return null

   return isSafeInternalRedirectPath(decoded) ? decoded : null
 }

Based on learnings, as per coding guidelines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const decodeQueryParam = (value: string): string | null => {
try {
return decodeURIComponent(value)
} catch {
return null
}
}
function decodeQueryParam(value: string): string | null {
try {
return decodeURIComponent(value)
} catch {
return null
}
}
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/utils/previousFullPath.ts around lines 3 - 9,
Convert the file's arrow-function definitions to named function declarations for
consistency: replace the arrow function decodeQueryParam with a function
declaration function decodeQueryParam(...) { ... }, do the same for
isSafeInternalRedirectPath and the third arrow function in the file, and update
exports to export the functions (e.g., export function decodeQueryParam...)
instead of exporting arrow constants.

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue:
- Around line 71-74: The default billing cycle falls back to 'monthly' in the
validation block using validCycles and cycleParam; change the fallback to
'yearly' so that when cycleParam is missing or invalid (in the code around the
validCycles: BillingCycle[] declaration and the if-check that assigns cycleParam
= 'monthly') it assigns 'yearly' instead, keeping behavior consistent with the
PricingTable default and the 20% yearly discount.
- Around line 117-123: The code uses the PrimeVue Button component (Button)
which is disallowed; replace it with the repo's custom button (TextButton) and
wire up the same behavior: keep the v-if="selectedTierKey", use TextButton
instead of Button, pass the translated label t('cloudOnboarding.skipToCloudApp')
and the link target (use the custom button's href/to prop or slot equivalent to
render an anchor to "/"), and remove the PrimeVue import/registration while
adding/importing/registering TextButton in the component where Button was used.
- Around line 26-35: The computed tierDisplayName includes a 'founder' entry
that's not in validTierKeys; remove the 'founder' property from the names object
inside the tierDisplayName computed (which uses selectedTierKey) so the mapping
only contains standard, creator, and pro, keeping display names consistent with
validTierKeys.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19f24ff and b53af16.

📒 Files selected for processing (2)
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧰 Additional context used
📓 Path-based instructions (7)
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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
🧠 Learnings (26)
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2026-01-06T19:17:04.618Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:04.618Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
  • GitHub Check: storybook-build
🔇 Additional comments (6)
src/platform/cloud/onboarding/CloudSignupView.vue (4)

103-103: LGTM: Import of previousFullPath utility.

The import of getSafePreviousFullPath supports the new feature for preserving navigation context through authentication flows.


114-114: LGTM: Improved cross-platform compatibility.

Using globalThis.isSecureContext instead of window.isSecureContext is more portable and aligns with modern JavaScript standards.


119-121: LGTM: Async navigation to login.

The updated navigateToLogin function correctly uses async/await with proper named route navigation and query parameter preservation.


123-138: LGTM: Well-structured redirect logic with previous path preservation.

The updated onSuccess function correctly implements the previous path preservation feature:

  • Uses validated previousFullPath from query when available
  • router.replace() prevents polluting browser history with the redirect
  • Falls back to default onboarding flow with correct { path: '/' } syntax
  • Query parameter preservation maintains state throughout the flow
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (2)

16-22: LGTM!

The composable setup is clean and properly structured, correctly destructuring all needed values including the isInitialized flag that addresses the previously raised race condition concern.


87-89: LGTM!

Proper use of void operator for the fire-and-forget async call in the lifecycle hook, with error handling correctly wrapped upstream.

Comment on lines +26 to +35
const tierDisplayName = computed(() => {
if (!selectedTierKey.value) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name'),
founder: t('subscription.tiers.founder.name')
}
return names[selectedTierKey.value]
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove 'founder' tier from the display names mapping.

The tierDisplayName computed includes a 'founder' entry (line 32), but 'founder' is intentionally excluded from validTierKeys at line 61. Since this tier is not purchasable through this flow, its presence in the display names mapping is inconsistent and unnecessary. Remove the 'founder' entry from the names object.

🔧 Suggested fix
 const tierDisplayName = computed(() => {
   if (!selectedTierKey.value) return ''
   const names: Record<TierKey, string> = {
     standard: t('subscription.tiers.standard.name'),
     creator: t('subscription.tiers.creator.name'),
-    pro: t('subscription.tiers.pro.name'),
-    founder: t('subscription.tiers.founder.name')
+    pro: t('subscription.tiers.pro.name')
   }
   return names[selectedTierKey.value]
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const tierDisplayName = computed(() => {
if (!selectedTierKey.value) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name'),
founder: t('subscription.tiers.founder.name')
}
return names[selectedTierKey.value]
})
const tierDisplayName = computed(() => {
if (!selectedTierKey.value) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name')
}
return names[selectedTierKey.value]
})
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
26 - 35, The computed tierDisplayName includes a 'founder' entry that's not in
validTierKeys; remove the 'founder' property from the names object inside the
tierDisplayName computed (which uses selectedTierKey) so the mapping only
contains standard, creator, and pro, keeping display names consistent with
validTierKeys.

Comment on lines +71 to +74
const validCycles: BillingCycle[] = ['monthly', 'yearly']
if (!cycleParam || !(validCycles as string[]).includes(cycleParam)) {
cycleParam = 'monthly'
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider defaulting to 'yearly' billing cycle to match the primary pricing interface.

The cycle parameter is now properly parsed and validated (which addresses the main concern from previous reviews), but it defaults to 'monthly' when not provided or invalid. The primary pricing interface (PricingTable) defaults to 'yearly' with a 20% discount, which is the better value proposition for users. Consider changing the default from 'monthly' to 'yearly' for consistency.

💡 Optional enhancement
   const validCycles: BillingCycle[] = ['monthly', 'yearly']
   if (!cycleParam || !(validCycles as string[]).includes(cycleParam)) {
-    cycleParam = 'monthly'
+    cycleParam = 'yearly'
   }
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
71 - 74, The default billing cycle falls back to 'monthly' in the validation
block using validCycles and cycleParam; change the fallback to 'yearly' so that
when cycleParam is missing or invalid (in the code around the validCycles:
BillingCycle[] declaration and the if-check that assigns cycleParam = 'monthly')
it assigns 'yearly' instead, keeping behavior consistent with the PricingTable
default and the 20% yearly discount.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue:
- Around line 27-36: Remove the unused 'founder' entry from the tierDisplayName
computed mapping to match validTierKeys; locate the computed named
tierDisplayName and its names: Record<TierKey, string> mapping and delete the
founder: t('subscription.tiers.founder.name') entry so the mapping only contains
standard, creator, and pro (ensuring selectedTierKey and validTierKeys remain
consistent).
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b53af16 and 1f66696.

📒 Files selected for processing (1)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧰 Additional context used
📓 Path-based instructions (7)
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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧠 Learnings (25)
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2026-01-06T19:17:04.618Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:04.618Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🔇 Additional comments (1)
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (1)

121-127: PrimeVue Button usage flagged in previous reviews.

The PrimeVue Button component violates the coding guidelines that state "Avoid new usage of PrimeVue components." Previous reviews recommended using the repository's custom button components from @/components/button/ (e.g., TextButton.vue) for consistency with the design system.

As per coding guidelines for **/*.vue files.

Likely an incorrect or invalid review comment.

Comment on lines +27 to +35
const tierDisplayName = computed(() => {
if (!selectedTierKey.value) return ''
const names: Record<TierKey, string> = {
standard: t('subscription.tiers.standard.name'),
creator: t('subscription.tiers.creator.name'),
pro: t('subscription.tiers.pro.name'),
founder: t('subscription.tiers.founder.name')
}
return names[selectedTierKey.value]
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove 'founder' tier from tierDisplayName mapping.

The tierDisplayName computed includes 'founder' (line 33), but validTierKeys at line 61 only contains ['standard', 'creator', 'pro']. Since 'founder' cannot be selected through this flow, including it in the display names mapping is inconsistent and unnecessary.

🔧 Suggested fix
 const tierDisplayName = computed(() => {
   if (!selectedTierKey.value) return ''
   const names: Record<TierKey, string> = {
     standard: t('subscription.tiers.standard.name'),
     creator: t('subscription.tiers.creator.name'),
-    pro: t('subscription.tiers.pro.name'),
-    founder: t('subscription.tiers.founder.name')
+    pro: t('subscription.tiers.pro.name')
   }
   return names[selectedTierKey.value]
 })
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
27 - 36, Remove the unused 'founder' entry from the tierDisplayName computed
mapping to match validTierKeys; locate the computed named tierDisplayName and
its names: Record<TierKey, string> mapping and delete the founder:
t('subscription.tiers.founder.name') entry so the mapping only contains
standard, creator, and pro (ensuring selectedTierKey and validTierKeys remain
consistent).

@Yourz Yourz force-pushed the feat--subscription-tier-button branch from 1f66696 to f8d6d1f Compare January 8, 2026 01:54
@github-actions
Copy link

github-actions bot commented Jan 8, 2026

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

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/components/PricingTable.vue (1)

275-278: Consider consolidating duplicate getCheckoutTier logic.

The getCheckoutTier helper (lines 275-278) duplicates identical logic from subscriptionCheckoutUtil.ts (lines 13-16). Since this component uses the utility for new subscriptions but still needs the checkout tier for billing portal navigation (line 414), consider exporting getCheckoutTier from the utility and importing it here to maintain a single source of truth.

♻️ Suggested refactor

In subscriptionCheckoutUtil.ts:

-const getCheckoutTier = (
+export function getCheckoutTier(
   tierKey: TierKey,
   billingCycle: BillingCycle
-): CheckoutTier => (billingCycle === 'yearly' ? `${tierKey}-yearly` : tierKey)
+): CheckoutTier {
+  return billingCycle === 'yearly' ? `${tierKey}-yearly` : tierKey
+}

In PricingTable.vue:

 import {
-  performSubscriptionCheckout
+  performSubscriptionCheckout,
+  getCheckoutTier
 } from '@/platform/cloud/subscription/utils/subscriptionCheckoutUtil'

-type CheckoutTierKey = Exclude<TierKey, 'founder'>
-type CheckoutTier = CheckoutTierKey | `${CheckoutTierKey}-yearly`
-
-const getCheckoutTier = (
-  tierKey: CheckoutTierKey,
-  billingCycle: BillingCycle
-): CheckoutTier => (billingCycle === 'yearly' ? `${tierKey}-yearly` : tierKey)

Note: You'll need to align the type definitions if the utility's TierKey includes 'founder' but the component excludes it.

🤖 Fix all issues with AI agents
In @src/platform/cloud/onboarding/CloudLoginView.vue:
- Around line 99-101: The navigateToSignup function is marked async but only
calls await router.push() with no error handling or further awaits; remove the
unnecessary async/await by converting navigateToSignup to a synchronous function
and either return router.push(...) directly or call router.push(...) without
await (reference navigateToSignup and router.push to locate the code).

In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts:
- Around line 103-107: Update the test's description string to match the
component's query parameter name: change "redirects to home when
subscriptionType is missing" to "redirects to home when tier is missing" in the
test wrapping the call to mountView({}) and asserting mockRouterPush
toHaveBeenCalledWith('/'); keep the test body (mountView and mockRouterPush
assertion) unchanged so it stays consistent with the component's use of the
`tier` query parameter.

In @src/platform/cloud/onboarding/utils/previousFullPath.test.ts:
- Around line 1-38: Add the optional edge-case tests for getSafePreviousFullPath
in previousFullPath.test.ts: add a test for the array form of the
previousFullPath query (e.g., previousFullPath: [encodeURIComponent('/path'),
'other']) expecting '/path', a test for rejecting an empty string
(previousFullPath: '') expecting null, and a test preserving fragments
(previousFullPath: encodeURIComponent('/path#section') expecting
'/path#section'); only include these tests if the current implementation of
getSafePreviousFullPath already supports array inputs, empty-string handling,
and fragment preservation—otherwise update the implementation to handle those
cases before adding the tests.

In @src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts:
- Around line 55-76: Extract the triple-nested try/catch into a reusable async
helper (e.g., normalizeErrorMessage(response: Response): Promise<string>) that
attempts response.json() then response.text() then falls back to HTTP status
text, and replace the inline logic inside the checkout initiation block with a
call to that helper; ensure the thrown FirebaseAuthStoreError still uses
t('toastMessages.failedToInitiateSubscription', { error: await
normalizeErrorMessage(response) }) so behavior is unchanged and the
normalization logic is easier to read and unit test.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f66696 and f8d6d1f.

📒 Files selected for processing (15)
  • lint-staged.config.mjs
  • src/composables/auth/useFirebaseAuthActions.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
🧰 Additional context used
📓 Path-based instructions (14)
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/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.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/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.ts
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.ts
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/locales/en/main.json
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.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/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Use unit/component tests in tests-ui/ or src/**/*.test.ts with Vitest framework
For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files
Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.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/useSubscription.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.ts
**/**/use[A-Z]*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables using the pattern useXyz.ts

Files:

  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/composables/auth/useFirebaseAuthActions.ts
🧠 Learnings (72)
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/UserCheckView.vue
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/onboarding/CloudLoginView.vue
  • src/platform/cloud/onboarding/CloudSignupView.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 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} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Use unit/component tests in `tests-ui/` or `src/**/*.test.ts` with Vitest framework

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/router.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/composables/auth/useFirebaseAuthActions.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.test.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.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 Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/cloud/onboarding/onboardingCloudRoutes.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/platform/cloud/onboarding/onboardingCloudRoutes.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
  • src/platform/cloud/subscription/composables/useSubscription.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the `pnpm lint:fix` command

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue,js,jsx,json,css} : Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Run quality gates before committing: `pnpm lint`, `pnpm typecheck`, `pnpm knip`, and ensure relevant tests pass; never use `--no-verify` to bypass

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-11T12:25:24.164Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:24.164Z
Learning: The project has CI automation that handles code formatting (pnpm format) automatically, so manual formatting suggestions should not be provided in code reviews for the Comfy-Org/ComfyUI_frontend repository.

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Write code that is expressive and self-documenting; avoid redundant comments and clean as you go

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Do not use `any` type or `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use TypeScript exclusively; do not write new JavaScript code

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Implement proper error handling in code

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • lint-staged.config.mjs
📚 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: Be sure to typecheck when you're done making a series of code changes using `pnpm typecheck`

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-16T17:41:58.464Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T17:41:58.464Z
Learning: Run tests, typecheck, lint, and format checks during development workflow

Applied to files:

  • lint-staged.config.mjs
📚 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/**/*.ts : Use TypeScript for type safety

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use es-toolkit for utility functions

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use sorted and grouped imports organized by plugin/source

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx} : Minimize the surface area (exported values) of each module and composable

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use es-toolkit for utility functions instead of other utility libraries

Applied to files:

  • lint-staged.config.mjs
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 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/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-12-13T05:34:22.209Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:22.209Z
Learning: In Playwright tests in the Comfy-Org/ComfyUI_frontend repository, the `toPass()` assertion method implements incremental backoff during retries, so increasing the timeout value (e.g., to 5000ms) is sufficient for handling async operations without being overly aggressive.

Applied to files:

  • src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Use function declarations instead of function expressions when possible

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting and follow the arrow anti-pattern

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.ts
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/platform/cloud/onboarding/utils/previousFullPath.ts
📚 Learning: 2025-12-17T00:40:17.361Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:17.361Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, prefer pure function declarations (e.g., `function foo() { ... }`) over function expressions (e.g., `const foo = () => { ... }`) for pure functions, as function declarations are considered more functional than function expressions.

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
🧬 Code graph analysis (3)
src/platform/cloud/onboarding/utils/previousFullPath.test.ts (1)
src/platform/cloud/onboarding/utils/previousFullPath.ts (1)
  • getSafePreviousFullPath (16-27)
src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts (4)
src/platform/cloud/subscription/constants/tierPricing.ts (1)
  • TierKey (5-5)
src/platform/cloud/subscription/utils/subscriptionTierRank.ts (1)
  • BillingCycle (3-3)
src/stores/firebaseAuthStore.ts (2)
  • useFirebaseAuthStore (58-480)
  • FirebaseAuthStoreError (51-56)
src/config/comfyApi.ts (1)
  • getComfyApiBaseUrl (21-31)
src/composables/auth/useFirebaseAuthActions.ts (1)
src/stores/firebaseAuthStore.ts (1)
  • BillingPortalTargetTier (45-49)
⏰ 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: test
  • GitHub Check: collect
  • GitHub Check: setup

Comment on lines +99 to 101
const navigateToSignup = async () => {
await router.push({ name: 'cloud-signup', query: route.query })
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Async keyword unnecessary for navigateToSignup.

The function is now async but only contains a single await router.push(). Since there's no error handling or subsequent awaits, and Vue Router's push is typically fire-and-forget in this context, the async/await adds no value here.

♻️ Optional simplification
-const navigateToSignup = async () => {
-  await router.push({ name: 'cloud-signup', query: route.query })
+const navigateToSignup = () => {
+  void router.push({ name: 'cloud-signup', query: route.query })
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const navigateToSignup = async () => {
await router.push({ name: 'cloud-signup', query: route.query })
}
const navigateToSignup = () => {
void router.push({ name: 'cloud-signup', query: route.query })
}
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudLoginView.vue around lines 99 - 101, The
navigateToSignup function is marked async but only calls await router.push()
with no error handling or further awaits; remove the unnecessary async/await by
converting navigateToSignup to a synchronous function and either return
router.push(...) directly or call router.push(...) without await (reference
navigateToSignup and router.push to locate the code).

Comment on lines +103 to +107
test('redirects to home when subscriptionType is missing', async () => {
await mountView({})

expect(mockRouterPush).toHaveBeenCalledWith('/')
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Test description uses outdated parameter name.

The test description refers to "subscriptionType" but the component uses tier as the query parameter. Update for consistency with the implementation.

🔧 Suggested fix
-  test('redirects to home when subscriptionType is missing', async () => {
+  test('redirects to home when tier is missing', async () => {
     await mountView({})

     expect(mockRouterPush).toHaveBeenCalledWith('/')
   })
🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.test.ts around
lines 103 - 107, Update the test's description string to match the component's
query parameter name: change "redirects to home when subscriptionType is
missing" to "redirects to home when tier is missing" in the test wrapping the
call to mountView({}) and asserting mockRouterPush toHaveBeenCalledWith('/');
keep the test body (mountView and mockRouterPush assertion) unchanged so it
stays consistent with the component's use of the `tier` query parameter.

Comment on lines +1 to +38
import { describe, expect, test } from 'vitest'
import type { LocationQuery } from 'vue-router'

import { getSafePreviousFullPath } from './previousFullPath'

describe('getSafePreviousFullPath', () => {
test('returns null when missing', () => {
expect(getSafePreviousFullPath({})).toBeNull()
})

test('decodes and returns internal relative paths', () => {
const query: LocationQuery = {
previousFullPath: encodeURIComponent('/some/path?x=1')
}
expect(getSafePreviousFullPath(query)).toBe('/some/path?x=1')
})

test('rejects protocol-relative urls', () => {
const query: LocationQuery = {
previousFullPath: encodeURIComponent('//evil.com')
}
expect(getSafePreviousFullPath(query)).toBeNull()
})

test('rejects absolute external urls', () => {
const query: LocationQuery = {
previousFullPath: encodeURIComponent('https://evil.com/path')
}
expect(getSafePreviousFullPath(query)).toBeNull()
})

test('rejects malformed encodings', () => {
const query: LocationQuery = {
previousFullPath: '%E0%A4%A'
}
expect(getSafePreviousFullPath(query)).toBeNull()
})
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

LGTM! Comprehensive security-focused test coverage.

The test suite thoroughly validates the critical security aspects of getSafePreviousFullPath:

  • Protocol-relative URL prevention (//evil.com)
  • External URL rejection
  • Malformed encoding handling
  • Valid internal path decoding
Optional: Consider additional edge case coverage

The following edge cases might be worth testing if they're relevant to the implementation:

test('handles array form of query parameter', () => {
  const query: LocationQuery = {
    previousFullPath: [encodeURIComponent('/path'), 'other']
  }
  expect(getSafePreviousFullPath(query)).toBe('/path')
})

test('rejects empty string', () => {
  const query: LocationQuery = { previousFullPath: '' }
  expect(getSafePreviousFullPath(query)).toBeNull()
})

test('preserves fragments in internal paths', () => {
  const query: LocationQuery = {
    previousFullPath: encodeURIComponent('/path#section')
  }
  expect(getSafePreviousFullPath(query)).toBe('/path#section')
})

Only add these if the implementation explicitly handles these cases.

🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/utils/previousFullPath.test.ts around lines 1
- 38, Add the optional edge-case tests for getSafePreviousFullPath in
previousFullPath.test.ts: add a test for the array form of the previousFullPath
query (e.g., previousFullPath: [encodeURIComponent('/path'), 'other']) expecting
'/path', a test for rejecting an empty string (previousFullPath: '') expecting
null, and a test preserving fragments (previousFullPath:
encodeURIComponent('/path#section') expecting '/path#section'); only include
these tests if the current implementation of getSafePreviousFullPath already
supports array inputs, empty-string handling, and fragment
preservation—otherwise update the implementation to handle those cases before
adding the tests.

Comment on lines +55 to +76
if (!response.ok) {
let errorMessage = 'Failed to initiate checkout'
try {
const errorData = await response.json()
errorMessage = errorData.message || errorMessage
} catch {
// If JSON parsing fails, try to get text response or use HTTP status
try {
const errorText = await response.text()
errorMessage =
errorText || `HTTP ${response.status} ${response.statusText}`
} catch {
errorMessage = `HTTP ${response.status} ${response.statusText}`
}
}

throw new FirebaseAuthStoreError(
t('toastMessages.failedToInitiateSubscription', {
error: errorMessage
})
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider extracting error normalization logic.

The triple-nested try-catch for error response parsing is functional but complex. While this defensive approach handles JSON, text, and HTTP status fallbacks correctly, consider extracting it into a helper function for better readability and testability:

async function normalizeErrorMessage(response: Response): Promise<string> {
  try {
    const errorData = await response.json()
    return errorData.message || 'Failed to initiate checkout'
  } catch {
    try {
      const errorText = await response.text()
      return errorText || `HTTP ${response.status} ${response.statusText}`
    } catch {
      return `HTTP ${response.status} ${response.statusText}`
    }
  }
}

This would simplify the main function and make the error handling logic easier to unit test.

🤖 Prompt for AI Agents
In @src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts around
lines 55 - 76, Extract the triple-nested try/catch into a reusable async helper
(e.g., normalizeErrorMessage(response: Response): Promise<string>) that attempts
response.json() then response.text() then falls back to HTTP status text, and
replace the inline logic inside the checkout initiation block with a call to
that helper; ensure the thrown FirebaseAuthStoreError still uses
t('toastMessages.failedToInitiateSubscription', { error: await
normalizeErrorMessage(response) }) so behavior is unchanged and the
normalization logic is easier to read and unit test.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue:
- Around line 121-127: The Button currently renders as an anchor (Button with
as="a" href="/" and v-if="selectedTierKey") which causes a full-page reload;
replace it with SPA navigation by either wrapping the button with a RouterLink
(to="/") or handling click with the router (useRouter().push('/') or
@click="router.push('/')") when you switch to the custom button component, keep
the existing v-if="selectedTierKey" and
:label="t('cloudOnboarding.skipToCloudApp')" bindings intact so behavior and
accessibility remain the same.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8d6d1f and a3dcd29.

📒 Files selected for processing (1)
  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧰 Additional context used
📓 Path-based instructions (7)
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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🧠 Learnings (25)
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.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/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue
🔇 Additional comments (3)
src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue (3)

91-93: LGTM!

The lifecycle hook properly initiates the redirect on mount with appropriate async handling.


27-36: > Likely an incorrect or invalid review comment.


71-74: Consider defaulting to 'yearly' billing cycle.

The cycle parameter defaults to 'monthly' when not provided or invalid (line 73). Past reviews noted that the primary pricing interface (PricingTable) defaults to 'yearly' with a 20% discount, which provides better value. Consider changing the default to 'yearly' for consistency and to offer users the better pricing by default.

Likely an incorrect or invalid review comment.

Comment on lines +121 to +127
<Button
v-if="selectedTierKey"
as="a"
href="/"
link
:label="t('cloudOnboarding.skipToCloudApp')"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using router navigation for the skip link.

The skip button uses href="/" with as="a" to navigate to the home page (line 124). In a Vue SPA, programmatic navigation via router.push('/') is typically preferred over <a href> for internal routes, as it prevents full page reloads and maintains SPA behavior.

Once you replace the PrimeVue Button with a custom button component (as flagged in previous reviews), consider using @click="router.push('/')" or wrapping it with a <RouterLink to="/"> instead of rendering as an anchor tag.

🤖 Prompt for AI Agents
In @src/platform/cloud/onboarding/CloudSubscriptionRedirectView.vue around lines
121 - 127, The Button currently renders as an anchor (Button with as="a"
href="/" and v-if="selectedTierKey") which causes a full-page reload; replace it
with SPA navigation by either wrapping the button with a RouterLink (to="/") or
handling click with the router (useRouter().push('/') or
@click="router.push('/')") when you switch to the custom button component, keep
the existing v-if="selectedTierKey" and
:label="t('cloudOnboarding.skipToCloudApp')" bindings intact so behavior and
accessibility remain the same.

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

Labels

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