Skip to content

fix(billing): stop reporting "processing" while a payment waits on the customer - #14910

Merged
wei-hai merged 3 commits into
mainfrom
fix/billing-toast-action-required
Aug 7, 2026
Merged

fix(billing): stop reporting "processing" while a payment waits on the customer#14910
wei-hai merged 3 commits into
mainfrom
fix/billing-toast-action-required

Conversation

@wei-hai

@wei-hai wei-hai commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

The billing-operation toast is created once when the operation starts and never revised, so an operation that parks on a 3DS challenge kept announcing "Processing payment — setting up your workspace..." while it was in fact waiting on the customer.

Changes

  • What: Drive the toast from the current action_url, which the generated contract defines as present exactly while a pending operation cannot proceed without the customer. The store already tracks that field and already renders a verification prompt from it — only the toast was left behind, so it contradicted the prompt beside it. The toast swaps whenever that answer changes, in either direction, so it can never outlive the action it points at.

Reproduction

Any environment in Stripe test mode:

  1. New workspace, no subscription.
  2. Subscribe to a monthly plan; complete checkout with the 3DS test card 4000 0027 6000 3184.
  3. The first invoice needs authentication, so the operation parks and the status endpoint returns status: "pending" with action_url set to the Stripe-hosted invoice page.
  4. Observe the toast while parked.

AS IS — "Processing payment — setting up your workspace..." with a spinner, for the whole time the operation waits on the customer, beside a "Complete verification" affordance rendered from the same action_url. A reload does not clear it.

TO BE — "Verify your payment to finish setting up your workspace" with a prompt icon, for as long as action_url is present.

The same state is reached before any payment exists, when the operation is waiting for the customer to finish checkout.

Before / after

flowchart TD
    A["Subscription operation starts"] --> B["⟳ Processing payment —<br/>setting up your workspace…"]
    B --> C["Poll returns action_url<br/>(bank challenge required)"]
    C --> D["Before: ⟳ Processing payment —<br/>setting up your workspace…"]
    C --> E["After: ⚠ Verify your payment to<br/>finish setting up your workspace"]
    D --> F["Contradicts the 'Complete<br/>verification' prompt beside it"]
    E --> G["Matches the 'Complete<br/>verification' prompt beside it"]
    E --> H["action_url clears →<br/>reverts to processing"]
Loading

Review Focus

  • The toast keys on the current action_url, not on the sticky authenticationRequiredSeen — so it cannot ask for verification after the verification action has gone. authenticationRequiredSeen continues to carry only polling cadence and the 23h timeout.
  • Swapped only when the answer changes, so a toast the customer dismissed is not resurfaced on every poll (cadence is 30s while parked).
  • severity: 'warn' only selects the icon in GlobalToast; this toast group renders through a custom #message slot, so severity carries no other behaviour here. The state is conveyed in the summary text, not by icon or colour alone.
  • English strings only — other locales are generated during release PRs.
  • Deliberately out of scope: the same stale copy appears in the subscription settings panel (SubscriptionPanelContentWorkspace.vue). Same fix, different surface — left for a follow-up to keep this reviewable.

Verification

  • billingOperationStore tests: 56 passed, 4 new. Each new test fails without the store change (verified by stashing it).
  • vitest run src/platform/workspace src/components/toast — 1075 passed.
  • vue-tsc --noEmit, oxfmt --check, oxlint --type-aware, eslint — clean.
  • Reproduced end to end on a fresh workspace with the 3DS test card before and after the change.

…e customer

The billing-operation toast is created once when the operation starts and is
never revised, so an operation that later parks on a 3DS challenge kept
announcing "Processing payment — setting up your workspace...". The store
already tracks the action URL that marks that state and renders a verification
prompt from it, so the toast contradicted the prompt beside it.

Replace the toast on the first transition into the action-required state, and
give it a prompt icon rather than the spinner, which otherwise keeps claiming
work is underway while nothing is.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@wei-hai
wei-hai requested a review from a team August 7, 2026 19:51
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🎭 Playwright: ✅ 1782 passed, 0 failed · 5 flaky

📊 Browser Reports
  • chromium: View Report (✅ 1763 / ❌ 0 / ⚠️ 4 / ⏭️ 5)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 16 / ❌ 0 / ⚠️ 1 / ⏭️ 0)

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 08/07/2026, 08:43:26 PM UTC

Links

📦 Bundle: 8.63 MB gzip 🔴 +138 B

Details

Summary

  • Raw size: 36.4 MB baseline 36.4 MB — 🔴 +1.03 kB
  • Gzip: 8.63 MB baseline 8.63 MB — 🔴 +138 B
  • Brotli: 6.02 MB baseline 6.01 MB — 🔴 +103 B
  • Bundles: 437 current • 437 baseline • 156 added / 156 removed

Category Glance
Data & Services 🔴 +622 B (3.49 MB) · Other 🔴 +408 B (13.8 MB) · Vendor & Third-Party ⚪ 0 B (16.3 MB) · Graph Workspace ⚪ 0 B (1.36 MB) · Panels & Settings ⚪ 0 B (570 kB) · Utilities & Hooks ⚪ 0 B (547 kB) · + 5 more

App Entry Points — 3.67 kB (baseline 3.67 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-DhfIlljZ.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.84 kB 🔴 +1.57 kB
assets/index-DtpaixVP.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.84 kB 🟢 -1.61 kB

Status: 1 added / 1 removed

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

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-9s40wYpS.js (removed) 1.35 MB 🟢 -1.35 MB 🟢 -294 kB 🟢 -221 kB
assets/GraphView-CEqPEPMZ.js (new) 1.35 MB 🔴 +1.35 MB 🔴 +294 kB 🔴 +221 kB
assets/WidgetCompositor-BvmzBx1V.js (new) 8.17 kB 🔴 +8.17 kB 🔴 +2.75 kB 🔴 +2.47 kB
assets/WidgetCompositor-RM8P55NP.js (removed) 8.17 kB 🟢 -8.17 kB 🟢 -2.75 kB 🟢 -2.46 kB

Status: 2 added / 2 removed / 1 unchanged

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-B6WAMpUr.js (removed) 25 kB 🟢 -25 kB 🟢 -6.24 kB 🟢 -5.52 kB
assets/CloudSurveyView-wijaYRy3.js (new) 25 kB 🔴 +25 kB 🔴 +6.24 kB 🔴 +5.52 kB
assets/CloudLayoutView-B2zX0RRH.js (new) 21.8 kB 🔴 +21.8 kB 🔴 +6.57 kB 🔴 +5.74 kB
assets/CloudLayoutView-BfJYKkdc.js (removed) 21.8 kB 🟢 -21.8 kB 🟢 -6.57 kB 🟢 -5.73 kB
assets/UserCheckView-CY91bxo6.js (new) 8.75 kB 🔴 +8.75 kB 🔴 +2.19 kB 🔴 +1.9 kB
assets/UserCheckView-DBR5a1cc.js (removed) 8.75 kB 🟢 -8.75 kB 🟢 -2.19 kB 🟢 -1.9 kB
assets/CloudLoginView-CPGHeoO9.js (new) 8.74 kB 🔴 +8.74 kB 🔴 +2.56 kB 🔴 +2.26 kB
assets/CloudLoginView-DQXeybBu.js (removed) 8.74 kB 🟢 -8.74 kB 🟢 -2.55 kB 🟢 -2.26 kB
assets/useCloudAuthPage-CHTveP9v.js (removed) 7.08 kB 🟢 -7.08 kB 🟢 -2.51 kB 🟢 -2.22 kB
assets/useCloudAuthPage-oBH1p59_.js (new) 7.08 kB 🔴 +7.08 kB 🔴 +2.51 kB 🔴 +2.19 kB
assets/CloudSignupView-CBlFcDYP.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -2.17 kB 🟢 -1.91 kB
assets/CloudSignupView-DVsBNhzv.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +2.17 kB 🔴 +1.91 kB
assets/WidgetTextPreview-BO26k7mL.js (removed) 6.07 kB 🟢 -6.07 kB 🟢 -2.13 kB 🟢 -1.9 kB
assets/WidgetTextPreview-ZhNqb0Wg.js (new) 6.07 kB 🔴 +6.07 kB 🔴 +2.13 kB 🔴 +1.89 kB
assets/CloudSubscriptionRedirectView-CvK6QCoM.js (removed) 6.01 kB 🟢 -6.01 kB 🟢 -2.24 kB 🟢 -1.95 kB
assets/CloudSubscriptionRedirectView-CZsWj4Le.js (new) 6.01 kB 🔴 +6.01 kB 🔴 +2.24 kB 🔴 +1.95 kB
assets/UserSelectView-51QXP0zm.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.95 kB 🟢 -1.72 kB
assets/UserSelectView-kpzDHeIp.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.95 kB 🔴 +1.71 kB
assets/CloudForgotPasswordView-4CjnL6x9.js (removed) 4.97 kB 🟢 -4.97 kB 🟢 -1.72 kB 🟢 -1.49 kB
assets/CloudForgotPasswordView-Blf_jKAt.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.72 kB 🔴 +1.49 kB
assets/CloudAuthTimeoutView-DeDry8-P.js (new) 4.43 kB 🔴 +4.43 kB 🔴 +1.54 kB 🔴 +1.33 kB
assets/CloudAuthTimeoutView-dFbFIP-R.js (removed) 4.43 kB 🟢 -4.43 kB 🟢 -1.54 kB 🟢 -1.33 kB
assets/OAuthLayoutView-B3QcerGZ.js (new) 1.31 kB 🔴 +1.31 kB 🔴 +700 B 🔴 +599 B
assets/OAuthLayoutView-DobtXLMe.js (removed) 1.31 kB 🟢 -1.31 kB 🟢 -700 B 🟢 -601 B
assets/WidgetTextPreview-B1oThNhn.js (removed) 131 B 🟢 -131 B 🟢 -100 B 🟢 -89 B
assets/WidgetTextPreview-DmY81FdD.js (new) 131 B 🔴 +131 B 🔴 +100 B 🔴 +91 B

Status: 13 added / 13 removed / 4 unchanged

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-DC3A4poU.js (new) 49.4 kB 🔴 +49.4 kB 🔴 +9.94 kB 🔴 +8.8 kB
assets/KeybindingPanel-gPeu15bd.js (removed) 49.4 kB 🟢 -49.4 kB 🟢 -9.94 kB 🟢 -8.81 kB
assets/SecretsPanel-Blh8TFUb.js (new) 33.7 kB 🔴 +33.7 kB 🔴 +7.87 kB 🔴 +6.92 kB
assets/SecretsPanel-CrNniSwA.js (removed) 33.7 kB 🟢 -33.7 kB 🟢 -7.87 kB 🟢 -6.91 kB
assets/CreditsPanel-CE1Amfre.js (removed) 16 kB 🟢 -16 kB 🟢 -4.63 kB 🟢 -4.07 kB
assets/CreditsPanel-j9U7QUzY.js (new) 16 kB 🔴 +16 kB 🔴 +4.63 kB 🔴 +4.07 kB
assets/AboutPanel-CfnOTo5v.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.03 kB 🟢 -2.74 kB
assets/AboutPanel-D5yHtpxg.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.02 kB 🔴 +2.74 kB
assets/ExtensionPanel-CrdxQEEO.js (new) 9.19 kB 🔴 +9.19 kB 🔴 +2.51 kB 🔴 +2.23 kB
assets/ExtensionPanel-D8PsWutc.js (removed) 9.19 kB 🟢 -9.19 kB 🟢 -2.51 kB 🟢 -2.23 kB
assets/ServerConfigPanel-C9xntdFR.js (removed) 6.09 kB 🟢 -6.09 kB 🟢 -1.94 kB 🟢 -1.72 kB
assets/ServerConfigPanel-Du-AJJo4.js (new) 6.09 kB 🔴 +6.09 kB 🔴 +1.94 kB 🔴 +1.72 kB
assets/UserPanel-BBxeswjc.js (new) 5.73 kB 🔴 +5.73 kB 🔴 +1.78 kB 🔴 +1.54 kB
assets/UserPanel-kYqnfvro.js (removed) 5.73 kB 🟢 -5.73 kB 🟢 -1.78 kB 🟢 -1.54 kB
assets/refreshRemoteConfig-CheD0NvR.js (new) 3.58 kB 🔴 +3.58 kB 🔴 +1.36 kB 🔴 +1.2 kB
assets/refreshRemoteConfig-D5ovhuKf.js (removed) 3.58 kB 🟢 -3.58 kB 🟢 -1.36 kB 🟢 -1.2 kB
assets/cloudRemoteConfig-BPWlNY1a.js (new) 951 B 🔴 +951 B 🔴 +515 B 🔴 +421 B
assets/cloudRemoteConfig-DdbshxOK.js (removed) 951 B 🟢 -951 B 🟢 -515 B 🟢 -421 B
assets/refreshRemoteConfig-Bp-D6IP_.js (removed) 110 B 🟢 -110 B 🟢 -89 B 🟢 -83 B
assets/refreshRemoteConfig-CUMIv7fD.js (new) 110 B 🔴 +110 B 🔴 +89 B 🔴 +92 B

Status: 10 added / 10 removed / 16 unchanged

User & Accounts — 27 kB (baseline 27 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SignUpForm-Dk3TvPNy.js (new) 12.8 kB 🔴 +12.8 kB 🔴 +4.31 kB 🔴 +3.75 kB
assets/SignUpForm-PsXTw6KR.js (removed) 12.8 kB 🟢 -12.8 kB 🟢 -4.31 kB 🟢 -3.75 kB
assets/auth-BMzlODFV.js (removed) 3.71 kB 🟢 -3.71 kB 🟢 -1.28 kB 🟢 -1.1 kB
assets/auth-Ctq58G7b.js (new) 3.71 kB 🔴 +3.71 kB 🔴 +1.29 kB 🔴 +1.1 kB
assets/UpdatePasswordContent-BSA9No0h.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -842 B 🟢 -731 B
assets/UpdatePasswordContent-DFIAIPjo.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +843 B 🔴 +734 B
assets/authStore-ClwOJNVv.js (removed) 128 B 🟢 -128 B 🟢 -107 B 🟢 -115 B
assets/authStore-CtM1BiMX.js (new) 128 B 🔴 +128 B 🔴 +107 B 🔴 +102 B
assets/workspaceAuthStore-B0eQ5p_Z.js (new) 108 B 🔴 +108 B 🔴 +99 B 🔴 +108 B
assets/workspaceAuthStore-Ctz8Sjk6.js (removed) 108 B 🟢 -108 B 🟢 -99 B 🟢 -108 B
assets/auth-9KlWPdsC.js (new) 105 B 🔴 +105 B 🔴 +96 B 🔴 +88 B
assets/auth-CaOctFZB.js (removed) 105 B 🟢 -105 B 🟢 -96 B 🟢 -81 B

Status: 6 added / 6 removed / 4 unchanged

Editors & Dialogs — 125 kB (baseline 125 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyHubPublishDialog-BvDx35xd.js (removed) 90.1 kB 🟢 -90.1 kB 🟢 -19.3 kB 🟢 -16.5 kB
assets/ComfyHubPublishDialog-Cl7MP0fX.js (new) 90.1 kB 🔴 +90.1 kB 🔴 +19.3 kB 🔴 +16.5 kB
assets/useShareDialog-35d759yM.js (new) 23.9 kB 🔴 +23.9 kB 🔴 +5.69 kB 🔴 +5.04 kB
assets/useShareDialog-BeF74Jqd.js (removed) 23.9 kB 🟢 -23.9 kB 🟢 -5.69 kB 🟢 -5.03 kB
assets/feedbackDialog-BlNb8uHp.js (removed) 4.45 kB 🟢 -4.45 kB 🟢 -1.87 kB 🟢 -1.59 kB
assets/feedbackDialog-CeroyiHZ.js (new) 4.45 kB 🔴 +4.45 kB 🔴 +1.87 kB 🔴 +1.59 kB
assets/useRangeEditor-3v08ZMuw.js (new) 3.29 kB 🔴 +3.29 kB 🔴 +1.14 kB 🔴 +1.06 kB
assets/useRangeEditor-PWlkC5Cy.js (removed) 3.29 kB 🟢 -3.29 kB 🟢 -1.14 kB 🟢 -1.03 kB
assets/useLayerEditor-B7czq9JJ.js (new) 1.01 kB 🔴 +1.01 kB 🔴 +489 B 🔴 +406 B
assets/useLayerEditor-DuUN8Ues.js (removed) 1.01 kB 🟢 -1.01 kB 🟢 -489 B 🟢 -407 B
assets/ComfyHubPublishDialog-CJIueVfA.js (removed) 143 B 🟢 -143 B 🟢 -105 B 🟢 -87 B
assets/ComfyHubPublishDialog-wmwKTGXZ.js (new) 143 B 🔴 +143 B 🔴 +105 B 🔴 +88 B
assets/useSubscriptionDialog-Bf0xs946.js (removed) 108 B 🟢 -108 B 🟢 -102 B 🟢 -95 B
assets/useSubscriptionDialog-C1-JAwAg.js (new) 108 B 🔴 +108 B 🔴 +102 B 🔴 +91 B

Status: 7 added / 7 removed / 1 unchanged

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-Byn1enag.js (new) 14.6 kB 🔴 +14.6 kB 🔴 +3.97 kB 🔴 +3.52 kB
assets/ComfyQueueButton-C62haNpO.js (removed) 14.6 kB 🟢 -14.6 kB 🟢 -3.97 kB 🟢 -3.52 kB
assets/useTerminalTabs-B_n5xKhJ.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.69 kB 🔴 +3.26 kB
assets/useTerminalTabs-BLsEYqPY.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.69 kB 🟢 -3.27 kB
assets/InviteMembersForm-CdU5CwwH.js (new) 8.2 kB 🔴 +8.2 kB 🔴 +2.72 kB 🔴 +2.45 kB
assets/InviteMembersForm-Dh2V-z_m.js (removed) 8.2 kB 🟢 -8.2 kB 🟢 -2.72 kB 🟢 -2.42 kB
assets/SubscribeButton-CTDYu8w9.js (removed) 2.15 kB 🟢 -2.15 kB 🟢 -969 B 🟢 -842 B
assets/SubscribeButton-zRpoI1L7.js (new) 2.15 kB 🔴 +2.15 kB 🔴 +967 B 🔴 +849 B
assets/cloudFeedbackTopbarButton-DtmXKSdj.js (removed) 705 B 🟢 -705 B 🟢 -421 B 🟢 -358 B
assets/cloudFeedbackTopbarButton-rF1S7OJg.js (new) 705 B 🔴 +705 B 🔴 +420 B 🔴 +358 B
assets/ComfyQueueButton-CoUNZSLc.js (removed) 128 B 🟢 -128 B 🟢 -99 B 🟢 -90 B
assets/ComfyQueueButton-CZz3A9nW.js (new) 128 B 🔴 +128 B 🔴 +99 B 🔴 +89 B

Status: 6 added / 6 removed / 8 unchanged

Data & Services — 3.49 MB (baseline 3.49 MB) • 🔴 +622 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/settingStore-BwKgLFXI.js (new) 3.21 MB 🔴 +3.21 MB 🔴 +744 kB 🔴 +560 kB
assets/settingStore-nQ-99DYS.js (removed) 3.21 MB 🟢 -3.21 MB 🟢 -744 kB 🟢 -560 kB
assets/load3dService-CwlwtPwD.js (removed) 132 kB 🟢 -132 kB 🟢 -29.3 kB 🟢 -24.6 kB
assets/load3dService-DlnV3apE.js (new) 132 kB 🔴 +132 kB 🔴 +29.3 kB 🔴 +24.6 kB
assets/api-BL5Kr5k8.js (new) 97.7 kB 🔴 +97.7 kB 🔴 +26.9 kB 🔴 +23.1 kB
assets/api-Du2Ql4gX.js (removed) 97.7 kB 🟢 -97.7 kB 🟢 -26.9 kB 🟢 -23.1 kB
assets/workflowShareService-_3stirp2.js (removed) 16.5 kB 🟢 -16.5 kB 🟢 -4.91 kB 🟢 -4.35 kB
assets/workflowShareService-Cj3yggW2.js (new) 16.5 kB 🔴 +16.5 kB 🔴 +4.91 kB 🔴 +4.35 kB
assets/keybindingService-CQpzdm9I.js (removed) 6.89 kB 🟢 -6.89 kB 🟢 -1.73 kB 🟢 -1.5 kB
assets/keybindingService-DRzs3LoE.js (new) 6.89 kB 🔴 +6.89 kB 🔴 +1.73 kB 🔴 +1.5 kB
assets/releaseStore-ckb1GW3j.js (new) 6.72 kB 🔴 +6.72 kB 🔴 +2.03 kB 🔴 +1.77 kB
assets/releaseStore-DMIe57x-.js (removed) 6.72 kB 🟢 -6.72 kB 🟢 -2.03 kB 🟢 -1.77 kB
assets/systemStatsStore-Bf4QAwZ3.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.74 kB 🟢 -1.47 kB
assets/systemStatsStore-D--GGc1t.js (new) 4.93 kB 🔴 +4.93 kB 🔴 +1.74 kB 🔴 +1.47 kB
assets/userStore-D1xz5b8P.js (new) 2.38 kB 🔴 +2.38 kB 🔴 +901 B 🔴 +791 B
assets/userStore-DZ4YpN3g.js (removed) 2.38 kB 🟢 -2.38 kB 🟢 -900 B 🟢 -792 B
assets/audioService-2nrNCmb3.js (new) 1.71 kB 🔴 +1.71 kB 🔴 +831 B 🔴 +722 B
assets/audioService-Bz9XuJBy.js (removed) 1.71 kB 🟢 -1.71 kB 🟢 -829 B 🟢 -721 B
assets/dialogService-CQhX5wss.js (new) 98 B 🔴 +98 B 🔴 +97 B 🔴 +91 B
assets/dialogService-Dp5yhpC3.js (removed) 98 B 🟢 -98 B 🟢 -97 B 🟢 -80 B
assets/releaseStore-DOEY2Ofk.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +90 B
assets/releaseStore-POTQLxCS.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -85 B
assets/settingStore-C77PzRPh.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -86 B
assets/settingStore-DX-0p9_X.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +86 B
assets/assetsStore-BZuujJl3.js (removed) 94 B 🟢 -94 B 🟢 -92 B 🟢 -86 B
assets/assetsStore-DwnATNKq.js (new) 94 B 🔴 +94 B 🔴 +92 B 🔴 +87 B
assets/api-ByzN-gtF.js (new) 62 B 🔴 +62 B 🔴 +74 B 🔴 +66 B
assets/api-DKKDYRnl.js (removed) 62 B 🟢 -62 B 🟢 -74 B 🟢 -66 B

Status: 14 added / 14 removed / 3 unchanged

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-DCVH6FFW.js (new) 235 kB 🔴 +235 kB 🔴 +52.5 kB 🔴 +42.8 kB
assets/useConflictDetection-DHPQ18z1.js (removed) 235 kB 🟢 -235 kB 🟢 -52.6 kB 🟢 -42.7 kB
assets/useLayerEditorSession-DQFtK2te.js (removed) 158 kB 🟢 -158 kB 🟢 -40.8 kB 🟢 -34.3 kB
assets/useLayerEditorSession-DtyRhLAY.js (new) 158 kB 🔴 +158 kB 🔴 +40.8 kB 🔴 +34.3 kB
assets/useLoad3d-D4rhPrHD.js (removed) 25.8 kB 🟢 -25.8 kB 🟢 -5.8 kB 🟢 -5.15 kB
assets/useLoad3d-Dd6yLNuM.js (new) 25.8 kB 🔴 +25.8 kB 🔴 +5.8 kB 🔴 +5.14 kB
assets/useLoad3dViewer-BTeKALci.js (removed) 21.2 kB 🟢 -21.2 kB 🟢 -4.98 kB 🟢 -4.36 kB
assets/useLoad3dViewer-BWbuorM_.js (new) 21.2 kB 🔴 +21.2 kB 🔴 +4.98 kB 🔴 +4.38 kB
assets/useImageCrop-B0k4VXek.js (removed) 14.9 kB 🟢 -14.9 kB 🟢 -3.42 kB 🟢 -2.98 kB
assets/useImageCrop-Jtg0Jo13.js (new) 14.9 kB 🔴 +14.9 kB 🔴 +3.42 kB 🔴 +2.98 kB
assets/useDowngradeToPersonal-BYlCnHHU.js (removed) 8.85 kB 🟢 -8.85 kB 🟢 -2.53 kB 🟢 -2.17 kB
assets/useDowngradeToPersonal-CQoPAiHr.js (new) 8.85 kB 🔴 +8.85 kB 🔴 +2.53 kB 🔴 +2.17 kB
assets/useFeatureFlags-COh0O74W.js (removed) 7.04 kB 🟢 -7.04 kB 🟢 -2.02 kB 🟢 -1.73 kB
assets/useFeatureFlags-Dxl7eZVk.js (new) 7.04 kB 🔴 +7.04 kB 🔴 +2.02 kB 🔴 +1.73 kB
assets/useCompositorLayers-Az5fGakT.js (removed) 2.94 kB 🟢 -2.94 kB 🟢 -901 B 🟢 -799 B
assets/useCompositorLayers-B1yotz7e.js (new) 2.94 kB 🔴 +2.94 kB 🔴 +899 B 🔴 +802 B
assets/useExternalLink-D86DHXZH.js (removed) 2.85 kB 🟢 -2.85 kB 🟢 -1.07 kB 🟢 -930 B
assets/useExternalLink-DrkB1Vyv.js (new) 2.85 kB 🔴 +2.85 kB 🔴 +1.07 kB 🔴 +924 B
assets/downloadUtil-CrhroCyd.js (new) 2.4 kB 🔴 +2.4 kB 🔴 +1.08 kB 🔴 +872 B
assets/downloadUtil-DGsZ93dv.js (removed) 2.4 kB 🟢 -2.4 kB 🟢 -1.08 kB 🟢 -869 B
assets/assetPreviewUtil-BdRNhPqm.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +970 B 🔴 +836 B
assets/assetPreviewUtil-DENXJiKW.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -970 B 🟢 -837 B
assets/useUpstreamValue-BvYC2_VL.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +760 B 🔴 +682 B
assets/useUpstreamValue-CiVm2pY5.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -761 B 🟢 -687 B
assets/useWorkspaceTierLabel-BIxhfZDM.js (new) 1.93 kB 🔴 +1.93 kB 🔴 +815 B 🔴 +692 B
assets/useWorkspaceTierLabel-DwHVrhct.js (removed) 1.93 kB 🟢 -1.93 kB 🟢 -814 B 🟢 -693 B
assets/useErrorHandling-DKT6VyzS.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +615 B 🔴 +522 B
assets/useErrorHandling-haTOgdGQ.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -612 B 🟢 -522 B
assets/subscriptionCheckoutUtil-DFrMc5l8.js (removed) 773 B 🟢 -773 B 🟢 -473 B 🟢 -411 B
assets/subscriptionCheckoutUtil-PO3aERKk.js (new) 773 B 🔴 +773 B 🔴 +473 B 🔴 +410 B
assets/useSessionCookie-B6-LpQIi.js (removed) 652 B 🟢 -652 B 🟢 -336 B 🟢 -292 B
assets/useSessionCookie-rte10YMu.js (new) 652 B 🔴 +652 B 🔴 +336 B 🔴 +291 B
assets/useLoad3d-B5chdBhf.js (removed) 311 B 🟢 -311 B 🟢 -163 B 🟢 -147 B
assets/useLoad3d-BiGJJqBF.js (new) 311 B 🔴 +311 B 🔴 +163 B 🔴 +147 B
assets/useSessionCookie-ClzsFTBR.js (removed) 101 B 🟢 -101 B 🟢 -86 B 🟢 -81 B
assets/useSessionCookie-DFlwqLvY.js (new) 101 B 🔴 +101 B 🔴 +86 B 🔴 +83 B
assets/useFeatureFlags-B5FfQKpT.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -81 B
assets/useFeatureFlags-CA6Hnq5L.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +86 B
assets/useLoad3dViewer-BtWLk38R.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +82 B
assets/useLoad3dViewer-DsX9lkzX.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -84 B
assets/useCurrentUser-DjJIBThm.js (new) 94 B 🔴 +94 B 🔴 +95 B 🔴 +86 B
assets/useCurrentUser-ViBJErPH.js (removed) 94 B 🟢 -94 B 🟢 -95 B 🟢 -93 B

Status: 21 added / 21 removed / 17 unchanged

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

External libraries and shared vendor chunks

Status: 17 unchanged

Other — 13.8 MB (baseline 13.8 MB) • 🔴 +408 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/main-3e6YSWX2.js (new) 205 kB 🔴 +205 kB 🔴 +59.7 kB 🔴 +50.1 kB
assets/main-D_kGBkOE.js (removed) 205 kB 🟢 -205 kB 🟢 -59.7 kB 🟢 -50.1 kB
assets/core-BVKiqSgW.js (removed) 114 kB 🟢 -114 kB 🟢 -29.2 kB 🟢 -24.8 kB
assets/core-Dani82A8.js (new) 114 kB 🔴 +114 kB 🔴 +29.2 kB 🔴 +24.7 kB
assets/WidgetSelect-BinTMfmJ.js (new) 88.8 kB 🔴 +88.8 kB 🔴 +20.1 kB 🔴 +17.2 kB
assets/WidgetSelect-CqDygzVZ.js (removed) 88.8 kB 🟢 -88.8 kB 🟢 -20.1 kB 🟢 -17.2 kB
assets/SubscriptionPanelContentWorkspace-hpstrv1D.js (removed) 79.9 kB 🟢 -79.9 kB 🟢 -15.7 kB 🟢 -13.6 kB
assets/SubscriptionPanelContentWorkspace-moUehhtC.js (new) 79.9 kB 🔴 +79.9 kB 🔴 +15.7 kB 🔴 +13.6 kB
assets/Load3D-HEGgVlRP.js (new) 71.3 kB 🔴 +71.3 kB 🔴 +11.7 kB 🔴 +9.99 kB
assets/Load3D-mY_y8uMt.js (removed) 71.3 kB 🟢 -71.3 kB 🟢 -11.7 kB 🟢 -10 kB
assets/WidgetVideoEdit-By-PJ82y.js (removed) 63.4 kB 🟢 -63.4 kB 🟢 -14.6 kB 🟢 -12.8 kB
assets/WidgetVideoEdit-RY1rZQJ-.js (new) 63.4 kB 🔴 +63.4 kB 🔴 +14.6 kB 🔴 +12.9 kB
assets/SubscriptionTransitionPreviewWorkspace-A28-f7yE.js (new) 63.1 kB 🔴 +63.1 kB 🔴 +13 kB 🔴 +11.3 kB
assets/SubscriptionTransitionPreviewWorkspace-B5WjBSgd.js (removed) 63.1 kB 🟢 -63.1 kB 🟢 -13 kB 🟢 -11.4 kB
assets/WorkspaceSettingsPanelContent-C9xGuBd6.js (removed) 61.7 kB 🟢 -61.7 kB 🟢 -13.2 kB 🟢 -11.5 kB
assets/WorkspaceSettingsPanelContent-DzNvMt18.js (new) 61.7 kB 🔴 +61.7 kB 🔴 +13.2 kB 🔴 +11.5 kB
assets/Preview3d-DrOiHaqh.js (removed) 50.9 kB 🟢 -50.9 kB 🟢 -8.31 kB 🟢 -7.26 kB
assets/Preview3d-WC4pCKkA.js (new) 50.9 kB 🔴 +50.9 kB 🔴 +8.31 kB 🔴 +7.25 kB
assets/main-7G29x7kg.js (new) 45.1 kB 🔴 +45.1 kB 🔴 +13.1 kB 🔴 +11.4 kB
assets/main-C_Gw5GW_.js (removed) 45.1 kB 🟢 -45.1 kB 🟢 -13.1 kB 🟢 -11.4 kB
assets/LayerEditorContent-4-Wiomj5.js (new) 42.5 kB 🔴 +42.5 kB 🔴 +9.62 kB 🔴 +8.44 kB
assets/LayerEditorContent-VbURl2LS.js (removed) 42.5 kB 🟢 -42.5 kB 🟢 -9.62 kB 🟢 -8.43 kB
assets/SubscriptionRequiredDialogContentUnified-BLuZuWeD.js (removed) 42.5 kB 🟢 -42.5 kB 🟢 -9.35 kB 🟢 -8.15 kB
assets/SubscriptionRequiredDialogContentUnified-C-whh0-x.js (new) 42.5 kB 🔴 +42.5 kB 🔴 +9.35 kB 🔴 +8.16 kB
assets/WidgetBoundingBoxes-BdgFngKp.js (new) 33.7 kB 🔴 +33.7 kB 🔴 +9.15 kB 🔴 +8.13 kB
assets/WidgetBoundingBoxes-ChixcL3Q.js (removed) 33.7 kB 🟢 -33.7 kB 🟢 -9.15 kB 🟢 -8.13 kB
assets/WidgetPainter-Cq_uDAHl.js (new) 32.6 kB 🔴 +32.6 kB 🔴 +7.87 kB 🔴 +6.97 kB
assets/WidgetPainter-n-Dd3nEC.js (removed) 32.6 kB 🟢 -32.6 kB 🟢 -7.87 kB 🟢 -6.97 kB
assets/Load3dViewerContent-C3feXW2b.js (new) 30.8 kB 🔴 +30.8 kB 🔴 +6.28 kB 🔴 +5.45 kB
assets/Load3dViewerContent-CPtJI5UO.js (removed) 30.8 kB 🟢 -30.8 kB 🟢 -6.28 kB 🟢 -5.45 kB
assets/HdrViewerContent-9fSXIfxo.js (new) 29.8 kB 🔴 +29.8 kB 🔴 +8.24 kB 🔴 +7.27 kB
assets/HdrViewerContent-sotYV-DD.js (removed) 29.8 kB 🟢 -29.8 kB 🟢 -8.24 kB 🟢 -7.27 kB
assets/SubscriptionRequiredDialogContent-BHoU07qS.js (new) 27 kB 🔴 +27 kB 🔴 +6.38 kB 🔴 +5.62 kB
assets/SubscriptionRequiredDialogContent-CWNfPeJJ.js (removed) 27 kB 🟢 -27 kB 🟢 -6.37 kB 🟢 -5.62 kB
assets/SubscriptionRequiredDialogContentWorkspace-DjiYaMW9.js (removed) 25.1 kB 🟢 -25.1 kB 🟢 -5.8 kB 🟢 -5.1 kB
assets/SubscriptionRequiredDialogContentWorkspace-jQTHy58V.js (new) 25.1 kB 🔴 +25.1 kB 🔴 +5.8 kB 🔴 +5.09 kB
assets/load3d-BaadTnQ-.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.4 kB 🟢 -4.67 kB
assets/load3d-CPzb1th_.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.4 kB 🔴 +4.67 kB
assets/CurrentUserPopoverWorkspace-C5ZW9YFK.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -4.84 kB 🟢 -4.32 kB
assets/CurrentUserPopoverWorkspace-CO1Ys5Xx.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +4.84 kB 🔴 +4.32 kB
assets/SignInContent-ITG2biv5.js (new) 20.2 kB 🔴 +20.2 kB 🔴 +5.09 kB 🔴 +4.44 kB
assets/SignInContent-K-o-7Nzw.js (removed) 20.2 kB 🟢 -20.2 kB 🟢 -5.09 kB 🟢 -4.45 kB
assets/CreditsTile-B9rBazUz.js (removed) 19.2 kB 🟢 -19.2 kB 🟢 -4.83 kB 🟢 -4.23 kB
assets/CreditsTile-BIRdO57C.js (new) 19.2 kB 🔴 +19.2 kB 🔴 +4.83 kB 🔴 +4.24 kB
assets/WidgetRecordAudio-CAcbUcTZ.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.6 kB 🟢 -4.1 kB
assets/WidgetRecordAudio-DM1pOi3s.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.59 kB 🔴 +4.1 kB
assets/i18n-AWSHiUiH.js (removed) 15.9 kB 🟢 -15.9 kB 🟢 -4.31 kB 🟢 -3.63 kB
assets/i18n-DXOIE5dh.js (new) 15.9 kB 🔴 +15.9 kB 🔴 +4.31 kB 🔴 +3.63 kB
assets/WidgetInputNumber-D0KAkgKv.js (removed) 13.9 kB 🟢 -13.9 kB 🟢 -3.63 kB 🟢 -3.2 kB
assets/WidgetInputNumber-hIUhZFBz.js (new) 13.9 kB 🔴 +13.9 kB 🔴 +3.63 kB 🔴 +3.21 kB
assets/WidgetRange-BQWDOe-z.js (new) 13.7 kB 🔴 +13.7 kB 🔴 +3.55 kB 🔴 +3.13 kB
assets/WidgetRange-C8PS5F3n.js (removed) 13.7 kB 🟢 -13.7 kB 🟢 -3.55 kB 🟢 -3.12 kB
assets/WaveAudioPlayer-Blhg6m3u.js (new) 12.8 kB 🔴 +12.8 kB 🔴 +3.47 kB 🔴 +3.05 kB
assets/WaveAudioPlayer-S06KOla-.js (removed) 12.8 kB 🟢 -12.8 kB 🟢 -3.47 kB 🟢 -3.03 kB
assets/WidgetCurve-BlhwnBTV.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.47 kB 🔴 +3.15 kB
assets/WidgetCurve-DV0a62Fi.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.47 kB 🟢 -3.15 kB
assets/AudioPreviewPlayer-Bix3-VdI.js (removed) 10.6 kB 🟢 -10.6 kB 🟢 -3.05 kB 🟢 -2.72 kB
assets/AudioPreviewPlayer-j30W4w8W.js (new) 10.6 kB 🔴 +10.6 kB 🔴 +3.05 kB 🔴 +2.71 kB
assets/TeamWorkspacesDialogContent-C-LmnKwO.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.96 kB 🟢 -2.63 kB
assets/TeamWorkspacesDialogContent-C57AChPX.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.97 kB 🔴 +2.63 kB
assets/onboardingCloudRoutes-BlYTmpsM.js (removed) 9.22 kB 🟢 -9.22 kB 🟢 -2.82 kB 🟢 -2.43 kB
assets/onboardingCloudRoutes-CWmVNgmk.js (new) 9.22 kB 🔴 +9.22 kB 🔴 +2.82 kB 🔴 +2.42 kB
assets/Load3DConfiguration-BcXjncUY.js (new) 8.91 kB 🔴 +8.91 kB 🔴 +2.61 kB 🔴 +2.3 kB
assets/Load3DConfiguration-Bge-b0qS.js (removed) 8.91 kB 🟢 -8.91 kB 🟢 -2.61 kB 🟢 -2.3 kB
assets/WidgetImageCrop-5-npvm0a.js (removed) 8.49 kB 🟢 -8.49 kB 🟢 -2.65 kB 🟢 -2.34 kB
assets/WidgetImageCrop-Eg8U7cj5.js (new) 8.49 kB 🔴 +8.49 kB 🔴 +2.65 kB 🔴 +2.34 kB
assets/SetMemberCreditLimitDialogContent-DbGOKm-B.js (removed) 8.47 kB 🟢 -8.47 kB 🟢 -2.34 kB 🟢 -2.05 kB
assets/SetMemberCreditLimitDialogContent-GPUO0QRy.js (new) 8.47 kB 🔴 +8.47 kB 🔴 +2.34 kB 🔴 +2.05 kB
assets/nodeTemplates-B4tyvjSF.js (new) 8.32 kB 🔴 +8.32 kB 🔴 +2.85 kB 🔴 +2.51 kB
assets/nodeTemplates-DaZTPNDF.js (removed) 8.32 kB 🟢 -8.32 kB 🟢 -2.85 kB 🟢 -2.51 kB
assets/NightlySurveyController-BHaUBEPr.js (new) 7.5 kB 🔴 +7.5 kB 🔴 +2.55 kB 🔴 +2.24 kB
assets/NightlySurveyController-GqrzG1wd.js (removed) 7.5 kB 🟢 -7.5 kB 🟢 -2.55 kB 🟢 -2.24 kB
assets/CloudRunButtonWrapper-BNZeJS-z.js (removed) 6.82 kB 🟢 -6.82 kB 🟢 -2.18 kB 🟢 -1.91 kB
assets/CloudRunButtonWrapper-CpfRsRT5.js (new) 6.82 kB 🔴 +6.82 kB 🔴 +2.18 kB 🔴 +1.91 kB
assets/WidgetWithControl-Cr1-2H27.js (removed) 6.41 kB 🟢 -6.41 kB 🟢 -2.61 kB 🟢 -2.3 kB
assets/WidgetWithControl-iPSO2ZO_.js (new) 6.41 kB 🔴 +6.41 kB 🔴 +2.61 kB 🔴 +2.31 kB
assets/CancelSubscriptionDialogContent-BiPTAwZf.js (removed) 5.97 kB 🟢 -5.97 kB 🟢 -1.98 kB 🟢 -1.75 kB
assets/CancelSubscriptionDialogContent-DICr3rWa.js (new) 5.97 kB 🔴 +5.97 kB 🔴 +1.98 kB 🔴 +1.75 kB
assets/main-CO13WAnK.js (removed) 5.92 kB 🟢 -5.92 kB 🟢 -1.9 kB 🟢 -1.6 kB
assets/main-D8UuG0Vb.js (new) 5.92 kB 🔴 +5.92 kB 🔴 +1.91 kB 🔴 +1.6 kB
assets/load3dPreviewExtensions-C0BXBuwg.js (removed) 5.88 kB 🟢 -5.88 kB 🟢 -1.81 kB 🟢 -1.61 kB
assets/load3dPreviewExtensions-DLx3z4KA.js (new) 5.88 kB 🔴 +5.88 kB 🔴 +1.81 kB 🔴 +1.6 kB
assets/missingModelDownload-Cl1o0617.js (removed) 5.88 kB 🟢 -5.88 kB 🟢 -2.08 kB 🟢 -1.81 kB
assets/missingModelDownload-ovQLcjje.js (new) 5.88 kB 🔴 +5.88 kB 🔴 +2.07 kB 🔴 +1.81 kB
assets/launchCancellationFlow-BHsXd0O4.js (new) 5.18 kB 🔴 +5.18 kB 🔴 +1.78 kB 🔴 +1.56 kB
assets/launchCancellationFlow-BuD06eB5.js (removed) 5.18 kB 🟢 -5.18 kB 🟢 -1.78 kB 🟢 -1.56 kB
assets/CreateWorkspaceDialogContent-APVTiPmE.js (removed) 5.12 kB 🟢 -5.12 kB 🟢 -1.79 kB 🟢 -1.55 kB
assets/CreateWorkspaceDialogContent-DrRJi9jh.js (new) 5.12 kB 🔴 +5.12 kB 🔴 +1.79 kB 🔴 +1.55 kB
assets/ChangeMemberRoleDialogContent-BJyYdVei.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.64 kB 🔴 +1.43 kB
assets/ChangeMemberRoleDialogContent-CtF0PtJs.js (removed) 4.97 kB 🟢 -4.97 kB 🟢 -1.64 kB 🟢 -1.42 kB
assets/InviteMemberDialogContent-4ywrL47j.js (removed) 4.96 kB 🟢 -4.96 kB 🟢 -1.65 kB 🟢 -1.44 kB
assets/InviteMemberDialogContent-BftB3tJ4.js (new) 4.96 kB 🔴 +4.96 kB 🔴 +1.65 kB 🔴 +1.44 kB
assets/EditWorkspaceDialogContent-DNeNcaiv.js (new) 4.93 kB 🔴 +4.93 kB 🔴 +1.76 kB 🔴 +1.53 kB
assets/EditWorkspaceDialogContent-WyeVr4T8.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.76 kB 🟢 -1.53 kB
assets/WidgetTextarea-BIGYFI9T.js (new) 4.81 kB 🔴 +4.81 kB 🔴 +1.87 kB 🔴 +1.63 kB
assets/WidgetTextarea-D_e6JiPA.js (removed) 4.81 kB 🟢 -4.81 kB 🟢 -1.87 kB 🟢 -1.63 kB
assets/saveMesh-B2Ch5_Xx.js (new) 4.76 kB 🔴 +4.76 kB 🔴 +1.52 kB 🔴 +1.35 kB
assets/saveMesh-CAWWRVfg.js (removed) 4.76 kB 🟢 -4.76 kB 🟢 -1.52 kB 🟢 -1.35 kB
assets/WorkspacePanelContent-BArrPH7h.js (removed) 4.74 kB 🟢 -4.74 kB 🟢 -1.62 kB 🟢 -1.43 kB
assets/WorkspacePanelContent-DjT2Asx8.js (new) 4.74 kB 🔴 +4.74 kB 🔴 +1.62 kB 🔴 +1.43 kB
assets/ValueControlPopover-BL8oC2hp.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.55 kB 🟢 -1.38 kB
assets/ValueControlPopover-DMSgpQly.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.55 kB 🔴 +1.38 kB
assets/ApiNodesSignInContent-DBp7me6y.js (removed) 4.08 kB 🟢 -4.08 kB 🟢 -1.31 kB 🟢 -1.15 kB
assets/ApiNodesSignInContent-Dih8nk6S.js (new) 4.08 kB 🔴 +4.08 kB 🔴 +1.31 kB 🔴 +1.17 kB
assets/DeleteWorkspaceDialogContent-CIEeanEF.js (removed) 3.84 kB 🟢 -3.84 kB 🟢 -1.44 kB 🟢 -1.24 kB
assets/DeleteWorkspaceDialogContent-GHzEk3CX.js (new) 3.84 kB 🔴 +3.84 kB 🔴 +1.44 kB 🔴 +1.24 kB
assets/RemoveMemberDialogContent-BMzddC_V.js (new) 3.76 kB 🔴 +3.76 kB 🔴 +1.38 kB 🔴 +1.2 kB
assets/RemoveMemberDialogContent-BXyLZSBI.js (removed) 3.76 kB 🟢 -3.76 kB 🟢 -1.39 kB 🟢 -1.2 kB
assets/RevokeInviteDialogContent-DQ5_0XwV.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.4 kB 🔴 +1.21 kB
assets/RevokeInviteDialogContent-Dsd7BFly.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.4 kB 🟢 -1.22 kB
assets/LeaveWorkspaceDialogContent-BjG2tIX_.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.39 kB 🔴 +1.19 kB
assets/LeaveWorkspaceDialogContent-Bua5_QXj.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.39 kB 🟢 -1.19 kB
assets/InviteMemberUpsellDialogContent-hUCdgV6w.js (new) 3.47 kB 🔴 +3.47 kB 🔴 +1.24 kB 🔴 +1.08 kB
assets/InviteMemberUpsellDialogContent-Udv3pzls.js (removed) 3.47 kB 🟢 -3.47 kB 🟢 -1.24 kB 🟢 -1.09 kB
assets/workspaceCheckoutTelemetry-CgYz0fKE.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.52 kB 🔴 +1.33 kB
assets/workspaceCheckoutTelemetry-fxTPsrQt.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.52 kB 🟢 -1.33 kB
assets/GlobalToast-BZhAQC5x.js (new) 3.25 kB 🔴 +3.25 kB 🔴 +1.3 kB 🔴 +1.16 kB
assets/Media3DTop-BfuMGdf5.js (new) 3.21 kB 🔴 +3.21 kB 🔴 +1.26 kB 🔴 +1.1 kB
assets/Media3DTop-BQDpqhGn.js (removed) 3.21 kB 🟢 -3.21 kB 🟢 -1.27 kB 🟢 -1.1 kB
assets/GlobalToast-DWIK520Q.js (removed) 3 kB 🟢 -3 kB 🟢 -1.22 kB 🟢 -1.05 kB
assets/load3dAdvanced-BneDsmxD.js (removed) 2.82 kB 🟢 -2.82 kB 🟢 -1.1 kB 🟢 -954 B
assets/load3dAdvanced-C8ERTb6j.js (new) 2.82 kB 🔴 +2.82 kB 🔴 +1.09 kB 🔴 +957 B
assets/SubscribeToRun-BXkUP1Qf.js (removed) 2.39 kB 🟢 -2.39 kB 🟢 -1.03 kB 🟢 -925 B
assets/SubscribeToRun-DLwjIx46.js (new) 2.39 kB 🔴 +2.39 kB 🔴 +1.03 kB 🔴 +893 B
assets/MediaAudioTop-DPOgNpU_.js (removed) 1.62 kB 🟢 -1.62 kB 🟢 -808 B 🟢 -668 B
assets/MediaAudioTop-p5za_Vvx.js (new) 1.62 kB 🔴 +1.62 kB 🔴 +807 B 🔴 +669 B
assets/signInSchema-2Pd5MvA2.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +554 B 🔴 +519 B
assets/signInSchema-BiKe9RrH.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -554 B 🟢 -521 B
assets/cloudSessionCookie-8DV4sGgj.js (new) 933 B 🔴 +933 B 🔴 +432 B 🔴 +377 B
assets/cloudSessionCookie-Ct5hCeUP.js (removed) 933 B 🟢 -933 B 🟢 -433 B 🟢 -378 B
assets/cloudBadges-DzouLYwk.js (new) 922 B 🔴 +922 B 🔴 +518 B 🔴 +446 B
assets/cloudBadges-H81dkMeo.js (removed) 922 B 🟢 -922 B 🟢 -518 B 🟢 -473 B
assets/Load3DAdvanced-C4o3EghS.js (new) 761 B 🔴 +761 B 🔴 +425 B 🔴 +360 B
assets/Load3DAdvanced-H1zeqJK9.js (removed) 761 B 🟢 -761 B 🟢 -424 B 🟢 -359 B
assets/nightlyBadges-BhwNE9Ds.js (new) 411 B 🔴 +411 B 🔴 +274 B 🔴 +272 B
assets/nightlyBadges-CrX7pkx3.js (removed) 411 B 🟢 -411 B 🟢 -272 B 🟢 -266 B
assets/missingModelDownload-C3oPEVqY.js (removed) 371 B 🟢 -371 B 🟢 -204 B 🟢 -174 B
assets/missingModelDownload-Dmvss0J2.js (new) 371 B 🔴 +371 B 🔴 +202 B 🔴 +172 B
assets/Load3dViewerContent-CaL_moKt.js (new) 137 B 🔴 +137 B 🔴 +103 B 🔴 +94 B
assets/Load3dViewerContent-CDu3bJ0b.js (removed) 137 B 🟢 -137 B 🟢 -103 B 🟢 -86 B
assets/Load3DAdvanced-CfW6ls2A.js (removed) 122 B 🟢 -122 B 🟢 -97 B 🟢 -87 B
assets/Load3DAdvanced-DZYf-oaD.js (new) 122 B 🔴 +122 B 🔴 +97 B 🔴 +93 B
assets/WidgetLegacy-B9esWCs4.js (new) 117 B 🔴 +117 B 🔴 +106 B 🔴 +105 B
assets/WidgetLegacy-Dhnyz6y5.js (removed) 117 B 🟢 -117 B 🟢 -106 B 🟢 -103 B
assets/workflowDraftStoreV2-Cv2by6Gl.js (new) 112 B 🔴 +112 B 🔴 +101 B 🔴 +110 B
assets/workflowDraftStoreV2-DC2FDyjt.js (removed) 112 B 🟢 -112 B 🟢 -101 B 🟢 -106 B
assets/Load3D-BNj_9SGv.js (removed) 98 B 🟢 -98 B 🟢 -89 B 🟢 -92 B
assets/Load3D-CuBWkA0i.js (new) 98 B 🔴 +98 B 🔴 +89 B 🔴 +96 B
assets/i18n-2pPDpfWh.js (removed) 97 B 🟢 -97 B 🟢 -92 B 🟢 -89 B
assets/i18n-BiMluV80.js (new) 97 B 🔴 +97 B 🔴 +92 B 🔴 +85 B
assets/changeTracker-CMYbFyB5.js (removed) 91 B 🟢 -91 B 🟢 -93 B 🟢 -90 B
assets/changeTracker-zVdk__Rc.js (new) 91 B 🔴 +91 B 🔴 +93 B 🔴 +88 B

Status: 76 added / 76 removed / 210 unchanged

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 66.8 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 61.5 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 69.9 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 50.7 MB heap
large-graph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 63.7 MB heap
large-graph-pan: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 63.7 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 64.4 MB heap
minimap-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 65.0 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 51.1 MB heap
subgraph-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 67.1 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 58.0 MB heap
subgraph-transition-enter: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 144ms TBT · 94.8 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 80.7 MB heap
vue-large-graph-idle: · 54.5 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 159.4 MB heap
vue-large-graph-pan: · 55.4 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 408ms TBT · 162.7 MB heap
workflow-execution: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 65.4 MB heap

⚠️ 11 regressions detected

Show regressions
Metric Baseline PR (median) Δ Sig
canvas-idle: task duration 528ms 654ms +24% ⚠️ z=8.3
canvas-zoom-sweep: task duration 424ms 476ms +12% ⚠️ z=6.5
dom-widget-clipping: task duration 385ms 420ms +9% ⚠️ z=3.4
large-graph-idle: task duration 725ms 857ms +18% ⚠️ z=5.8
large-graph-idle: script duration 104ms 147ms +41% ⚠️ z=4.2
large-graph-pan: task duration 1311ms 1455ms +11% ⚠️ z=8.7
large-graph-pan: script duration 412ms 490ms +19% ⚠️ z=4.2
minimap-idle: task duration 726ms 832ms +15% ⚠️ z=6.4
minimap-idle: script duration 106ms 141ms +33% ⚠️ z=4.4
subgraph-dom-widget-clipping: task duration 416ms 456ms +10% ⚠️ z=4.2
subgraph-idle: task duration 546ms 621ms +14% ⚠️ z=8.0
All metrics
Metric Baseline PR (median) Δ Sig
canvas-idle: avg frame time 17ms 17ms +0% z=-0.5
canvas-idle: p95 frame time 17ms 17ms +1%
canvas-idle: layout duration 0ms 0ms +0%
canvas-idle: style recalc duration 8ms 9ms +12% z=-2.1
canvas-idle: layout count 0 0 +0%
canvas-idle: style recalc count 9 9 -6% z=-4.7
canvas-idle: task duration 528ms 654ms +24% ⚠️ z=8.3
canvas-idle: script duration 24ms 27ms +11% z=0.8
canvas-idle: TBT 0ms 0ms +0%
canvas-idle: heap used 67.0 MB 66.8 MB -0%
canvas-idle: DOM nodes 18 17 -6% z=-4.4
canvas-idle: event listeners 4 5 +25% z=-1.4
canvas-mouse-sweep: avg frame time 17ms 17ms +0% z=-0.4
canvas-mouse-sweep: p95 frame time 17ms 17ms +0%
canvas-mouse-sweep: layout duration 4ms 4ms -1% z=0.8
canvas-mouse-sweep: style recalc duration 37ms 45ms +20% z=0.7
canvas-mouse-sweep: layout count 12 12 +0%
canvas-mouse-sweep: style recalc count 74 76 +3% z=-1.1
canvas-mouse-sweep: task duration 908ms 960ms +6% z=1.6
canvas-mouse-sweep: script duration 118ms 137ms +17% z=0.2
canvas-mouse-sweep: TBT 0ms 0ms +0%
canvas-mouse-sweep: heap used 47.9 MB 61.5 MB +29%
canvas-mouse-sweep: DOM nodes -279 59 -121% z=-1.3
canvas-mouse-sweep: event listeners -153 4 -103% z=-1.1
canvas-zoom-sweep: avg frame time 17ms 17ms -0% z=-0.3
canvas-zoom-sweep: p95 frame time 17ms 17ms -1%
canvas-zoom-sweep: layout duration 1ms 1ms -14% z=1.0
canvas-zoom-sweep: style recalc duration 18ms 20ms +11% z=0.7
canvas-zoom-sweep: layout count 6 6 +0%
canvas-zoom-sweep: style recalc count 31 33 +5% z=2.7
canvas-zoom-sweep: task duration 424ms 476ms +12% ⚠️ z=6.5
canvas-zoom-sweep: script duration 26ms 28ms +10% z=0.4
canvas-zoom-sweep: TBT 0ms 0ms +0%
canvas-zoom-sweep: heap used 69.5 MB 69.9 MB +0%
canvas-zoom-sweep: DOM nodes 77 78 +1% z=-1.6
canvas-zoom-sweep: event listeners 19 19 +0% z=-0.9
dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.5
dom-widget-clipping: p95 frame time 17ms 17ms -1%
dom-widget-clipping: layout duration 0ms 0ms +0%
dom-widget-clipping: style recalc duration 8ms 7ms -11% z=-3.1
dom-widget-clipping: layout count 0 0 +0%
dom-widget-clipping: style recalc count 12 10 -21% z=-7.2
dom-widget-clipping: task duration 385ms 420ms +9% ⚠️ z=3.4
dom-widget-clipping: script duration 57ms 65ms +15% z=-0.7
dom-widget-clipping: TBT 0ms 0ms +0%
dom-widget-clipping: heap used 50.8 MB 50.7 MB -0%
dom-widget-clipping: DOM nodes 20 15 -25% z=-5.0
dom-widget-clipping: event listeners 0 2 variance too high
large-graph-idle: avg frame time 17ms 17ms +0% z=-0.2
large-graph-idle: p95 frame time 17ms 17ms +0%
large-graph-idle: layout duration 0ms 0ms +0%
large-graph-idle: style recalc duration 7ms 9ms +27% z=-3.2
large-graph-idle: layout count 0 0 +0%
large-graph-idle: style recalc count 8 9 +6% z=-9.9
large-graph-idle: task duration 725ms 857ms +18% ⚠️ z=5.8
large-graph-idle: script duration 104ms 147ms +41% ⚠️ z=4.2
large-graph-idle: TBT 0ms 0ms +0%
large-graph-idle: heap used 62.5 MB 63.7 MB +2%
large-graph-idle: DOM nodes -282 -284 +1% z=-341.5
large-graph-idle: event listeners -179 -179 +0% z=-33.6
large-graph-pan: avg frame time 17ms 17ms -0% z=-0.2
large-graph-pan: p95 frame time 17ms 17ms +0%
large-graph-pan: layout duration 0ms 0ms +0%
large-graph-pan: style recalc duration 16ms 14ms -13% z=-4.6
large-graph-pan: layout count 0 0 +0%
large-graph-pan: style recalc count 68 68 -1% z=-3.2
large-graph-pan: task duration 1311ms 1455ms +11% ⚠️ z=8.7
large-graph-pan: script duration 412ms 490ms +19% ⚠️ z=4.2
large-graph-pan: TBT 0ms 0ms +0%
large-graph-pan: heap used 59.7 MB 63.7 MB +7%
large-graph-pan: DOM nodes -285 -284 -1% z=-183.3
large-graph-pan: event listeners -149 -149 +0% z=-185.9
large-graph-zoom: avg frame time 17ms 17ms -0%
large-graph-zoom: p95 frame time 17ms 17ms -0%
large-graph-zoom: layout duration 10ms 8ms -16%
large-graph-zoom: style recalc duration 18ms 16ms -10%
large-graph-zoom: layout count 60 60 +0%
large-graph-zoom: style recalc count 65 65 -1%
large-graph-zoom: task duration 1521ms 1779ms +17%
large-graph-zoom: script duration 509ms 646ms +27%
large-graph-zoom: TBT 0ms 0ms +0%
large-graph-zoom: heap used 83.3 MB 64.4 MB -23%
large-graph-zoom: DOM nodes 12 -287 -2488%
large-graph-zoom: event listeners 8 -151 -1988%
minimap-idle: avg frame time 17ms 17ms +0% z=0.1
minimap-idle: p95 frame time 17ms 17ms -1%
minimap-idle: layout duration 0ms 0ms +0%
minimap-idle: style recalc duration 6ms 7ms +15% z=-2.6
minimap-idle: layout count 0 0 +0%
minimap-idle: style recalc count 7 8 +7% z=-3.0
minimap-idle: task duration 726ms 832ms +15% ⚠️ z=6.4
minimap-idle: script duration 106ms 141ms +33% ⚠️ z=4.4
minimap-idle: TBT 0ms 0ms +0%
minimap-idle: heap used 64.5 MB 65.0 MB +1%
minimap-idle: DOM nodes -285 -284 -1% z=-221.3
minimap-idle: event listeners -149 -150 +1% z=-234.1
subgraph-dom-widget-clipping: avg frame time 17ms 17ms -0% z=-0.9
subgraph-dom-widget-clipping: p95 frame time 17ms 17ms -0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms +0%
subgraph-dom-widget-clipping: style recalc duration 11ms 13ms +11% z=-0.2
subgraph-dom-widget-clipping: layout count 0 0 +0%
subgraph-dom-widget-clipping: style recalc count 47 46 -2% z=-3.3
subgraph-dom-widget-clipping: task duration 416ms 456ms +10% ⚠️ z=4.2
subgraph-dom-widget-clipping: script duration 121ms 132ms +9% z=0.5
subgraph-dom-widget-clipping: TBT 0ms 0ms +0%
subgraph-dom-widget-clipping: heap used 51.3 MB 51.1 MB -0%
subgraph-dom-widget-clipping: DOM nodes 20 18 -10% z=-3.7
subgraph-dom-widget-clipping: event listeners 8 8 +0% z=-1.4
subgraph-idle: avg frame time 17ms 17ms -0% z=0.4
subgraph-idle: p95 frame time 17ms 17ms -0%
subgraph-idle: layout duration 0ms 0ms +0%
subgraph-idle: style recalc duration 9ms 10ms +13% z=-0.9
subgraph-idle: layout count 0 0 +0%
subgraph-idle: style recalc count 10 10 -5% z=-2.1
subgraph-idle: task duration 546ms 621ms +14% ⚠️ z=8.0
subgraph-idle: script duration 21ms 24ms +15% z=1.6
subgraph-idle: TBT 0ms 0ms +0%
subgraph-idle: heap used 44.1 MB 67.1 MB +52%
subgraph-idle: DOM nodes -280 19 -107% z=-1.9
subgraph-idle: event listeners -153 4 -103% variance too high
subgraph-mouse-sweep: avg frame time 17ms 17ms +0% z=0.4
subgraph-mouse-sweep: p95 frame time 17ms 17ms -0%
subgraph-mouse-sweep: layout duration 5ms 5ms -3% z=0.2
subgraph-mouse-sweep: style recalc duration 39ms 41ms +5% z=-0.4
subgraph-mouse-sweep: layout count 16 16 +0%
subgraph-mouse-sweep: style recalc count 77 77 -1% z=-1.9
subgraph-mouse-sweep: task duration 828ms 883ms +7% z=1.7
subgraph-mouse-sweep: script duration 94ms 104ms +11% z=0.6
subgraph-mouse-sweep: TBT 0ms 0ms +0%
subgraph-mouse-sweep: heap used 57.9 MB 58.0 MB +0%
subgraph-mouse-sweep: DOM nodes 59 62 +5% z=-2.2
subgraph-mouse-sweep: event listeners 4 4 +0% variance too high
subgraph-transition-enter: avg frame time 17ms 17ms +0%
subgraph-transition-enter: p95 frame time 17ms 17ms -0%
subgraph-transition-enter: layout duration 11ms 13ms +19%
subgraph-transition-enter: style recalc duration 29ms 32ms +13%
subgraph-transition-enter: layout count 13 13 +0%
subgraph-transition-enter: style recalc count 17 17 +0%
subgraph-transition-enter: task duration 941ms 1060ms +13%
subgraph-transition-enter: script duration 38ms 43ms +12%
subgraph-transition-enter: TBT 135ms 144ms +7%
subgraph-transition-enter: heap used 94.5 MB 94.8 MB +0%
subgraph-transition-enter: DOM nodes 13673 13673 +0%
subgraph-transition-enter: event listeners 2375 2375 +0%
viewport-pan-sweep: avg frame time 17ms 17ms -0%
viewport-pan-sweep: p95 frame time 17ms 17ms +0%
viewport-pan-sweep: layout duration 0ms 0ms +0%
viewport-pan-sweep: style recalc duration 47ms 40ms -15%
viewport-pan-sweep: layout count 0 0 +0%
viewport-pan-sweep: style recalc count 249 249 +0%
viewport-pan-sweep: task duration 4624ms 5304ms +15%
viewport-pan-sweep: script duration 1360ms 1664ms +22%
viewport-pan-sweep: TBT 0ms 0ms +0%
viewport-pan-sweep: heap used 68.1 MB 80.7 MB +19%
viewport-pan-sweep: DOM nodes -283 -284 +0%
viewport-pan-sweep: event listeners -133 -145 +9%
vue-large-graph-idle: avg frame time 18ms 18ms +3%
vue-large-graph-idle: p95 frame time 17ms 17ms +1%
vue-large-graph-idle: layout duration 0ms 0ms +0%
vue-large-graph-idle: style recalc duration 0ms 0ms +0%
vue-large-graph-idle: layout count 0 0 +0%
vue-large-graph-idle: style recalc count 0 0 +0%
vue-large-graph-idle: task duration 15213ms 17678ms +16%
vue-large-graph-idle: script duration 551ms 620ms +12%
vue-large-graph-idle: TBT 0ms 0ms +0%
vue-large-graph-idle: heap used 158.3 MB 159.4 MB +1%
vue-large-graph-idle: DOM nodes -8312 -8312 +0%
vue-large-graph-idle: event listeners -16387 -16387 +0%
vue-large-graph-pan: avg frame time 18ms 18ms +2%
vue-large-graph-pan: p95 frame time 17ms 17ms -0%
vue-large-graph-pan: layout duration 0ms 0ms +0%
vue-large-graph-pan: style recalc duration 20ms 21ms +7%
vue-large-graph-pan: layout count 0 0 +0%
vue-large-graph-pan: style recalc count 123 151 +22%
vue-large-graph-pan: task duration 17975ms 21470ms +19%
vue-large-graph-pan: script duration 869ms 983ms +13%
vue-large-graph-pan: TBT 123ms 408ms +232%
vue-large-graph-pan: heap used 156.8 MB 162.7 MB +4%
vue-large-graph-pan: DOM nodes -8312 -8312 +0%
vue-large-graph-pan: event listeners -16385 -16381 -0%
workflow-execution: avg frame time 17ms 17ms -0% z=0.1
workflow-execution: p95 frame time 17ms 17ms -1%
workflow-execution: layout duration 1ms 1ms -23% z=-5.7
workflow-execution: style recalc duration 19ms 24ms +24% z=-0.2
workflow-execution: layout count 3 3 +0% z=-3.6
workflow-execution: style recalc count 13 13 +0% z=-2.3
workflow-execution: task duration 122ms 129ms +6% z=0.6
workflow-execution: script duration 10ms 12ms +18% z=-5.6
workflow-execution: TBT 0ms 0ms +0%
workflow-execution: heap used 65.5 MB 65.4 MB -0%
workflow-execution: DOM nodes 123 128 +4% z=-4.7
workflow-execution: event listeners 97 99 +2% z=10.8
Historical variance (last 15 runs)
Metric μ σ CV
canvas-idle: avg frame time 17ms 0ms 0.0%
canvas-idle: layout duration 0ms 0ms 0.0%
canvas-idle: style recalc duration 11ms 1ms 8.2%
canvas-idle: layout count 0 0 0.0%
canvas-idle: style recalc count 11 1 5.0%
canvas-idle: task duration 395ms 31ms 7.9%
canvas-idle: script duration 25ms 2ms 8.8%
canvas-idle: TBT 0ms 0ms 0.0%
canvas-idle: DOM nodes 23 1 5.6%
canvas-idle: event listeners 12 5 40.9%
canvas-mouse-sweep: avg frame time 17ms 0ms 0.0%
canvas-mouse-sweep: layout duration 4ms 0ms 5.4%
canvas-mouse-sweep: style recalc duration 43ms 3ms 7.4%
canvas-mouse-sweep: layout count 12 0 0.0%
canvas-mouse-sweep: style recalc count 79 2 3.0%
canvas-mouse-sweep: task duration 865ms 58ms 6.7%
canvas-mouse-sweep: script duration 136ms 6ms 4.8%
canvas-mouse-sweep: TBT 0ms 0ms 0.0%
canvas-mouse-sweep: DOM nodes 62 3 4.2%
canvas-mouse-sweep: event listeners 8 4 49.4%
canvas-zoom-sweep: avg frame time 17ms 0ms 0.0%
canvas-zoom-sweep: layout duration 1ms 0ms 7.0%
canvas-zoom-sweep: style recalc duration 19ms 2ms 8.0%
canvas-zoom-sweep: layout count 6 0 0.0%
canvas-zoom-sweep: style recalc count 31 0 1.5%
canvas-zoom-sweep: task duration 327ms 23ms 7.1%
canvas-zoom-sweep: script duration 27ms 3ms 11.1%
canvas-zoom-sweep: TBT 0ms 0ms 0.0%
canvas-zoom-sweep: DOM nodes 79 1 1.0%
canvas-zoom-sweep: event listeners 24 5 21.8%
dom-widget-clipping: avg frame time 17ms 0ms 0.0%
dom-widget-clipping: layout duration 0ms 0ms 0.0%
dom-widget-clipping: style recalc duration 10ms 1ms 8.0%
dom-widget-clipping: layout count 0 0 0.0%
dom-widget-clipping: style recalc count 13 0 3.8%
dom-widget-clipping: task duration 365ms 16ms 4.5%
dom-widget-clipping: script duration 68ms 3ms 4.8%
dom-widget-clipping: TBT 0ms 0ms 0.0%
dom-widget-clipping: DOM nodes 22 1 6.4%
dom-widget-clipping: event listeners 8 6 81.2%
large-graph-idle: avg frame time 17ms 0ms 0.0%
large-graph-idle: layout duration 0ms 0ms 0.0%
large-graph-idle: style recalc duration 12ms 1ms 8.6%
large-graph-idle: layout count 0 0 0.0%
large-graph-idle: style recalc count 12 0 2.7%
large-graph-idle: task duration 542ms 54ms 10.0%
large-graph-idle: script duration 102ms 11ms 10.3%
large-graph-idle: TBT 0ms 0ms 0.0%
large-graph-idle: DOM nodes 25 1 3.7%
large-graph-idle: event listeners 26 6 23.2%
large-graph-pan: avg frame time 17ms 0ms 0.0%
large-graph-pan: layout duration 0ms 0ms 0.0%
large-graph-pan: style recalc duration 17ms 1ms 4.6%
large-graph-pan: layout count 0 0 0.0%
large-graph-pan: style recalc count 70 1 0.9%
large-graph-pan: task duration 1082ms 43ms 4.0%
large-graph-pan: script duration 408ms 20ms 4.8%
large-graph-pan: TBT 0ms 0ms 0.0%
large-graph-pan: DOM nodes 19 2 8.7%
large-graph-pan: event listeners 5 1 16.8%
minimap-idle: avg frame time 17ms 0ms 0.0%
minimap-idle: layout duration 0ms 0ms 0.0%
minimap-idle: style recalc duration 10ms 1ms 8.6%
minimap-idle: layout count 0 0 0.0%
minimap-idle: style recalc count 10 1 7.1%
minimap-idle: task duration 527ms 47ms 9.0%
minimap-idle: script duration 98ms 10ms 10.1%
minimap-idle: TBT 0ms 0ms 0.0%
minimap-idle: DOM nodes 19 1 7.1%
minimap-idle: event listeners 5 1 14.4%
subgraph-dom-widget-clipping: avg frame time 17ms 0ms 0.0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms 0.0%
subgraph-dom-widget-clipping: style recalc duration 13ms 1ms 7.4%
subgraph-dom-widget-clipping: layout count 0 0 0.0%
subgraph-dom-widget-clipping: style recalc count 48 1 1.2%
subgraph-dom-widget-clipping: task duration 378ms 18ms 4.9%
subgraph-dom-widget-clipping: script duration 128ms 6ms 4.9%
subgraph-dom-widget-clipping: TBT 0ms 0ms 0.0%
subgraph-dom-widget-clipping: DOM nodes 22 1 5.0%
subgraph-dom-widget-clipping: event listeners 16 6 36.0%
subgraph-idle: avg frame time 17ms 0ms 0.0%
subgraph-idle: layout duration 0ms 0ms 0.0%
subgraph-idle: style recalc duration 10ms 1ms 7.5%
subgraph-idle: layout count 0 0 0.0%
subgraph-idle: style recalc count 11 1 6.0%
subgraph-idle: task duration 370ms 31ms 8.5%
subgraph-idle: script duration 20ms 3ms 13.2%
subgraph-idle: TBT 0ms 0ms 0.0%
subgraph-idle: DOM nodes 22 1 6.9%
subgraph-idle: event listeners 10 7 64.5%
subgraph-mouse-sweep: avg frame time 17ms 0ms 0.0%
subgraph-mouse-sweep: layout duration 5ms 0ms 6.8%
subgraph-mouse-sweep: style recalc duration 42ms 3ms 7.8%
subgraph-mouse-sweep: layout count 16 0 0.0%
subgraph-mouse-sweep: style recalc count 80 2 2.4%
subgraph-mouse-sweep: task duration 766ms 69ms 9.0%
subgraph-mouse-sweep: script duration 101ms 7ms 6.5%
subgraph-mouse-sweep: TBT 0ms 0ms 0.0%
subgraph-mouse-sweep: DOM nodes 67 2 3.3%
subgraph-mouse-sweep: event listeners 8 4 52.6%
workflow-execution: avg frame time 17ms 0ms 0.0%
workflow-execution: layout duration 2ms 0ms 9.4%
workflow-execution: style recalc duration 24ms 2ms 9.1%
workflow-execution: layout count 5 1 11.0%
workflow-execution: style recalc count 18 2 11.5%
workflow-execution: task duration 123ms 11ms 8.8%
workflow-execution: script duration 29ms 3ms 10.2%
workflow-execution: TBT 0ms 0ms 0.0%
workflow-execution: DOM nodes 161 7 4.4%
workflow-execution: event listeners 52 4 8.4%
Trend (last 15 commits on main)
Metric Trend Dir Latest
canvas-idle: avg frame time ▆▃▆▁▆▃▆█▆▆▄▃▃▄▃ ➡️ 17ms
canvas-idle: p95 frame time ➡️ NaNms
canvas-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: style recalc duration ▇▇▆▆▃█▄▃▄▃▇▄▁▆▇ ➡️ 11ms
canvas-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
canvas-idle: style recalc count █▃▅▂▅▆▃▁▂▁▂▅▆▅▆ ➡️ 12
canvas-idle: task duration ▃▃▃▆▂▃▃▅▆▂█▃▁▃▃ ➡️ 391ms
canvas-idle: script duration ▄▃▅▇▂▅▃▆▇▅█▄▁▅▆ ➡️ 27ms
canvas-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: heap used ➡️ NaN MB
canvas-idle: DOM nodes █▇▆▅▃▇▃▁▂▂▅▆▆▆▇ ➡️ 24
canvas-idle: event listeners ▅█▅▄▁▅▁▁▁▄▅▅▁▅▄ 📉 11
canvas-mouse-sweep: avg frame time ▆█▆▃▁▃▁▆▆▁▃▆▆▃▃ ➡️ 17ms
canvas-mouse-sweep: p95 frame time ➡️ NaNms
canvas-mouse-sweep: layout duration ▁▃▂▄▁▂▁▃▆▂█▇▆▄▃ ➡️ 4ms
canvas-mouse-sweep: style recalc duration ▄▄▂▄▁▂▃▃▅▄█▆▂▄▄ ➡️ 43ms
canvas-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 12
canvas-mouse-sweep: style recalc count █▅▄▃▂▂▁▄▄▅▆▅▂▇▄ ➡️ 79
canvas-mouse-sweep: task duration █▆▄▂▂▃▂▄▄▅█▆▁▆▄ ➡️ 868ms
canvas-mouse-sweep: script duration ▄▅▄▆▄▆▆▆▅▅█▆▁▅▆ ➡️ 139ms
canvas-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-mouse-sweep: heap used ➡️ NaN MB
canvas-mouse-sweep: DOM nodes █▅▃▃▁▂▂▃▂▄▆▅▃▅▅ ➡️ 64
canvas-mouse-sweep: event listeners █▁▁▁▁▁▇▁▁▁██▇▁█ 📈 13
canvas-zoom-sweep: avg frame time ▅▅█▄▅▁▁▁▅▁▁▅▄▅▁ ➡️ 17ms
canvas-zoom-sweep: p95 frame time ➡️ NaNms
canvas-zoom-sweep: layout duration ▆▅▅▄▁▁█▅▃▅▇▆▁▂▆ ➡️ 1ms
canvas-zoom-sweep: style recalc duration ▆▅▄▆▅▃█▆▇▅▇▄▁▃▅ ➡️ 20ms
canvas-zoom-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 6
canvas-zoom-sweep: style recalc count ▁▁▃▄▆▃▆█▄▄▆▁▆▁▆ ➡️ 32
canvas-zoom-sweep: task duration ▄▂▁▇▂▂▄▅▆▃█▄▁▁▅ ➡️ 338ms
canvas-zoom-sweep: script duration ▃▃▂▇▂▂▅▇▆▅█▄▁▂▆ ➡️ 30ms
canvas-zoom-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-zoom-sweep: heap used ➡️ NaN MB
canvas-zoom-sweep: DOM nodes ▄▃▁▅█▁▃▆▄▅▅▃▃▄▃ ➡️ 79
canvas-zoom-sweep: event listeners ▁▁▂▅█▂▁▅▁▅▅▄▁▅▁ ➡️ 19
dom-widget-clipping: avg frame time ▂▄▅▅▂▄█▇▅▇▇▅▅▁▇ ➡️ 17ms
dom-widget-clipping: p95 frame time ➡️ NaNms
dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: style recalc duration ▆▆▂▆▄▃██▄▁▆▇▆▃▅ ➡️ 10ms
dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
dom-widget-clipping: style recalc count ▇█▅█▅▄█▇▇▁▇▄▇▂▅ ➡️ 13
dom-widget-clipping: task duration ▃▃▁▅▄▃▅▆▅▂▇█▁▅▅ ➡️ 371ms
dom-widget-clipping: script duration ▅▄▄▆▆▅▇▇▆▃█▇▁▇▇ ➡️ 71ms
dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: heap used ➡️ NaN MB
dom-widget-clipping: DOM nodes ▇▇▄▇▅▄█▇▅▁▅▄▇▃▄ ➡️ 21
dom-widget-clipping: event listeners ▅▅▅▅▁▅██▁▁▁▁█▁▁ 📉 2
large-graph-idle: avg frame time ▅▅▅▅▅▂▁▂▄▅▄▂▂▅█ ➡️ 17ms
large-graph-idle: p95 frame time ➡️ NaNms
large-graph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: style recalc duration ▅▅▅▆▄▅▃▄▅▅▆█▁▄▆ ➡️ 13ms
large-graph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-idle: style recalc count █▆█▃▃▁▃▆▃▆▆▃▆██ ➡️ 12
large-graph-idle: task duration ▂▃▂▆▂▃▃▇▅▃██▁▂▅ ➡️ 569ms
large-graph-idle: script duration ▄▅▄▆▄▅▅▇▆▅█▆▁▃▆ ➡️ 110ms
large-graph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: heap used ➡️ NaN MB
large-graph-idle: DOM nodes ▆█▅▂▅▃▁▂▃▅▅▆▂▆▅ ➡️ 25
large-graph-idle: event listeners ███▇██▄▁▄▇▇█▂█▇ ➡️ 29
large-graph-pan: avg frame time ▆▃▃▆█▃▁█▆▆▆▆█▁▆ ➡️ 17ms
large-graph-pan: p95 frame time ➡️ NaNms
large-graph-pan: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: style recalc duration ▃▂▄▄▁▅▂▂▁▄▄█▃▁▂ ➡️ 17ms
large-graph-pan: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-pan: style recalc count ▆▃█▂▃▂▂▂▁▇▅▃█▆▃ ➡️ 69
large-graph-pan: task duration ▄▃▄▆▄▄▄▆▄▄█▆▁▂▅ ➡️ 1100ms
large-graph-pan: script duration ▅▄▅▆▆▅▄▆▄▅█▄▁▄▅ ➡️ 413ms
large-graph-pan: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: heap used ➡️ NaN MB
large-graph-pan: DOM nodes ▅▃▆▂▄▁▃▁▁▅▁▂█▅▂ ➡️ 18
large-graph-pan: event listeners █▆█▁▁▆▁▁▃▆▁▃██▃ ➡️ 5
minimap-idle: avg frame time ▃▆▆▃█▁█▆▆▃▃▆█▆█ ➡️ 17ms
minimap-idle: p95 frame time ➡️ NaNms
minimap-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: style recalc duration ▄█▁█▅▅█▅▅▃▅▁▁▄▆ ➡️ 10ms
minimap-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
minimap-idle: style recalc count ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 9
minimap-idle: task duration ▃▄▁▅▁▃▄▅▇▃█▅▁▁▅ ➡️ 547ms
minimap-idle: script duration ▄▆▃▇▃▅▆▆▇▅█▅▁▃▆ ➡️ 106ms
minimap-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: heap used ➡️ NaN MB
minimap-idle: DOM nodes ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 19
minimap-idle: event listeners ▃▃▆▁▁▁▃▁▁▆▁▃█▆▁ ➡️ 4
subgraph-dom-widget-clipping: avg frame time ▅▄▄▄▄▄█▄▄▄▃▁▆▃▃ ➡️ 17ms
subgraph-dom-widget-clipping: p95 frame time ➡️ NaNms
subgraph-dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: style recalc duration ▂▄▃▅▅▃▂▅▇▃▄█▁▄▆ ➡️ 14ms
subgraph-dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-dom-widget-clipping: style recalc count ▇█▆▃▆▃▁▆█▇▃▆▇█▅ ➡️ 48
subgraph-dom-widget-clipping: task duration ▂▃▃▆▅▅▂▅█▂▆█▁▂▇ ➡️ 398ms
subgraph-dom-widget-clipping: script duration ▃▃▃▄▅▅▂▄█▂▅▇▁▂▅ ➡️ 131ms
subgraph-dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: heap used ➡️ NaN MB
subgraph-dom-widget-clipping: DOM nodes ▅▇▅▂▅▂▁▅▅▅▁▇▅█▄ ➡️ 22
subgraph-dom-widget-clipping: event listeners ▅▅▅▂▅▁▅██▁▁█▅█▅ 📈 16
subgraph-idle: avg frame time ▆▆█▁▆▃▆▆▆▃▆▁▃▆█ ➡️ 17ms
subgraph-idle: p95 frame time ➡️ NaNms
subgraph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: style recalc duration ▁▇▃▆▂▄▂▃▃▆▆▄▃▇█ ➡️ 12ms
subgraph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-idle: style recalc count ▃▆▃▃▂▅▁▂▁▆▃▃██▇ ➡️ 12
subgraph-idle: task duration ▁▃▁▇▁▁▃▆▅▂█▅▁▁▄ ➡️ 378ms
subgraph-idle: script duration ▁▃▂▇▁▂▃▇▆▂█▅▂▁▅ ➡️ 22ms
subgraph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: heap used ➡️ NaN MB
subgraph-idle: DOM nodes ▃▅▃▂▁▄▁▂▁▅▃▂▇█▇ ➡️ 24
subgraph-idle: event listeners ▁▅▁▁▁▁▁▁▁▅▄▁███ 📈 21
subgraph-mouse-sweep: avg frame time ▅▄▁▃▃▄▆▄▆▃▃█▁▃▃ ➡️ 17ms
subgraph-mouse-sweep: p95 frame time ➡️ NaNms
subgraph-mouse-sweep: layout duration ▁▄▄▄▃▃▅▅▅▂█▇▂▃▆ ➡️ 5ms
subgraph-mouse-sweep: style recalc duration ▃▂▄▅▂▃▄▅█▃█▆▁▂▅ ➡️ 43ms
subgraph-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 16
subgraph-mouse-sweep: style recalc count ▅▂▅▅▁▄▃▅█▅▆▄▂▄▅ ➡️ 81
subgraph-mouse-sweep: task duration ▃▂▄▅▂▄▄▅▇▄█▆▁▃▅ ➡️ 785ms
subgraph-mouse-sweep: script duration ▄▅▄▇▅▅▆▇▆▅██▁▄▆ ➡️ 105ms
subgraph-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-mouse-sweep: heap used ➡️ NaN MB
subgraph-mouse-sweep: DOM nodes ▅▁▄▅▁▄▃▃█▅▅▄▂▅▃ ➡️ 66
subgraph-mouse-sweep: event listeners ▇▁▂▇▁▂▂▂█▇▂▂▇▇▂ 📈 5
workflow-execution: avg frame time ▆▆▆▄▆▆▃▄▁▄█▆▅▄▆ ➡️ 17ms
workflow-execution: p95 frame time ➡️ NaNms
workflow-execution: layout duration ▁▆▁▃▂▄▃▂▃▃▅█▄▂▅ ➡️ 2ms
workflow-execution: style recalc duration ▃▇▅▇▁▅▆▇█▁██▂▄▆ ➡️ 25ms
workflow-execution: layout count ▁█▂▃▂▃▃▁▃▃▄▃▂▃▂ ➡️ 5
workflow-execution: style recalc count ▃█▅▇▁▄▅▆▅▅▅▅▄▄▂ ➡️ 15
workflow-execution: task duration ▂▅▄▅▁▄▆▆▆▁▇█▁▃▃ ➡️ 120ms
workflow-execution: script duration ▄▃▄▄▃▅▄▅▆▂▇█▁▃▄ ➡️ 29ms
workflow-execution: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
workflow-execution: heap used ➡️ NaN MB
workflow-execution: DOM nodes ▂█▃▆▁▄▃▅▃█▃▃▄▃▁ ➡️ 152
workflow-execution: event listeners ▅███▁▅███▁██▅█▅ ➡️ 49
Raw data
{
  "timestamp": "2026-08-07T20:54:26.595Z",
  "gitSha": "0b9ab96a0ff4435cc05b874c74541735a63a1d1d",
  "branch": "fix/billing-toast-action-required",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2045.7910000000084,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 8.122999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 675.63,
      "heapDeltaBytes": 5831268,
      "heapUsedBytes": 70250580,
      "domNodes": 16,
      "jsHeapTotalBytes": 24903680,
      "scriptDurationMs": 26.416,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-idle",
      "durationMs": 2068.9590000000635,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.767000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 632.729,
      "heapDeltaBytes": 5600240,
      "heapUsedBytes": 69916628,
      "domNodes": 18,
      "jsHeapTotalBytes": 24903680,
      "scriptDurationMs": 27.811,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1913.1659999999897,
      "styleRecalcs": 77,
      "styleRecalcDurationMs": 45.716,
      "layouts": 12,
      "layoutDurationMs": 3.764,
      "taskDurationMs": 961.2149999999999,
      "heapDeltaBytes": 512108,
      "heapUsedBytes": 64862240,
      "domNodes": 60,
      "jsHeapTotalBytes": 25165824,
      "scriptDurationMs": 136.79799999999997,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1873.578000000066,
      "styleRecalcs": 75,
      "styleRecalcDurationMs": 44.278,
      "layouts": 12,
      "layoutDurationMs": 3.778,
      "taskDurationMs": 959.195,
      "heapDeltaBytes": -26436,
      "heapUsedBytes": 64169756,
      "domNodes": 58,
      "jsHeapTotalBytes": 24903680,
      "scriptDurationMs": 137.464,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1751.2459999999805,
      "styleRecalcs": 31,
      "styleRecalcDurationMs": 18.772000000000002,
      "layouts": 6,
      "layoutDurationMs": 0.6739999999999999,
      "taskDurationMs": 475.576,
      "heapDeltaBytes": 8841956,
      "heapUsedBytes": 73268160,
      "domNodes": 75,
      "jsHeapTotalBytes": 24379392,
      "scriptDurationMs": 27.377000000000002,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1772.4499999999352,
      "styleRecalcs": 34,
      "styleRecalcDurationMs": 21.768000000000004,
      "layouts": 6,
      "layoutDurationMs": 0.6990000000000002,
      "taskDurationMs": 476.753,
      "heapDeltaBytes": 8645212,
      "heapUsedBytes": 73254348,
      "domNodes": 81,
      "jsHeapTotalBytes": 24903680,
      "scriptDurationMs": 29.402,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 705.6790000000319,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.471999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 420.77899999999994,
      "heapDeltaBytes": -11497640,
      "heapUsedBytes": 53097284,
      "domNodes": 14,
      "jsHeapTotalBytes": 25427968,
      "scriptDurationMs": 63.96199999999999,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 668.8789999999472,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 7.370999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 418.958,
      "heapDeltaBytes": -11245848,
      "heapUsedBytes": 53184352,
      "domNodes": 16,
      "jsHeapTotalBytes": 25690112,
      "scriptDurationMs": 66.812,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2017.628000000002,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 8.303,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 876.592,
      "heapDeltaBytes": 6225636,
      "heapUsedBytes": 66831020,
      "domNodes": -286,
      "jsHeapTotalBytes": 3510272,
      "scriptDurationMs": 146.221,
      "eventListeners": -179,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2033.9629999999715,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.524999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 837.5740000000001,
      "heapDeltaBytes": 7096672,
      "heapUsedBytes": 66826968,
      "domNodes": -282,
      "jsHeapTotalBytes": 2985984,
      "scriptDurationMs": 146.929,
      "eventListeners": -179,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2402.1700000000124,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 13.881999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1469.789,
      "heapDeltaBytes": 3912900,
      "heapUsedBytes": 64848364,
      "domNodes": -283,
      "jsHeapTotalBytes": 3440640,
      "scriptDurationMs": 491.89200000000005,
      "eventListeners": -149,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2343.2240000000775,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 13.334999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1441.161,
      "heapDeltaBytes": 7025044,
      "heapUsedBytes": 68691260,
      "domNodes": -284,
      "jsHeapTotalBytes": 3702784,
      "scriptDurationMs": 488.5930000000001,
      "eventListeners": -149,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3711.456999999996,
      "styleRecalcs": 64,
      "styleRecalcDurationMs": 15.595999999999998,
      "layouts": 60,
      "layoutDurationMs": 8.33,
      "taskDurationMs": 1808.3960000000002,
      "heapDeltaBytes": -4539444,
      "heapUsedBytes": 57504004,
      "domNodes": -286,
      "jsHeapTotalBytes": 5607424,
      "scriptDurationMs": 660.111,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3532.447999999931,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 16.316,
      "layouts": 60,
      "layoutDurationMs": 8.107,
      "taskDurationMs": 1749.273,
      "heapDeltaBytes": 15322508,
      "heapUsedBytes": 77545476,
      "domNodes": -287,
      "jsHeapTotalBytes": 6393856,
      "scriptDurationMs": 631.162,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2039.2150000000129,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.347000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 789.5790000000001,
      "heapDeltaBytes": 6992712,
      "heapUsedBytes": 68174632,
      "domNodes": -284,
      "jsHeapTotalBytes": 3510272,
      "scriptDurationMs": 135.25400000000002,
      "eventListeners": -151,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "minimap-idle",
      "durationMs": 2044.7869999999284,
      "styleRecalcs": 6,
      "styleRecalcDurationMs": 5.447,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 875.084,
      "heapDeltaBytes": 6714988,
      "heapUsedBytes": 68164300,
      "domNodes": -283,
      "jsHeapTotalBytes": 3248128,
      "scriptDurationMs": 147.316,
      "eventListeners": -149,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 701.1439999999993,
      "styleRecalcs": 46,
      "styleRecalcDurationMs": 13.812999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 464.995,
      "heapDeltaBytes": -10926264,
      "heapUsedBytes": 53486816,
      "domNodes": 18,
      "jsHeapTotalBytes": 27000832,
      "scriptDurationMs": 136.84799999999998,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 701.5989999999874,
      "styleRecalcs": 46,
      "styleRecalcDurationMs": 11.203000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 447.491,
      "heapDeltaBytes": -10628352,
      "heapUsedBytes": 53737700,
      "domNodes": 18,
      "jsHeapTotalBytes": 25952256,
      "scriptDurationMs": 126.49000000000002,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2022.849000000008,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 10.409000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 615.9689999999999,
      "heapDeltaBytes": 5924812,
      "heapUsedBytes": 70312124,
      "domNodes": 20,
      "jsHeapTotalBytes": 24379392,
      "scriptDurationMs": 22.945999999999998,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2003.2720000000381,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 8.947000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 626.355,
      "heapDeltaBytes": 6009180,
      "heapUsedBytes": 70493936,
      "domNodes": 18,
      "jsHeapTotalBytes": 24379392,
      "scriptDurationMs": 25.885,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1739.689999999996,
      "styleRecalcs": 78,
      "styleRecalcDurationMs": 43.616,
      "layouts": 16,
      "layoutDurationMs": 5.014,
      "taskDurationMs": 856.0530000000001,
      "heapDeltaBytes": -3880044,
      "heapUsedBytes": 60631956,
      "domNodes": 64,
      "jsHeapTotalBytes": 24641536,
      "scriptDurationMs": 104.46900000000001,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1759.2420000000857,
      "styleRecalcs": 75,
      "styleRecalcDurationMs": 38.690000000000005,
      "layouts": 16,
      "layoutDurationMs": 4.538,
      "taskDurationMs": 910.0380000000001,
      "heapDeltaBytes": -3469588,
      "heapUsedBytes": 60943860,
      "domNodes": 60,
      "jsHeapTotalBytes": 25690112,
      "scriptDurationMs": 104.50899999999999,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-transition-enter",
      "durationMs": 1434.00900000006,
      "styleRecalcs": 17,
      "styleRecalcDurationMs": 32.483,
      "layouts": 13,
      "layoutDurationMs": 12.671999999999999,
      "taskDurationMs": 1059.556,
      "heapDeltaBytes": 30647432,
      "heapUsedBytes": 99384920,
      "domNodes": 13673,
      "jsHeapTotalBytes": 15990784,
      "scriptDurationMs": 42.978,
      "eventListeners": 2375,
      "totalBlockingTimeMs": 144,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 9345.786000000033,
      "styleRecalcs": 249,
      "styleRecalcDurationMs": 40.403999999999996,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 5320.048999999999,
      "heapDeltaBytes": 25607160,
      "heapUsedBytes": 85663024,
      "domNodes": -284,
      "jsHeapTotalBytes": 4751360,
      "scriptDurationMs": 1651.213,
      "eventListeners": -159,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 9286.195000000022,
      "styleRecalcs": 249,
      "styleRecalcDurationMs": 39.449,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 5288.817000000001,
      "heapDeltaBytes": 24255740,
      "heapUsedBytes": 83634612,
      "domNodes": -283,
      "jsHeapTotalBytes": 6062080,
      "scriptDurationMs": 1676.473,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.80000000000109
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 17662.14000000002,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 17641.353,
      "heapDeltaBytes": -39335980,
      "heapUsedBytes": 166796360,
      "domNodes": -8312,
      "jsHeapTotalBytes": -7540736,
      "scriptDurationMs": 630.7609999999999,
      "eventListeners": -16387,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 17734.185000000027,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 17713.847,
      "heapDeltaBytes": -40789892,
      "heapUsedBytes": 167485336,
      "domNodes": -8312,
      "jsHeapTotalBytes": -8855552,
      "scriptDurationMs": 609.4300000000001,
      "eventListeners": -16387,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 18.89333333333331,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 21051.84799999995,
      "styleRecalcs": 143,
      "styleRecalcDurationMs": 19.17199999999997,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 21025.058999999997,
      "heapDeltaBytes": -41589604,
      "heapUsedBytes": 176669464,
      "domNodes": -8312,
      "jsHeapTotalBytes": -8396800,
      "scriptDurationMs": 972.3410000000001,
      "eventListeners": -16383,
      "totalBlockingTimeMs": 357,
      "frameDurationMs": 18.333333333333332,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 21949.34599999999,
      "styleRecalcs": 158,
      "styleRecalcDurationMs": 22.713999999999956,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 21915.004,
      "heapDeltaBytes": -41867168,
      "heapUsedBytes": 164515848,
      "domNodes": -8312,
      "jsHeapTotalBytes": -11968512,
      "scriptDurationMs": 992.7839999999999,
      "eventListeners": -16379,
      "totalBlockingTimeMs": 459,
      "frameDurationMs": 17.776666666666763,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "workflow-execution",
      "durationMs": 468.87199999991935,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 24.334999999999997,
      "layouts": 3,
      "layoutDurationMs": 0.667,
      "taskDurationMs": 134.61200000000002,
      "heapDeltaBytes": 5329912,
      "heapUsedBytes": 68620528,
      "domNodes": 132,
      "jsHeapTotalBytes": 4980736,
      "scriptDurationMs": 13.287000000000003,
      "eventListeners": 99,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "workflow-execution",
      "durationMs": 473.07499999999436,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 23.413000000000004,
      "layouts": 3,
      "layoutDurationMs": 0.788,
      "taskDurationMs": 124.294,
      "heapDeltaBytes": 5092908,
      "heapUsedBytes": 68543788,
      "domNodes": 123,
      "jsHeapTotalBytes": 4718592,
      "scriptDurationMs": 11.488999999999999,
      "eventListeners": 99,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    }
  ]
}

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Billing operations now centralize progress-toast handling. Payment verification states replace processing toasts with warning toasts, use new localized messages, display an exclamation icon, and avoid repeated announcements during polling.

Changes

Billing action-required toast flow

Layer / File(s) Summary
Operation toast state
src/platform/workspace/stores/billingOperationStore.ts, src/locales/en/main.json
billingOperationStore creates or replaces processing and action-required toasts for subscription and top-up operations. English messages describe the required payment verification.
Toast presentation and validation
src/components/toast/GlobalToast.vue, src/platform/workspace/stores/billingOperationStore.test.ts
Warning toasts display an exclamation icon. Tests cover action discovery, initial action URLs, cleared action URLs, and duplicate-poll prevention.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BillingOperationStore
  participant ToastSystem
  participant GlobalToast
  BillingOperationStore->>ToastSystem: start billing operation
  ToastSystem->>GlobalToast: show processing or action-required toast
  BillingOperationStore->>ToastSystem: update payment action URL state
  ToastSystem->>GlobalToast: replace the current progress toast
Loading

Possibly related PRs

Suggested labels: released:cloud, cloud/1.49

Suggested reviewers: christian-byrne


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
End-To-End Regression Coverage For Fixes ❓ Inconclusive The changed-file list is available, but the PR title and literal commit subjects are not; the bug-fix signal cannot be verified from the supplied metadata. Provide the PR title and literal commit subjects so the required bug-fix signal can be checked.
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Adr Compliance For Entity/Litegraph Changes ✅ Passed The changed files are limited to toast, locale, and billing-operation store code; none are under litegraph, ecs, or graph-entity paths.
Title check ✅ Passed The title clearly and concisely describes the billing toast fix for payments that require customer action.
Description check ✅ Passed The description covers the change, behavior, review focus, scope, reproduction steps, and verification results.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/billing-toast-action-required

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/toast/GlobalToast.vue`:
- Around line 6-12: Add aria-hidden="true" to both decorative <i> elements in
the toast severity rendering within GlobalToast.vue, including the warning icon
and spinner, so assistive technology announces only the toast summary.

In `@src/platform/workspace/stores/billingOperationStore.test.ts`:
- Around line 701-727: Update the bank-challenge toast tests around
startOperation, including the cases at lines 729-754 and 756-780, to use the
real i18n plugin/backend instead of the mocked t function from `@/i18n`. Assert
each toast’s rendered summary value from the configured translations rather than
raw billingOperation.* translation keys, while preserving the existing toast
behavior assertions.

In `@src/platform/workspace/stores/billingOperationStore.ts`:
- Around line 285-301: Preserve the existing actionUrl in the operation update
when a pending response omits action_url. Update the logic around
authenticationRequiredSeen and the operations.value Map set so a valid new URL
replaces it, null clears it only for successful or terminal-failure responses,
and pending responses retain the prior URL.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c4b7af60-31a2-4679-b0a6-087617b8b277

📥 Commits

Reviewing files that changed from the base of the PR and between d11f308 and 5e28054.

📒 Files selected for processing (4)
  • src/components/toast/GlobalToast.vue
  • src/locales/en/main.json
  • src/platform/workspace/stores/billingOperationStore.test.ts
  • src/platform/workspace/stores/billingOperationStore.ts

Comment thread src/components/toast/GlobalToast.vue Outdated
Comment thread src/platform/workspace/stores/billingOperationStore.test.ts
Comment thread src/platform/workspace/stores/billingOperationStore.ts Outdated
The icon carries no information the summary does not, so announcing it only
adds noise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@wei-hai

wei-hai commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — went through all three. One applied, two declined with reasons.

1. aria-hidden on the toast icons — applied (42bc723)

Correct: both icons are decorative and the summary already carries the meaning, so announcing them is pure noise. Added to both branches, including the pre-existing spinner since this change touches that line anyway.

2. Use real i18n in the new tests — declined

This file mocks @/i18n at module scope (t: (key) => key) and all 52 pre-existing tests assert on translation keys. Switching the three new tests to resolved strings would either make them inconsistent with every neighbour, or require unmocking globally and rewriting the rest of the file — a much larger diff than the fix it accompanies.

The keys are covered by their own i18n tooling; what these tests need to pin is which key the store selects and when it swaps, which is exactly what asserting on the key does.

3. Preserve actionUrl when a pending response omits it — declined

Two reasons.

The state doesn't occur. GetBillingOpStatus returns the action URL for every pending response — it's a persisted column surfaced whenever the op is pending:

var actionURL *string
if billingOp.Status == billing.BillingOpStatusPending {
    actionURL = billingOp.StripeHostedInvoiceURL
}

So a pending poll that omits action_url while the operation is still parked isn't something the server produces. The existing test that simulates it is exercising the store's defensive clearing, not a real sequence.

It's pre-existing behaviour with a test asserting it. updateOperationActionUrl already clears on a pending response without a URL, and keeps a valid action URL pending past discovery and clears it on success pins actionUrl: null in exactly that case. Changing the clearing semantics would rewrite deliberate behaviour that this PR doesn't touch.

It also can't affect this change. The toast swap keys on authenticationRequiredSeen, which is sticky — once true it never returns to false — so a cleared actionUrl cannot revert the toast. That's covered by the does not re-announce verification on later polls test.

Worth noting for anyone reading later: if the server ever did drop action_url mid-park, the panel's verification button (gated on the live URL) would disappear while the toast still asked for verification. That would be worth fixing then — in updateOperationActionUrl, not here.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 7, 2026
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.95652% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/components/toast/GlobalToast.vue 0.00% 3 Missing ⚠️
@@            Coverage Diff             @@
##             main   #14910      +/-   ##
==========================================
- Coverage   78.98%   78.80%   -0.18%     
==========================================
  Files        1866     1866              
  Lines      111132   112209    +1077     
  Branches    31445    32521    +1076     
==========================================
+ Hits        87779    88431     +652     
- Misses      22886    23286     +400     
- Partials      467      492      +25     
Flag Coverage Δ
unit 72.21% <86.95%> (-0.16%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...platform/workspace/stores/billingOperationStore.ts 71.60% <100.00%> (+1.69%) ⬆️
src/components/toast/GlobalToast.vue 64.58% <0.00%> (-2.81%) ⬇️

... and 380 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dante01yoon dante01yoon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I verified the backend rather than assuming the mocked sequence: Cloud’s OpenAPI contract does define action_url as the current deterministic signal that a pending operation cannot proceed without the customer, and the handler returns the persisted URL while the operation is pending. So deriving the UI from the current server field is valid. I’m not ready to approve the implementation yet for two reasons.

Unanchored:

  • issue: This behavior still consumes a handwritten BillingOpStatusResponse in src/platform/workspace/api/workspaceApi.ts, even though @comfyorg/ingest-types already exports the generated contract. Because this change adds UI behavior that depends on the exact semantics of action_url, please use the generated response type rather than a duplicate frontend contract.
  • question: The PR has no linked issue, production report, or real-app AS IS/TO BE capture. The added unit test proves the frontend behaves for a mocked response, but not that the stale toast is occurring in the actual 3DS flow. Could you add a real reproduction/capture or link the evidence that established the bug?

Comment thread src/platform/workspace/stores/billingOperationStore.ts Outdated
The toast keyed on authenticationRequiredSeen, a sticky flag that never
returns to false, so it relied on the server retaining the URL for every
pending poll. The contract does not promise that: action_url is defined as
present exactly while the operation cannot proceed without the customer, and
absent otherwise. Keying on the sticky flag could therefore leave the toast
asking for verification after the action it points at had gone.

Track the current field instead, swapping only when the answer changes so a
dismissed toast does not return on every poll. authenticationRequiredSeen goes
back to carrying only polling cadence and timeout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@wei-hai

wei-hai commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for verifying the backend rather than taking the mocked sequence at face value — the inline point was right and is fixed in f034138 (reply in that thread). The two unanchored points:

Generated type — already the case

workspaceApi.ts imports BillingOpStatusResponse from @comfyorg/ingest-types and re-exports it; there's no handwritten duplicate on this branch:

// src/platform/workspace/api/workspaceApi.ts:1-35
import type {
  ...
  BillingOpStatusResponse,
  ...
} from '@comfyorg/ingest-types'

// :148
export type { BillingOpStatusResponse }

So response.action_url is already typed by the generated contract, including the doc comment that decided the inline discussion. Happy to be pointed at a specific spot if you're seeing a duplicate I've missed.

Reproduction

Fair — the unit tests prove the store's behaviour against a mocked response, not that the state occurs. It does; I reproduced it end to end on a fresh workspace before writing the fix.

Steps (any environment in Stripe test mode):

  1. New workspace, no subscription.
  2. Subscribe to a monthly plan; complete checkout with the 3DS test card 4000 0027 6000 3184.
  3. The subscription's first invoice needs authentication, so the operation parks and the status endpoint returns status: "pending" with action_url set to the Stripe-hosted invoice page.
  4. Observe the toast while parked.

AS IS — the toast reads "Processing payment — setting up your workspace..." with a spinner, for the entire time the operation is waiting on the customer. It sits next to the "Complete verification" affordance rendered from the same action_url, so the two contradict each other. A page reload does not clear it, because the toast is recreated on the same pending operation.

TO BE — "Verify your payment to finish setting up your workspace" with a prompt icon, for as long as action_url is present, reverting to the processing copy if it clears.

Worth adding: the parked state is also reached before any payment exists — an operation waiting for the customer to finish checkout shows the same "Processing payment" copy with no charge having been attempted. Same root cause, same fix.

I've added the reproduction to the PR description. The detailed capture (screenshots, timings, operation IDs) is from an internal environment so I've kept it out of a public repo — happy to share it internally, and to link the tracking issue there.

For completeness on the timing question that motivated this: once the challenge is completed, activation is automatic and fast — the grant landed 2 seconds after the challenge in my run. Nothing is stuck; the copy just says otherwise while the customer is the one being waited on.

@wei-hai
wei-hai requested a review from dante01yoon August 7, 2026 20:45
@wei-hai wei-hai added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch backport Backporting a PR onto a release candidate core/1.48 core/1.49 Backport PRs for core 1.49 cloud/1.49 Backport PRs for cloud 1.49 and removed core/1.48 core/1.49 Backport PRs for core 1.49 cloud/1.49 Backport PRs for cloud 1.49 labels Aug 7, 2026

@dante01yoon dante01yoon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-reviewed the current action_url-driven implementation. The generated backend contract defines action_url as the current customer-action signal, and the toast now follows transitions of that validated field rather than the sticky authenticationRequiredSeen history. I verified initial action URLs, repeated polls, URL removal, and terminal cleanup; the focused billing-operation store suite passes all 56 tests, and the PR CI is green. I do not see a regression from this change.

@dante01yoon dante01yoon removed their assignment Aug 7, 2026
@dante01yoon dante01yoon added the cloud/1.49 Backport PRs for cloud 1.49 label Aug 7, 2026
@wei-hai
wei-hai added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit f587cf6 Aug 7, 2026
162 of 170 checks passed
@wei-hai
wei-hai deleted the fix/billing-toast-action-required branch August 7, 2026 21:27
@comfy-pr-bot

Copy link
Copy Markdown
Member

@wei-hai Successfully backported to #14911

@comfy-pr-bot

Copy link
Copy Markdown
Member

@wei-hai Successfully backported to #14912

@comfy-pr-bot

Copy link
Copy Markdown
Member

@wei-hai Successfully backported to #14913

@github-actions github-actions Bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Aug 7, 2026
comfy-pr-bot added a commit that referenced this pull request Aug 7, 2026
…a payment waits on the customer (#14911)

Backport of #14910 to `core/1.48`

Automatically created by backport workflow.

Co-authored-by: Wei Hai <hai.vincent@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
comfy-pr-bot added a commit that referenced this pull request Aug 7, 2026
… a payment waits on the customer (#14912)

Backport of #14910 to `cloud/1.48`

Automatically created by backport workflow.

Co-authored-by: Wei Hai <hai.vincent@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
comfy-pr-bot added a commit that referenced this pull request Aug 7, 2026
… a payment waits on the customer (#14913)

Backport of #14910 to `cloud/1.49`

Automatically created by backport workflow.

Co-authored-by: Wei Hai <hai.vincent@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@comfy-pr-bot comfy-pr-bot added the released:cloud PR has been released to cloud label Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport Backporting a PR onto a release candidate cloud/1.49 Backport PRs for cloud 1.49 released:cloud PR has been released to cloud size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants