Skip to content

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Dec 9, 2025

This PR changes the credits icons and tooltips based on state of the subscription_tiers_enabled feature flag.

When the flag is enabled (or undefined -- for local), the dollar icon is replaced with the lucide-component icon in UserCredit and node price badges (Partner Nodes), and a new tooltip row appears in CurrentUserPopover displaying "Credits have been unified" with a detailed hover tooltip explaining the credit unification across Partner Nodes and Cloud workflows.

image

Related:

┆Issue is synchronized with this Notion page by Unito

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 9, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

📝 Walkthrough

Walkthrough

Adds a subscription_tiers_enabled remote flag and a subscriptionTiersEnabled getter in useFeatureFlags; components and badge logic now branch on that flag to render image-based icons (with size/bg handling) or fallback unicode glyphs; litegraph icon/badge types updated and localization adds unified-credits text.

Changes

Cohort / File(s) Summary
Feature flag & composable
src/composables/useFeatureFlags.ts
Adds ServerFeatureFlag.SUBSCRIPTION_TIERS_ENABLED and exposes flags.subscriptionTiersEnabled (resolves remoteConfig then server flag).
Components — UI & templates
src/components/common/UserCredit.vue, src/components/topbar/CurrentUserPopover.vue, src/renderer/extensions/vueNodes/components/NodeHeader.vue
Import useFeatureFlags and branch rendering on flags.subscriptionTiersEnabled; replace static icon usage with conditional image vs unicode/icon-slot rendering; add gated unified-credits block in popover.
Price badge logic
src/composables/node/usePriceBadge.ts
Reads flags.subscriptionTiersEnabled; when enabled returns image-based badge (shared SVG/component icon, fixed size and theme-aware colors) and updates credit-badge detection; otherwise retains unicode/PrimeIcons badge behavior.
Litegraph — icon model
src/lib/litegraph/src/LGraphIcon.ts
Makes unicode optional, adds image?: HTMLImageElement and size fields; constructor and draw logic now support image-based rendering (optional bgColor) and preserve unicode path.
Litegraph — badge layout
src/lib/litegraph/src/LGraphBadge.ts
getWidth and draw now differentiate image-based icons (icon.image, icon.size) from unicode glyphs when measuring and positioning.
Remote config types
src/platform/remoteConfig/types.ts
Adds optional subscription_tiers_enabled?: boolean to RemoteConfig.
Localization
src/locales/en/main.json
Adds credits.details.unified with message and multi-line tooltip about unified credits and conversion/learn-more link.

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch credits/tooltips

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8102d99 and cc17525.

📒 Files selected for processing (3)
  • src/composables/useFeatureFlags.ts (2 hunks)
  • src/lib/litegraph/src/LGraphIcon.ts (2 hunks)
  • src/platform/remoteConfig/types.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

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.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: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.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}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

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
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
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
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphIcon.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/useFeatureFlags.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/useFeatureFlags.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/composables/useFeatureFlags.ts
src/composables/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts

Files:

  • src/composables/useFeatureFlags.ts
🧠 Learnings (5)
📚 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/remoteConfig/types.ts
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.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} : 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/lib/litegraph/src/LGraphIcon.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/lib/litegraph/src/LGraphIcon.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} : When writing methods, prefer returning idiomatic JavaScript `undefined` over `null`

Applied to files:

  • src/lib/litegraph/src/LGraphIcon.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} : Prefer single line `if` syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement

Applied to files:

  • src/lib/litegraph/src/LGraphIcon.ts
🧬 Code graph analysis (1)
src/composables/useFeatureFlags.ts (2)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1289-1289)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (4)
src/platform/remoteConfig/types.ts (1)

28-41: RemoteConfig flag addition is consistent and well-typed.

subscription_tiers_enabled?: boolean matches existing remote flag conventions (optional, snake_case) and lines up with useFeatureFlags usage; no changes needed here.

src/composables/useFeatureFlags.ts (2)

9-17: ServerFeatureFlag enum extension looks consistent.

SUBSCRIPTION_TIERS_ENABLED = 'subscription_tiers_enabled' follows the existing naming and wiring pattern; no issues from a typing or API-shape standpoint.


53-69: Confirm the intended default behavior for subscriptionTiersEnabled in local/dev environments.

The getter correctly follows the "remoteConfig first, websocket flag fallback" pattern. However, the false default means the feature is disabled by default until explicitly enabled—effectively an opt-in pattern. This is consistent with other new features (modelUploadButtonEnabled, assetUpdateOptionsEnabled, privateModelsEnabled), all using the same conservative approach.

Given that this is a paid feature, verify whether:

  • "missing flag ⇒ disabled" (current behavior with false default) is the intended design, or
  • "missing flag ⇒ enabled" (alternative, requiring removal of the false default and mapping undefined to true)

All usages of subscriptionTiersEnabled (in CurrentUserPopover, NodeHeader, UserCredit, and usePriceBadge) treat it as a simple boolean toggle, so the choice affects whether legacy credit UI or subscription tier UI displays by default.

src/lib/litegraph/src/LGraphIcon.ts (1)

1-48: Icon options/constructor wiring for image + size looks solid.

Making unicode optional, adding image and size, and defaulting size with size ?? fontSize avoid the prior “0 treated as unset” issue while keeping the constructor aligned with LGraphIconOptions. This extension is type-safe and backwards-compatible.


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 9, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/09/2025, 09:37:49 AM UTC

📈 Summary

  • Total Tests: 487
  • Passed: 465 ✅
  • Failed: 0
  • Flaky: 13 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

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

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

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/09/2025, 09:29:17 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

Bundle Size Report

Summary

  • Raw size: 17.1 MB baseline 17.1 MB — 🔴 +4.31 kB
  • Gzip: 3.38 MB baseline 3.38 MB — 🔴 +1.04 kB
  • Brotli: 2.59 MB baseline 2.59 MB — 🔴 +505 B
  • Bundles: 97 current • 97 baseline • 37 added / 37 removed

Category Glance
App Entry Points 🔴 +3.37 kB (3.21 MB) · Graph Workspace 🔴 +2.28 kB (985 kB) · UI Components 🟢 -1.35 kB (176 kB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Panels & Settings ⚪ 0 B (298 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.21 MB (baseline 3.21 MB) • 🔴 +3.37 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CG0lPWQF.js (new) 2.99 MB 🔴 +2.99 MB 🔴 +621 kB 🔴 +472 kB
assets/index-DV_tmGFb.js (removed) 2.98 MB 🟢 -2.98 MB 🟢 -620 kB 🟢 -471 kB
assets/index-9WJk1bRf.js (removed) 223 kB 🟢 -223 kB 🟢 -47.6 kB 🟢 -39.3 kB
assets/index-niSB90AD.js (new) 223 kB 🔴 +223 kB 🔴 +47.6 kB 🔴 +39.3 kB
assets/index-CASNIcLe.js (removed) 345 B 🟢 -345 B 🟢 -244 B 🟢 -237 B
assets/index-zxXM_fga.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +199 B

Status: 3 added / 3 removed

Graph Workspace — 985 kB (baseline 983 kB) • 🔴 +2.28 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-6_dA8Bjs.js (new) 985 kB 🔴 +985 kB 🔴 +190 kB 🔴 +145 kB
assets/GraphView-RysQ4hzP.js (removed) 983 kB 🟢 -983 kB 🟢 -190 kB 🟢 -145 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

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

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-CwNJl-m9.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.49 kB
assets/CreditsPanel-DonVt6SG.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/KeybindingPanel-eFVuCvD6.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.01 kB
assets/KeybindingPanel-jkvSx8I_.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/ExtensionPanel-BApyhPlQ.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.58 kB 🟢 -2.26 kB
assets/ExtensionPanel-CTN_wFN4.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.58 kB 🔴 +2.26 kB
assets/AboutPanel-CTy-Bj40.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-Dz6i2Ysi.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-BkxfOqLN.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/ServerConfigPanel-D6mKkCPw.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/UserPanel-CilKTWl4.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-DGrOrui5.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 176 kB (baseline 177 kB) • 🟢 -1.35 kB

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-BTiiF-rD.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.31 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-CuM-s88R.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.31 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-D-qN-cc1.js (new) 48.1 kB 🔴 +48.1 kB 🔴 +10.4 kB 🔴 +8.99 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DNWyb32o.js (removed) 48.1 kB 🟢 -48.1 kB 🟢 -10.4 kB 🟢 -9.02 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-CHV7dKyO.js (removed) 47.3 kB 🟢 -47.3 kB 🟢 -10.6 kB 🟢 -9.29 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-DpqQHCyg.js (new) 46 kB 🔴 +46 kB 🔴 +10.3 kB 🔴 +8.99 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CHqMIZWw.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.97 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-w4_Y9ST1.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/ComfyQueueButton-DVE_fAYy.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.21 kB
assets/ComfyQueueButton-UDDFOKvs.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/MediaTitle.vue_vue_type_script_setup_true_lang-DT6PoKUH.js (removed) 897 B 🟢 -897 B 🟢 -502 B 🟢 -436 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-DYdOv0gk.js (new) 897 B 🔴 +897 B 🔴 +504 B 🔴 +444 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-BkTMAMst.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CMkR1knv.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-6ZIklFyS.js 2.26 kB 2.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 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-Bh2HSEKD.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/keybindingService-DLrn_d9C.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.57 kB
assets/audioService-B3DIVEBf.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +963 B 🔴 +828 B
assets/audioService-B9WOZ90P.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -826 B
assets/serverConfigStore-L3qzi_1Z.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CteiKSq4.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -651 B 🟢 -546 B
assets/audioUtils-VtLHPxAX.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +549 B
assets/mathUtil-CD4DsosH.js 1.32 kB 1.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DJFoH6N_.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BZV8aGUB.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-CkvDSSUa.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-Cmu0_BY4.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Bz22sFex.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio--aVBFR44.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.24 kB 🟢 -4.63 kB
assets/WidgetRecordAudio-DM9crjjB.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.64 kB
assets/AudioPreviewPlayer-CGg77HF5.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.05 kB
assets/AudioPreviewPlayer-DCYcO8n7.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/WidgetGalleria-CiuHTAKS.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.45 kB 🟢 -1.3 kB
assets/WidgetGalleria-vuOecqZ0.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.31 kB
assets/WidgetColorPicker-Be_nUsd7.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-CVx7Sm-4.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetMarkdown-B3wHKZTI.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetMarkdown-DhV92cYK.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.13 kB
assets/WidgetTextarea-B1zrANMY.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.17 kB 🟢 -1.04 kB
assets/WidgetTextarea-Cz7buTCE.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.17 kB 🔴 +1.04 kB
assets/WidgetAudioUI-C7_hLd6g.js (removed) 2.85 kB 🟢 -2.85 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/WidgetAudioUI-sH6fGcss.js (new) 2.85 kB 🔴 +2.85 kB 🔴 +1.17 kB 🔴 +1.05 kB
assets/WidgetInputText-DOfMvA9U.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -915 B 🟢 -847 B
assets/WidgetInputText-V9e9UDlm.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +916 B 🔴 +832 B
assets/MediaImageBottom-BkAVyIK7.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -740 B 🟢 -649 B
assets/MediaImageBottom-C2hNwicE.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +742 B 🔴 +650 B
assets/MediaAudioBottom-CtWixugM.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +741 B 🔴 +658 B
assets/MediaAudioBottom-t0Psmp6s.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -740 B 🟢 -656 B
assets/MediaVideoBottom-B7p0q0U7.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -740 B 🟢 -655 B
assets/MediaVideoBottom-BU0aV0WJ.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +740 B 🔴 +658 B
assets/Media3DBottom-CxZOv8cE.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +733 B 🔴 +652 B
assets/Media3DBottom-m8gpgq6E.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -732 B 🟢 -651 B
assets/Media3DTop-BXp4d2Qx.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +762 B 🔴 +652 B
assets/Media3DTop-WWka41-f.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -761 B 🟢 -650 B
assets/WidgetSelect-b-mThute.js (removed) 655 B 🟢 -655 B 🟢 -343 B 🟢 -287 B
assets/WidgetSelect-DWELllKo.js (new) 655 B 🔴 +655 B 🔴 +343 B 🔴 +287 B
assets/WidgetInputNumber-DT1L2Ihg.js (removed) 595 B 🟢 -595 B 🟢 -330 B 🟢 -277 B
assets/WidgetInputNumber-hfTykVM-.js (new) 595 B 🔴 +595 B 🔴 +330 B 🔴 +276 B
assets/Load3D-DjR7cFh3.js (removed) 424 B 🟢 -424 B 🟢 -265 B 🟢 -223 B
assets/Load3D-T5040tlT.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +224 B
assets/WidgetLegacy-BAK44Zbx.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -196 B
assets/WidgetLegacy-BbQ3onth.js (new) 364 B 🔴 +364 B 🔴 +237 B 🔴 +217 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BPDWO8-i.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-BtY1hGDO.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-ehTZdDBw.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BC3OlaIn.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BsqN8-W1.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CK2saYDx.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cm5kR4Hi.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CMrh-uxB.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DlUIOit1.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DNu_xoP2.js 282 kB 282 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DpcvlpZe.js 303 kB 303 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-IyjOYIl-.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-DhnqAfj7.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-DFci1T8T.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-D6b0vE-q.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 17 added / 17 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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/composables/node/usePriceBadge.ts (1)

19-19: Missing i18n for user-facing string.

The string "Partner Nodes x " is displayed in the UI but is not internationalized.

As per coding guidelines, use vue-i18n for all user-facing strings. Apply this diff:

+import { useI18n } from 'vue-i18n'

 export const usePriceBadge = () => {
   const { flags } = useFeatureFlags()
+  const { t } = useI18n()
   function updateSubgraphCredits(node: LGraphNode) {
     if (!node.isSubgraphNode()) return
     node.badges = node.badges.filter((b) => !isCreditsBadge(b))
     const newBadges = collectCreditsBadges(node.subgraph)
     if (newBadges.length > 1) {
-      node.badges.push(getCreditsBadge('Partner Nodes x ' + newBadges.length))
+      node.badges.push(getCreditsBadge(t('partnerNodesCount', { count: newBadges.length })))
     } else {
       node.badges.push(...newBadges)
     }
   }

Add to src/locales/en/main.json:

"partnerNodesCount": "Partner Nodes x {count}"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0a99a0 and bd8b4b4.

📒 Files selected for processing (7)
  • src/components/common/UserCredit.vue (3 hunks)
  • src/components/topbar/CurrentUserPopover.vue (3 hunks)
  • src/composables/node/usePriceBadge.ts (2 hunks)
  • src/composables/useFeatureFlags.ts (2 hunks)
  • src/lib/litegraph/src/LGraphBadge.ts (2 hunks)
  • src/lib/litegraph/src/LGraphIcon.ts (2 hunks)
  • src/locales/en/main.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (18)
src/**/*.vue

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

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

Files:

  • src/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.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}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
src/components/**/*.vue

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

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

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
src/components/**/*.{vue,css}

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

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

Files:

  • src/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
src/components/**/*.{vue,ts,js}

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

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

Files:

  • src/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
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/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.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: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/composables/useFeatureFlags.ts
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.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/useFeatureFlags.ts
  • src/composables/node/usePriceBadge.ts
src/composables/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts

Files:

  • src/composables/useFeatureFlags.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

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
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
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
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
🧠 Learnings (15)
📚 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/components/common/UserCredit.vue
  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components

Applied to files:

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

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Implement computed properties with `computed()` instead of using `ref` and `watch`

Applied to files:

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

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-12-09T04:35:40.491Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:40.491Z
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-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/composables/useFeatureFlags.ts
  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/lib/litegraph/src/LGraphIcon.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/composables/node/usePriceBadge.ts
  • src/lib/litegraph/src/LGraphIcon.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} : The `size` and `pos` properties of `Rectangle` share the same array buffer (`subarray`); they may be used to set the rectangle's size and position

Applied to files:

  • src/lib/litegraph/src/LGraphBadge.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} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/lib/litegraph/src/LGraphIcon.ts
🧬 Code graph analysis (2)
src/composables/useFeatureFlags.ts (1)
src/scripts/api.ts (1)
  • api (1289-1289)
src/composables/node/usePriceBadge.ts (3)
src/composables/useFeatureFlags.ts (1)
  • useFeatureFlags (22-75)
src/lib/litegraph/src/LGraphBadge.ts (1)
  • LGraphBadge (22-128)
src/utils/colorUtil.ts (1)
  • adjustColor (345-352)
⏰ 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 (10)
src/components/common/UserCredit.vue (2)

10-20: LGTM! Clean conditional icon rendering.

The feature-flag driven icon switching is well implemented. The use of the #icon slot template to conditionally render either the lucide icon or PrimeIcons dollar icon is a clean approach.


30-39: Feature flag integration looks correct.

The useFeatureFlags composable is properly imported and destructured. The reactive flags object will correctly update the icon when the feature flag state changes.

src/components/topbar/CurrentUserPopover.vue (2)

29-44: LGTM! Well-implemented unified credits notice.

The feature-flag gated UI block is correctly implemented:

  • Proper use of v-if with flags.subscriptionTiersEnabled
  • i18n correctly used for both tooltip ($t('credits.unified.tooltip')) and message ($t('credits.unified.message'))
  • Help icon with cursor-help provides good UX affordance

121-143: Feature flag composable integration is correct.

The import and usage of useFeatureFlags follows the established pattern in the codebase.

src/composables/useFeatureFlags.ts (2)

15-16: New feature flag enum member correctly added.

The enum value follows the established naming convention with snake_case for the string value.


59-65: Verify if remoteConfig fallback is intentionally omitted.

Other similar flags like modelUploadButtonEnabled and assetUpdateOptionsEnabled check remoteConfig.value first before falling back to api.getServerFeature. This flag only checks the server feature flag directly.

If this is intentional (e.g., this flag is only controlled server-side), the implementation is correct. Otherwise, consider adding the remoteConfig check for consistency:

 get subscriptionTiersEnabled() {
-  return api.getServerFeature(
-    ServerFeatureFlag.SUBSCRIPTION_TIERS_ENABLED,
-    false
+  return (
+    remoteConfig.value.subscription_tiers_enabled ??
+    api.getServerFeature(ServerFeatureFlag.SUBSCRIPTION_TIERS_ENABLED, false)
   )
 }
src/locales/en/main.json (1)

1844-1848: Locale entries added correctly.

The new credits.unified entries follow the established i18n patterns. The tooltip text uses \n for line breaks which should render correctly in the tooltip component.

Minor consideration: The tooltip mentions "Learn more here" but doesn't appear to include an actual hyperlink. If this is intended to be clickable, it would need HTML rendering support in the tooltip. If it's just informational text, it's fine as-is.

src/lib/litegraph/src/LGraphBadge.ts (1)

69-74: LGTM! Image-based icon width calculation.

The branching logic correctly handles both image-based and unicode-based icons:

  • Image mode: uses icon.size
  • Unicode mode: measures the actual text width

This aligns with the new LGraphIcon implementation.

src/lib/litegraph/src/LGraphIcon.ts (2)

1-12: LGTM! Interface properly extended for image support.

The LGraphIconOptions interface now correctly supports both rendering modes:

  • unicode made optional to allow image-only icons
  • image for HTMLImageElement-based rendering
  • size for controlling image dimensions

68-90: LGTM! Unicode rendering with proper context restoration.

The unicode branch correctly saves and restores all modified canvas context properties (font, textBaseline, textAlign, fillStyle), ensuring no side effects on subsequent drawing operations.

AustinMroz
AustinMroz previously approved these changes Dec 9, 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: 4

♻️ Duplicate comments (1)
src/composables/node/usePriceBadge.ts (1)

51-89: Refactor to eliminate code duplication.

The two branches share identical fgColor and bgColor logic for the badge itself. This was already flagged in a previous review.

Apply this diff to consolidate the shared logic:

   function getCreditsBadge(price: string): LGraphBadge {
     const isLightTheme = colorPaletteStore.completedActivePalette.light_theme
+    const badgeBgColor = isLightTheme
+      ? adjustColor('#8D6932', { lightness: 0.5 })
+      : '#8D6932'
+    const badgeFgColor =
+      colorPaletteStore.completedActivePalette.colors.litegraph_base
+        .BADGE_FG_COLOR
 
-    if (flags.subscriptionTiersEnabled) {
-      return new LGraphBadge({
-        text: price,
-        iconOptions: {
+    const iconOptions = flags.subscriptionTiersEnabled
+      ? {
           image: componentIconSvg,
           size: 8
-        },
-        fgColor:
-          colorPaletteStore.completedActivePalette.colors.litegraph_base
-            .BADGE_FG_COLOR,
-        bgColor: isLightTheme
-          ? adjustColor('#8D6932', { lightness: 0.5 })
-          : '#8D6932'
-      })
-    } else {
-      return new LGraphBadge({
-        text: price,
-        iconOptions: {
+        }
+      : {
           unicode: '\ue96b',
           fontFamily: 'PrimeIcons',
           color: isLightTheme
             ? adjustColor('#FABC25', { lightness: 0.5 })
             : '#FABC25',
           bgColor: isLightTheme
             ? adjustColor('#654020', { lightness: 0.5 })
             : '#654020',
           fontSize: 8
-        },
-        fgColor:
-          colorPaletteStore.completedActivePalette.colors.litegraph_base
-            .BADGE_FG_COLOR,
-        bgColor: isLightTheme
-          ? adjustColor('#8D6932', { lightness: 0.5 })
-          : '#8D6932'
-      })
-    }
+        }
+
+    return new LGraphBadge({
+      text: price,
+      iconOptions,
+      fgColor: badgeFgColor,
+      bgColor: badgeBgColor
+    })
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd8b4b4 and 3adbeb2.

📒 Files selected for processing (4)
  • src/components/topbar/CurrentUserPopover.vue (3 hunks)
  • src/composables/node/usePriceBadge.ts (2 hunks)
  • src/lib/litegraph/src/LGraphIcon.ts (2 hunks)
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue (3 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
src/**/*.vue

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

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
src/**/*.{vue,ts}

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

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.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}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/components/**/*.vue

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

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

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/topbar/CurrentUserPopover.vue
src/components/**/*.{vue,css}

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

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

Files:

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

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

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

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
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/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.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: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

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
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
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
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphIcon.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/node/usePriceBadge.ts
🧠 Learnings (9)
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.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/components/topbar/CurrentUserPopover.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/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/renderer/extensions/vueNodes/components/NodeHeader.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/lib/litegraph/src/LGraphIcon.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/lib/litegraph/src/LGraphIcon.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/lib/litegraph/src/LGraphIcon.ts
  • src/composables/node/usePriceBadge.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/composables/node/usePriceBadge.ts
🧬 Code graph analysis (1)
src/composables/node/usePriceBadge.ts (3)
src/composables/useFeatureFlags.ts (1)
  • useFeatureFlags (22-75)
src/lib/litegraph/src/LGraphBadge.ts (1)
  • LGraphBadge (22-128)
src/utils/colorUtil.ts (1)
  • adjustColor (345-352)
🔇 Additional comments (6)
src/components/topbar/CurrentUserPopover.vue (1)

121-143: Proper integration of feature flags composable.

The import and usage of useFeatureFlags follows the established pattern in the codebase. The flags object is correctly destructured and used reactively in the template.

src/renderer/extensions/vueNodes/components/NodeHeader.vue (2)

42-50: Clean conditional icon rendering.

The feature flag driven icon selection between icon-[lucide--component] and icon-[lucide--dollar-sign] is cleanly implemented using a ternary expression in the class binding.


107-139: Feature flag integration is consistent with codebase patterns.

Import and initialization of useFeatureFlags follows the established pattern used in other components.

src/composables/node/usePriceBadge.ts (1)

8-10: Module-level Image instantiation is appropriate for caching.

Creating the Image object at module scope ensures the SVG is loaded once and reused across all badge instances, which is efficient. The oklch color in the SVG matches the design requirement from the past review discussion.

src/lib/litegraph/src/LGraphIcon.ts (2)

54-69: Image rendering branch correctly preserves canvas state.

The image path now saves and restores ctx.fillStyle around the background circle fill, so later drawing isn’t accidentally affected. The use of iconSize/iconRadius and padding for centering also looks correct.


70-92: Unicode rendering branch is state‑safe; confirm image‑vs‑unicode priority.

The unicode path correctly saves/restores font, alignment, and fillStyle, matching the image branch’s goal of leaving the canvas state unchanged. The overall if (this.image) … else if (this.unicode) means image icons always take precedence when both are provided; if that matches the intended fallback behavior, this implementation is solid.

- Add subscription_tiers_enabled feature flag to control new UI elements
- Change dollar icon to lucide-component icon in UserCredit when flag enabled
- Add "Credits have been unified" tooltip row in CurrentUserPopover when flag enabled
- Update node price badges to use lucide-component SVG icon when flag enabled
- Extend LGraphIcon system to support both Unicode fonts and SVG images via ctx.drawImage()
- Maintain backward compatibility - all existing behavior preserved when flag disabled
- Add detailed tooltip explaining credit unification
- Include information about Partner Nodes and Cloud workflows
- Mention existing balance conversion
- Add proper hover states and delays for better UX
Remove obvious comments that don't add value:
- 'Create SVG data URI for lucide-component icon'
- 'SVG image rendering' / 'Font-based Unicode rendering'
- 'Draw icon background circle if bgColor is set'
- 'Draw SVG image' / 'Draw icon'
- Unicode constant inline comments

Code should be self-documenting without redundant explanations.
Change text size from text-sm to text-xs to prevent the message from
wrapping and making the top-up button layout awkward.
Remove px-4 padding from the tooltip row to align with UserCredit.
The Partner Nodes button keeps its pl-6 indentation as intended.
Add text-xs class to the question mark icon to match the
unified credits message text size for better visual consistency.
Save and restore ctx.fillStyle in the image rendering branch to match
the pattern used in the unicode rendering branch. This prevents the
background circle color from affecting subsequent canvas operations.
- Use #FABC25 stroke color for canvas badges without circular background
- Keep existing #8D6932 badge background color
- Add feature flag toggle to Vue NodeHeader.vue for API node icons
- Switch between dollar-sign and component icons based on subscription_tiers_enabled flag
- Ensure consistent icon behavior across both litegraph and Vue node systems
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 (5)
src/lib/litegraph/src/LGraphBadge.ts (1)

111-112: Consider extracting the magic number for clarity.

The + 4 spacing adjustment could benefit from being a named constant. This is a minor readability improvement that was noted in a previous review.

src/composables/node/usePriceBadge.ts (3)

54-67: Add missing color and bgColor properties to image-based icon branch.

The subscriptionTiersEnabled branch omits color and bgColor from iconOptions, which means the image-based icon will lack the circular colored background that the unicode version renders. The LGraphIcon.draw() method in src/lib/litegraph/src/LGraphIcon.ts explicitly checks if (this.bgColor) and renders a circular background for both image and unicode icons. Without these properties, the image icon will have no background, creating a visual inconsistency.

Apply this diff to add the missing properties:

     if (flags.subscriptionTiersEnabled) {
       return new LGraphBadge({
         text: price,
         iconOptions: {
           image: componentIconSvg,
-          size: 8
+          size: 8,
+          color: isLightTheme
+            ? adjustColor('#FABC25', { lightness: 0.5 })
+            : '#FABC25',
+          bgColor: isLightTheme
+            ? adjustColor('#654020', { lightness: 0.5 })
+            : '#654020'
         },

51-89: Refactor to eliminate code duplication.

The two branches share identical color logic and badge options, differing only in iconOptions. Extract the common badge configuration to reduce duplication and improve maintainability.

Apply this diff to consolidate the logic:

   const colorPaletteStore = useColorPaletteStore()
   function getCreditsBadge(price: string): LGraphBadge {
     const isLightTheme = colorPaletteStore.completedActivePalette.light_theme
+    const iconColor = isLightTheme
+      ? adjustColor('#FABC25', { lightness: 0.5 })
+      : '#FABC25'
+    const iconBgColor = isLightTheme
+      ? adjustColor('#654020', { lightness: 0.5 })
+      : '#654020'
+    const badgeBgColor = isLightTheme
+      ? adjustColor('#8D6932', { lightness: 0.5 })
+      : '#8D6932'
 
-    if (flags.subscriptionTiersEnabled) {
-      return new LGraphBadge({
-        text: price,
-        iconOptions: {
-          image: componentIconSvg,
-          size: 8
-        },
-        fgColor:
-          colorPaletteStore.completedActivePalette.colors.litegraph_base
-            .BADGE_FG_COLOR,
-        bgColor: isLightTheme
-          ? adjustColor('#8D6932', { lightness: 0.5 })
-          : '#8D6932'
-      })
-    } else {
-      return new LGraphBadge({
-        text: price,
-        iconOptions: {
-          unicode: '\ue96b',
-          fontFamily: 'PrimeIcons',
-          color: isLightTheme
-            ? adjustColor('#FABC25', { lightness: 0.5 })
-            : '#FABC25',
-          bgColor: isLightTheme
-            ? adjustColor('#654020', { lightness: 0.5 })
-            : '#654020',
-          fontSize: 8
-        },
-        fgColor:
-          colorPaletteStore.completedActivePalette.colors.litegraph_base
-            .BADGE_FG_COLOR,
-        bgColor: isLightTheme
-          ? adjustColor('#8D6932', { lightness: 0.5 })
-          : '#8D6932'
-      })
-    }
+    const iconOptions = flags.subscriptionTiersEnabled
+      ? {
+          image: componentIconSvg,
+          color: iconColor,
+          bgColor: iconBgColor,
+          size: 8
+        }
+      : {
+          unicode: '\ue96b',
+          fontFamily: 'PrimeIcons',
+          color: iconColor,
+          bgColor: iconBgColor,
+          fontSize: 8
+        }
+
+    return new LGraphBadge({
+      text: price,
+      iconOptions,
+      fgColor:
+        colorPaletteStore.completedActivePalette.colors.litegraph_base
+          .BADGE_FG_COLOR,
+      bgColor: badgeBgColor
+    })
   }

41-48: Potential performance concern: badge function evaluation.

When badge is a function, it's invoked on every isCreditsBadge call. In collectCreditsBadges, this could evaluate thunks multiple times during filtering. Consider whether this repeated evaluation is intentional or if results should be cached.

src/lib/litegraph/src/LGraphIcon.ts (1)

44-44: Consider using nullish coalescing for size default.

this.size = size || fontSize will ignore an explicit size of 0 (treating it as falsy) and fall back to fontSize. If 0 should be distinguishable from "not provided", prefer nullish coalescing:

-    this.size = size || fontSize
+    this.size = size ?? fontSize

This keeps the intent clear and only falls back when size is undefined/null.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3adbeb2 and 8102d99.

📒 Files selected for processing (8)
  • src/components/common/UserCredit.vue (3 hunks)
  • src/components/topbar/CurrentUserPopover.vue (3 hunks)
  • src/composables/node/usePriceBadge.ts (2 hunks)
  • src/composables/useFeatureFlags.ts (2 hunks)
  • src/lib/litegraph/src/LGraphBadge.ts (2 hunks)
  • src/lib/litegraph/src/LGraphIcon.ts (2 hunks)
  • src/locales/en/main.json (1 hunks)
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue (3 hunks)
🧰 Additional context used
📓 Path-based instructions (18)
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/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.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: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/composables/node/usePriceBadge.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}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

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
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
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
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/lib/litegraph/src/LGraphBadge.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/lib/litegraph/src/LGraphBadge.ts
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/lib/litegraph/src/LGraphIcon.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/**/*.vue

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

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/composables/useFeatureFlags.ts
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
  • src/composables/node/usePriceBadge.ts
src/components/**/*.vue

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

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

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
src/components/**/*.{vue,css}

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

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
src/components/**/*.{vue,ts,js}

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

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

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
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/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
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/useFeatureFlags.ts
  • src/composables/node/usePriceBadge.ts
src/composables/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts

Files:

  • src/composables/useFeatureFlags.ts
🧠 Learnings (22)
📚 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/lib/litegraph/src/LGraphIcon.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/lib/litegraph/src/LGraphIcon.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} : When writing methods, prefer returning idiomatic JavaScript `undefined` over `null`

Applied to files:

  • src/lib/litegraph/src/LGraphIcon.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} : Prefer single line `if` syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement

Applied to files:

  • src/lib/litegraph/src/LGraphIcon.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/lib/litegraph/src/LGraphIcon.ts
  • src/composables/useFeatureFlags.ts
  • src/lib/litegraph/src/LGraphBadge.ts
  • src/composables/node/usePriceBadge.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-09T04:35:40.491Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:40.491Z
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/components/topbar/CurrentUserPopover.vue
  • 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/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.{ts,vue} : Use vue-i18n in Composition API for string literals and place new translation entries in `src/locales/en/main.json`

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.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/components/topbar/CurrentUserPopover.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/components/topbar/CurrentUserPopover.vue
  • src/components/common/UserCredit.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components

Applied to files:

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

Applied to files:

  • src/components/common/UserCredit.vue
  • src/renderer/extensions/vueNodes/components/NodeHeader.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/common/UserCredit.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Implement computed properties with `computed()` instead of using `ref` and `watch`

Applied to files:

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

Applied to files:

  • src/components/common/UserCredit.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} : The `size` and `pos` properties of `Rectangle` share the same array buffer (`subarray`); they may be used to set the rectangle's size and position

Applied to files:

  • src/lib/litegraph/src/LGraphBadge.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/composables/node/usePriceBadge.ts
🧬 Code graph analysis (2)
src/composables/useFeatureFlags.ts (1)
src/scripts/api.ts (1)
  • api (1289-1289)
src/composables/node/usePriceBadge.ts (3)
src/composables/useFeatureFlags.ts (1)
  • useFeatureFlags (22-75)
src/lib/litegraph/src/LGraphBadge.ts (1)
  • LGraphBadge (22-128)
src/utils/colorUtil.ts (1)
  • adjustColor (345-352)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (7)
src/locales/en/main.json (1)

855-859: LGTM! i18n entries correctly structured.

The new unified credits messaging follows the existing localization pattern and is properly consumed by CurrentUserPopover.vue.

src/components/common/UserCredit.vue (1)

10-20: LGTM! Feature flag integration is clean.

The conditional icon rendering correctly uses the subscriptionTiersEnabled flag to switch between the lucide component icon and the dollar icon. The implementation follows the Vue 3 Composition API pattern and integrates cleanly with the existing component logic.

Also applies to: 30-30, 39-39

src/lib/litegraph/src/LGraphBadge.ts (1)

69-74: LGTM! Width calculation correctly handles both icon types.

The conditional logic properly distinguishes between image-based icons (using icon.size) and unicode glyphs (measuring text width). The font context is correctly saved and restored.

src/components/topbar/CurrentUserPopover.vue (1)

29-44: LGTM! Feature flag gated UI correctly implemented.

The new unified credits information block is properly gated by flags.subscriptionTiersEnabled and uses the correct i18n keys that were added to main.json. The tooltip integration follows the existing pattern in the component.

Also applies to: 121-121, 143-143

src/renderer/extensions/vueNodes/components/NodeHeader.vue (1)

41-50: LGTM! Conditional icon rendering follows established pattern.

The feature flag integration correctly switches between the component icon and dollar-sign icon based on flags.subscriptionTiersEnabled. The implementation is consistent with similar changes in UserCredit.vue and properly integrates with the existing isApiNode logic.

Also applies to: 110-110, 141-141

src/composables/node/usePriceBadge.ts (1)

8-10: LGTM! SVG icon properly preloaded.

The component icon is correctly initialized as an Image with an inline SVG data URL. The oklch color format works properly in data URLs, as confirmed by the previous review discussion.

src/lib/litegraph/src/LGraphIcon.ts (1)

54-92: LGTM! Icon rendering correctly supports both image and unicode modes.

The draw method properly branches on this.image vs this.unicode, with correct context save/restore in both paths. The image rendering uses this.size for dimensions while unicode rendering uses this.fontSize, and both optionally draw a circular background when bgColor is present. The canvas context is properly managed in both branches.

…rt for subscription tiers

- Replace logical OR with nullish coalescing in LGraphIcon.ts to preserve explicit 0 values
- Update subscriptionTiersEnabled to check remoteConfig first, matching other feature flags pattern
- Add subscription_tiers_enabled to RemoteConfig type definition
@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.34 Backport PRs for cloud 1.34 labels Dec 9, 2025
@christian-byrne christian-byrne merged commit d3e9e15 into main Dec 9, 2025
38 checks passed
@christian-byrne christian-byrne deleted the credits/tooltips branch December 9, 2025 09:41
@github-actions

This comment was marked as outdated.

@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.34 Backport PRs for cloud 1.34 and removed needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.34 Backport PRs for cloud 1.34 labels Dec 9, 2025
github-actions bot pushed a commit that referenced this pull request Dec 9, 2025
This PR changes the credits icons and tooltips based on state of the
`subscription_tiers_enabled` feature flag.

When the flag is enabled (or undefined -- for local), the dollar icon is
replaced with the lucide-component icon in UserCredit and node price
badges (Partner Nodes), and a new tooltip row appears in
CurrentUserPopover displaying "Credits have been unified" with a
detailed hover tooltip explaining the credit unification across Partner
Nodes and Cloud workflows.

<img width="539" height="535" alt="image"
src="https://github.com/user-attachments/assets/7e952f9b-0abb-4979-85b7-0eecdeaf808c"
/>

Related:

- #6115 (borrows badge
implementation from this PR)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7276-change-credits-icons-and-tooltips-conditional-on-feature-flag-2c46d73d365081809a6afd5861018a15)
by [Unito](https://www.unito.io)
@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #7291

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Dec 9, 2025
christian-byrne added a commit that referenced this pull request Dec 9, 2025
…on feature flag) (#7291)

Backport of #7276 to `cloud/1.34`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7291-backport-cloud-1-34-change-credits-icons-and-tooltips-conditional-on-feature-flag-2c46d73d36508163b2d6cad792078e4c)
by [Unito](https://www.unito.io)

Co-authored-by: Christian Byrne <[email protected]>
Enferlain pushed a commit to Enferlain/ComfyUI_frontend that referenced this pull request Dec 9, 2025
…y-Org#7276)

This PR changes the credits icons and tooltips based on state of the
`subscription_tiers_enabled` feature flag.

When the flag is enabled (or undefined -- for local), the dollar icon is
replaced with the lucide-component icon in UserCredit and node price
badges (Partner Nodes), and a new tooltip row appears in
CurrentUserPopover displaying "Credits have been unified" with a
detailed hover tooltip explaining the credit unification across Partner
Nodes and Cloud workflows.

<img width="539" height="535" alt="image"
src="https://github.com/user-attachments/assets/7e952f9b-0abb-4979-85b7-0eecdeaf808c"
/>

Related:

- Comfy-Org#6115 (borrows badge
implementation from this PR)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7276-change-credits-icons-and-tooltips-conditional-on-feature-flag-2c46d73d365081809a6afd5861018a15)
by [Unito](https://www.unito.io)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud/1.34 Backport PRs for cloud 1.34 size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants