Backport of #6677 to rh-test branch.
## Changes
- Adds `preservedQueryTracker` to preserve template/source query params
during login/signup flows
- Resolves merge conflicts by keeping rh-test routing structure while
adding the fix
## Conflict Resolution
Kept rh-test branch structure:
- Import path: `./onboardingCloudRoutes` (not nested path)
- `PUBLIC_ROUTE_NAMES` and `isPublicRoute` at top level with
`/cloud/code` check
- Existing auth guard logic intact
Added from PR #6677:
- `installPreservedQueryTracker` with template/source keys
- New navigation utility files
## Testing
✅ Typecheck passes
✅ All new tests pass (20/20)
Fixes issue where template query params were being stripped during login
flows.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6711-Backport-6677-fix-template-query-param-stripped-during-login-views-2ac6d73d36508115ad5fe2776fd93c7c)
by [Unito](https://www.unito.io)
## Summary
Fixes incorrect badge placement from PR #6515. Badges should remain in
the main topbar row at all times, not move to the second row with
workflow tabs.
## Problem
PR #6515 added `TopbarBadges` to `SecondRowWorkflowTabs.vue`, causing
badges to appear in the second row when workflow tabs position was set
to `'Topbar (2nd-row)'`.
The original issue was that badges weren't visible when tabs were in
second-row mode because they were conditionally rendered only when
`workflowTabsPosition === 'Topbar'`.
## Changes
- Remove `TopbarBadges` from `SecondRowWorkflowTabs.vue` (badges should
never be in second row)
- Move `TopbarBadges` from conditional workflow tabs row to main topbar
in `TopMenubar.vue`
- Badges now always display in main topbar regardless of workflow tabs
position
## Testing
- Badges visible in main topbar when `workflowTabsPosition === 'Topbar'`
- Badges visible in main topbar when `workflowTabsPosition === 'Topbar
(2nd-row)'`
- Workflow tabs correctly move to second row without badges
Fixes issue introduced in #6515
Backports the combined changes from the following PRs into `rh-test`:
- #6504 — Settings telemetry (track `SETTING_CHANGED` on successful
update)
- #6511 — UI telemetry (actionbar drag handle, run button
choices/multi‑batch submit, breadcrumb item/root selection)
Key points
- Settings telemetry added via `SettingItem.vue` after successful
setting updates and wired to `TelemetryEvents.SETTING_CHANGED`.
- UI telemetry wired for run/queue actions and breadcrumbs to match
upstream behavior.
Divergences from the source PRs
- Removed `input_type`, `category`, and `sub_category` from
`SettingChangedMetadata` to keep the event shape focused and consistent
with downstream consumers.
- Replaced lazy telemetry import in `dialogService` error dialog
`onClose` handlers with a top‑level `useTelemetry()` import for clarity
and to avoid unnecessary dynamic imports.
- Kept a few additional telemetry events already present in this branch
(error dialog actions, graph/sidebar/template interactions). Happy to
trim these for a strict backport if desired.
Validation
- Ran `pnpm lint:fix && pnpm typecheck` successfully locally.
References
- Upstream PRs: https://github.com/Comfy-Org/ComfyUI_frontend/pull/6504,
https://github.com/Comfy-Org/ComfyUI_frontend/pull/6511
- Branch: `backport-6511-6504-to-rh-test`
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6567-Backport-telemetry-settings-UI-tracking-6504-6511-and-dialog-import-refactor-2a16d73d365081ce80a0f973c4483653)
by [Unito](https://www.unito.io)
## Summary
Manual backport of #6518 to the `rh-test` branch.
Deduplicates workflow run telemetry and keeps a single source of truth
for execution while retaining click analytics and attributing initiator
source.
- Keep execution tracking in one place via `trackWorkflowExecution()`
- Keep click analytics via `trackRunButton(...)`
- Attribute initiator with `trigger_source` = 'button' | 'keybinding' |
'legacy_ui'
- Remove pre-tracking from keybindings to avoid double/triple counting
- Update legacy UI buttons to emit both click + execution events
## Backport Notes
This backport required manual conflict resolution in:
- `src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue` - Added
batchCount tracking and trigger_source metadata
- `src/composables/useCoreCommands.ts` - Added error handling and
execution tracking
- `src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts`
- Updated trackRunButton signature with trigger_source support
Additionally added:
- `trackUiButtonClicked` method to TelemetryProvider interface
- `UiButtonClickMetadata` type definition
- `UI_BUTTON_CLICKED` event constant
All conflicts resolved intelligently to maintain the intent of the
original PR while adapting to the rh-test branch codebase.
## Original PR
- Original PR: #6518
- Original commit: 6fe88dba54
## Testing
- ✅ Typecheck passed
- ✅ Pre-commit hooks passed (lint, format)
- ✅ All conflicts resolved
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6552-Backport-to-rh-test-fix-telemetry-remove-redundant-run-tracking-keep-click-analytics-2a06d73d365081f78e4ad46a16be69f1)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Christian Byrne <c.byrne@comfy.org>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Benjamin Lu <benjaminlu1107@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Christian Byrne <chrbyrne96@gmail.com>
Manual backport of
https://github.com/Comfy-Org/ComfyUI_frontend/pull/6500, nothing changed
other than imports and some types
---
Summary
- Add TelemetryEvents.API_CREDIT_TOPUP_SUCCEEDED and provider method
trackApiCreditTopupSucceeded
- Introduce topupTrackerStore to persist pending top-ups per user
(localStorage) and reconcile against recent audit logs
- Hook purchase flow to start tracking before opening Stripe checkout
- Reconcile after fetching audit events (UsageLogsTable) and after
fetchBalance, then emit telemetry, refresh balance, and clear pending
- Minor refactor in customerEventsService to return awaited result
Implementation details
- Matching strategy:
- Event type: credit_added
- Time window: createdAt between top-up start time and +24h
- Amount: if known, e.params.amount must equal expected cents
- Cross-tab/user changes: synchronize via storage event and userId
watcher
Limitations / Follow-up
- Reconciliation fetches only page 1 (limit 10) of events; in
high-volume cases, a recent credit_added could fall outside the first
page
- The window and pagination issue will be "resolved by a followup PR to
core and cloud"
Files touched
- src/stores/topupTrackerStore.ts (new)
- src/components/dialog/content/setting/UsageLogsTable.vue
- src/composables/auth/useFirebaseAuthActions.ts
- src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts
- src/platform/telemetry/types.ts
- src/services/customerEventsService.ts
page](https://www.notion.so/PR-6500-feat-telemetry-track-API-credit-top-up-success-via-audit-events-29e6d73d365081169941efae70cf71fe)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Christian Byrne <chrbyrne96@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6520-feat-telemetry-track-API-credit-top-up-success-via-audit-events-6500-29e6d73d365081a18717ca29546ea050)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Christian Byrne <chrbyrne96@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Fix `useSubscriptionCredits` test to use cents (500) instead of
incorrect micros (5000000)
- Despite API field names containing `micros`, the server actually
returns cents (1/100)
- Add clarifying comment to `usdToMicros()` about the cents vs micros
confusion
- Increase performance test threshold from 10ms to 50ms to reduce
flakiness
## Context
The API response fields are named `amount_micros`,
`cloud_credit_balance_micros`, etc., but the server actually sends
**cents** (1/100 of a dollar), not true micros (1/1,000,000).
Verified with real API response:
```json
{
"amount_micros": 2725.927956, // = $27.26 when divided by 100
"currency": "usd"
}
```
## Changes
-
`tests-ui/tests/platform/cloud/subscription/composables/useSubscriptionCredits.test.ts`:
Update test values from micros to cents
- `packages/shared-frontend-utils/src/formatUtil.ts`: Add clarifying
documentation
- `tests-ui/tests/store/modelToNodeStore.test.ts`: Increase performance
test threshold to reduce flakiness
## Test Plan
- ✅ All unit tests pass (3202 passed, 206 skipped)
- ✅ Linting passes
- ✅ Formatting passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Hides the node name badge in queue task items on cloud builds since
workflow data is not available.
## Problem
On cloud distribution, `extra_data.extra_pnginfo.workflow` is omitted
from history task items to reduce memory usage. The node name badge
relies on this workflow data to:
1. Get the `nodeId` from the task output
2. Find the matching node in `workflow.nodes[]`
3. Display `node.type (#node.id)` (e.g., "SaveImage (#8)")
Without workflow data, the badge would be empty or show undefined
values.
## Changes
- Added `isCloud` check to the node badge `v-if` condition
- Badge now only renders when `!isCloud && isFlatTask && task.isHistory`
- Imported `isCloud` from `@/platform/distribution/types`
## Impact
- **Cloud builds**: Node name badge hidden in flat list view (workflow
data unavailable)
- **OSS/localhost builds**: Node name badge continues to show normally
(workflow data available)
## Note
This is an **rh-test only** change since cloud builds use this branch.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6517-fix-hide-node-name-badge-on-cloud-builds-29e6d73d36508163818acb07be90cf74)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Christian Byrne <c.byrne@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Fixes missing cloud badges and server health alerts when workflow tabs
are in the second-row position.
## Problem
Badges were only visible when `Comfy.Workflow.WorkflowTabsPosition` was
set to `'Topbar'`, but not when set to `'Topbar (2nd-row)'` which is the
**default for screens < 1536px wide** on rh-test.
The `SecondRowWorkflowTabs.vue` component only rendered `<WorkflowTabs
/>` but was missing `<TopbarBadges />`.
## Changes
- Added `<TopbarBadges />` component to `SecondRowWorkflowTabs.vue`
- Updated container to use flex layout to match other topbar badge
implementations
- Badges now display in both 'Topbar' and 'Topbar (2nd-row)' positions
## Testing
- Cloud badges should now be visible on screens < 1536px wide (default
setting)
- Server health alerts from remote config should display properly in
second-row tabs
## Note
This is an **rh-test only** issue. The main branch removed the 'Topbar
(2nd-row)' option in the Floating Menus PR (#5980).
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6515-fix-add-cloud-badges-and-server-health-alerts-to-second-row-workflow-tabs-29e6d73d365081c4a4defaf97d2e789e)
by [Unito](https://www.unito.io)
Co-authored-by: Christian Byrne <c.byrne@comfy.org>
Backport of #6396 to `rh-test`
Automatically created by backport workflow.
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: Claude <noreply@anthropic.com>
This backport adds the new telemetry:
- Subscription/credit events:
- MONTHLY_SUBSCRIPTION_SUCCEEDED
- ADD_API_CREDIT_BUTTON_CLICKED
- API_CREDIT_TOPUP_BUTTON_PURCHASE_CLICKED(amount)
- Run/Execution context now includes node composition metrics:
- total_node_count, subgraph_count, has_api_nodes, api_node_names
- ExecutionContext also includes custom_node_count and api_node_count
Fixes type errors during onboarding by including required fields in
minimal payloads for:
- RUN_BUTTON_CLICKED (uses zeroed node metrics)
- EXECUTION_START (uses zeroed node metrics)
Implementation notes:
- Node metrics computed via collectAllNodes + nodeDefStore; safe
defaults on failure.
- Onboarding minimal payloads include zeroed metrics to satisfy new
typings.
This is a manual backport of
https://github.com/Comfy-Org/ComfyUI_frontend/pull/6468
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6492-Backport-telemetry-API-credit-node-metrics-fix-onboarding-payload-typing-29d6d73d365081a58d96c47fc069daa6)
by [Unito](https://www.unito.io)
Backport of #6476 onto rh-test.
- Adds telemetry events for `workflow_opened` and `workflow_imported`
including `open_source` and missing node metrics.
- Resolves merge conflict in `src/scripts/app.ts` by keeping the
telemetry block after `afterConfigureGraph`.
- Includes template load and file input changes to pass `openSource`.
Files changed:
- src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts
- src/platform/telemetry/types.ts
- src/platform/workflow/templates/composables/useTemplateWorkflows.ts
- src/scripts/app.ts
- src/scripts/ui.ts
Validated with `pnpm lint:fix` and `pnpm typecheck`.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6497-Backport-telemetry-workflow_opened-with-open_source-and-missing-node-metrics-6476-29e6d73d365081238b8cef1d1a44287f)
by [Unito](https://www.unito.io)
Co-authored-by: bymyself <cbyrne@comfy.org>
This pull request makes a minor adjustment to the test setup for
`useSubscriptionCredits`. The change ensures that the actual Pinia store
implementation is used for `firebaseAuthStore` rather than a mocked
version, which can help improve the reliability and accuracy of the
tests.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6479-Fix-unit-tests-in-rh-test-29d6d73d365081be8a54c260b2ce10fe)
by [Unito](https://www.unito.io)
## Summary
Remove dead code that checks for X-Reconnecting header which is never
actually set anywhere in the codebase.
## Changes
- Remove X-Reconnecting header check in fetchApi() method
- Simplify getAuthHeader() call to not pass unused parameter
## Context
The X-Reconnecting header was being checked but never set, making this
code non-functional. This cleanup removes the confusion and simplifies
the authentication flow.
## Test Plan
- Code builds without errors
- TypeScript validation passes
- Linting passes
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6495-fix-remove-unused-X-Reconnecting-header-check-29e6d73d365081df88faeb46b1789a83)
by [Unito](https://www.unito.io)
## Summary
Adds mixpanel telemetry with goal of: "We currently only know when a
user opens a template workflow. But we also want to know if they failed
to find what they want"
Example mixpanel query:
```
app:template_library_closed
WHERE template_selected = false AND time_spent_seconds >= 10
```
But can drill down further into what filters were selected etc to answer what they were looking for but couldn't find.
```
1. Event: app:template_filter_changed
2. Filter:
- Add formula: "Where user also triggered app:template_library_closed
with template_selected = false in same session"
3. Breakdown by: search_query
4. Sort by: Total Count (descending)
Search Query Failed Sessions
-----------------------------------
"flux video" 45 times
"sdxl controlnet" 32 times
"upscaler" 28 times
(empty/just filter) 20 times
```
```
Event: app:template_filter_changed
WHERE filtered_count = 0
AND user did app:template_library_closed
with template_selected = false
Breakdown by: search_query
```
etc.
https://www.notion.so/comfy-org/Number-of-users-who-open-the-template-library-and-where-do-they-click-29b6d73d36508044a595c0fb653ca6dc?source=copy_link
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6489-feat-add-telemetry-to-answer-for-user-failed-to-find-template-29d6d73d365081cdad72fd7c6ada5dc7)
by [Unito](https://www.unito.io)
## Summary
- Prevents logged-in users from viewing the login page unnecessarily
- Adds explicit account switching flow with query parameter
- Fixes issue where logged-in users could see the login page when
directly navigating to `/cloud/login`
## Changes
1. Added `beforeEnter` guard to `cloud-login` route to check
authentication status
2. Redirect authenticated users to `cloud-user-check` (which handles
survey, waitlist, and main page routing)
3. Added `switchAccount` query parameter to allow intentional access to
login page for account switching
4. Updated CloudClaimInviteView and CloudWaitlistView to include the
`switchAccount` parameter when users click "Switch accounts"
5. Reverted UserCheckView to use `window.location.href = '/'` instead of
`router.replace('/')` to prevent infinite loading issue
## Context
The change in UserCheckView reverts to the original implementation
(`window.location.href = '/'`) because using `router.replace('/')`
caused an infinite loading issue. The direct window navigation avoids
the router's internal state issues and ensures a clean redirect to the
main application.
## Test plan
- [ ] Navigate to `/cloud/login` while logged in → Should redirect to
appropriate page
- [ ] Click "Switch accounts" from waitlist or invite views → Should
stay on login page
- [ ] Complete login flow → Should redirect properly based on user
status
- [ ] Verify no infinite loading occurs when redirecting to main app
🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6478-fix-prevent-logged-in-users-from-accessing-login-page-unless-switching-accounts-29d6d73d3650815a9d98c11951425241)
by [Unito](https://www.unito.io)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Backport of PR #6378 to `rh-test` branch.
## Changes
- Extract credit calculations into useSubscriptionCredits composable
- Extract action handlers into useSubscriptionActions composable
- Add comprehensive component and unit tests
- Update subscription panel layout to match Figma design exactly
- Add proper design tokens for modal card surfaces
- Update terminology from "API Nodes" to "Partner Nodes"
- Make credit breakdown dynamic with real API data
- Add proper loading states and error handling
- Remove unused tailwindcss eslint dependencies
## Conflicts Resolved
- Resolved merge conflicts in `packages/design-system/src/css/style.css`
related to button surface CSS variables
## Test plan
- Existing tests pass
- New tests for subscription composables and components
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6397-Backport-update-subscription-panel-for-new-designs-29c6d73d3650812aaa12ff242fd5e078)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Johnpaul Chiwetelu <49923152+Myestery@users.noreply.github.com>
## Summary
This PR improves code comments to accurately describe the whitelist
feature flag implementation logic.
## Changes
- Updated comments in `router.ts` and `UserCheckView.vue` to clarify
that the feature flag is checked first before user status
- Removed unreachable comment after return statement in
`UserCheckView.vue`
- Comments now accurately reflect the actual code execution order
## Technical Details
The logic flow remains unchanged:
1. Check `require_whitelist` feature flag first (defaults to `true`)
2. If flag is `true` AND user status is not `'active'`, redirect to
waitlist
3. If flag is `false`, allow all users to proceed regardless of status
## Testing
No functional changes - only comment improvements for better code
maintainability.
🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6457-fix-improve-whitelist-feature-flag-comments-for-clarity-29c6d73d365081cf8a59d662118f7243)
by [Unito](https://www.unito.io)
Co-authored-by: Claude <noreply@anthropic.com>
## 🐛 Problem
Users were experiencing the following issues during WebSocket
reconnection:
1. Automatic redirect to login page after "Reconnecting" toast message
appears
2. Automatic re-login after a few seconds, returning to the main
interface
3. This cycle repeats, severely degrading user experience
## 🔍 Root Cause Analysis
### 1. Router Guard Catching Too Many Errors
```typescript
// Problematic code
try {
const { getUserCloudStatus, getSurveyCompletedStatus } = await import('@/api/auth')
const userStatus = await getUserCloudStatus()
// ...
} catch (error) {
// All types of errors are caught here
return next({ name: 'cloud-user-check' })
}
```
With dynamic import inside the try block, the following were all being
caught:
- Errors during `@/api/auth` module loading
- Runtime errors from the API singleton
- Actual API call errors
Everything was caught and redirected to `cloud-user-check`.
### 2. Full Page Reload in UserCheckView
```typescript
// Problematic code
window.location.href = '/' // Full page reload!
```
This caused:
- Loss of SPA benefits
- Firebase Auth re-initialization → temporarily null user
- Router guard re-execution → potential for another redirect
## ✅ Solution
### 1. router.ts: Move dynamic import outside try block
```typescript
// After fix
const { getUserCloudStatus, getSurveyCompletedStatus } = await import('@/api/auth')
try {
// Only API calls inside try
const userStatus = await getUserCloudStatus()
// ...
} catch (error) {
// Now only catches pure API call errors
return next({ name: 'cloud-user-check' })
}
```
### 2. UserCheckView.vue: Use SPA routing
```typescript
// After fix
await router.replace('/') // Use Vue Router instead of window.location.href
```
🤖 Generated with [Claude Code](https://claude.ai/code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6410-fix-prevent-unwanted-login-redirects-during-WebSocket-reconnection-29c6d73d3650818a8a1acbdcebd2f703)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
Fixes subscription dialog incorrectly appearing on cloud onboarding
pages (email verification, survey, waitlist). Root cause: logout uses
SPA routing leaving extensions with stale auth state. Solution: (1) use
full page navigation for logout to reset app state, (2) add defensive
route guard to skip subscription checks on /cloud/* paths. Prevents
subscription modal from showing during account switching and onboarding
flows.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6367-Fix-subscription-dialog-appearing-during-onboarding-29b6d73d3650818d88e0d59ade7de02e)
by [Unito](https://www.unito.io)