Skip to content

fix(perps): align decimal behavior and display parity cp-13.28.0#41855

Closed
abretonc7s wants to merge 36 commits into
mainfrom
fix/tat-2699-ui-decimal-display-parity
Closed

fix(perps): align decimal behavior and display parity cp-13.28.0#41855
abretonc7s wants to merge 36 commits into
mainfrom
fix/tat-2699-ui-decimal-display-parity

Conversation

@abretonc7s

@abretonc7s abretonc7s commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is stacked on top of #41558.

It keeps the perps UI decimal/display parity work isolated from the controller/base PR and aligns the key extension screens with current mobile behavior across market detail, order entry, position detail, reverse, remove-margin, close, and withdraw.

Temporary Jest workaround (TAT-2990)

This PR extends jest.config.js and jest.integration.config.js transformIgnorePatterns to allow Babel to transpile @metamask/perps-controller and its ESM-only transitive deps (@nktkas/hyperliquid, @noble/hashes, micro-eth-signer, micro-packed, @scure) during tests.

Why: the controller's main entry statically imports @nktkas/hyperliquid which imports @noble/hashes/sha3.js (ESM-only via @noble/hashes@2.0.1 bumped by @nktkas/hyperliquid@0.30.3). Jest's default transformIgnorePatterns skips node_modules, so 13 unit-test suites across bridge, settings, notifications, account-overview, design-system, etc. plus all 23 integration suites fail with SyntaxError: Cannot use import statement outside a module as soon as anything in this PR tightens the perps-controller import path.

Scope: single well-commented block in each config, scoped to the known ESM chain. No other project behavior changes.

Exit plan: upstream fix is tracked in TAT-2990. Preferred solution is to lazy-load the HyperLiquid SDK in HyperLiquidClientService (mirror the existing MYXProvider dynamic-import pattern) so the main entry is CJS-safe again. Once that ships and the extension bumps the controller version, both transformIgnorePatterns blocks are reverted.

LavaMoat MV3 policy update

This PR adds "Intl.NumberFormat": true for @metamask/perps-controller to all four MV3 policy flavors (main, beta, flask, experimental).

Why: the new ui/components/app/perps/utils/formatPerpsDisplayPrice.ts directly imports formatPerpsFiat and PRICE_RANGES_* from @metamask/perps-controller. This is the first UI-side direct import of the controller, so it now appears in the MV3 UI bundle as its own module entry. formatPerpsFiat uses Intl.NumberFormat internally, and LavaMoat's lavamoat:auto step regenerates the policy to whitelist that global. CI's Check working tree step for MV3 enforces this — the policy must be committed or CI cannot go green.

Changelog

CHANGELOG entry: null

Related issues

Fixes: N/A (stacked UI/display follow-up for TAT-2699 on top of #41558)

Related:

Manual testing steps

  1. Check out this branch on top of fix/tat-2699-fix-perps-decimal-logic.
  2. Open perps market detail and order entry for BTC and ETH, then verify the displayed price/change/margin/liquidation/fees formatting.
  3. Check ETH position detail, reverse, remove-margin, close, and withdraw screens.
  4. Run the extension focused parity recipe: temp/agentic/recipes/teams/perps/recipes/pr-41558-decimal-formatting.json.
  5. Run the extension full smoke recipe: temp/agentic/recipes/domains/perps/recipes/full-trade-lifecycle.json.
  6. For the mobile parity reference, run scripts/perps/agentic/teams/perps/recipes/reference-decimal-key-screens.json on mm-1.

Validation Recipe

Extension full recipe.json
{
  "title": "Full trade lifecycle — testnet, open ETH long, close, verify BTC market",
  "description": "End-to-end smoke test: ensures testnet, navigates to perps, opens a long position on ETH, closes it, then navigates to BTC market detail to verify multi-market navigation. Restores original network on teardown.",
  "validate": {
    "workflow": {
      "pre_conditions": ["wallet.unlocked", "perps.feature_enabled"],
      "setup": [
        {
          "id": "save-original-network",
          "action": "eval_sync",
          "expression": "(function(){var m=stateHooks.store.getState().metamask;return JSON.stringify({network:m.isTestnet?'testnet':'mainnet',provider:m.activeProvider||'hyperliquid'})})()",
          "assert": {
            "all": [
              { "operator": "length_gt", "field": "network", "value": 0 },
              { "operator": "length_gt", "field": "provider", "value": 0 }
            ]
          },
          "save_as": "original_network"
        }
      ],
      "teardown": [
        {
          "id": "restore-network",
          "action": "call",
          "ref": "perps/ensure-perps-network",
          "params": { "network": "{{vars.original_network.network}}", "provider": "{{vars.original_network.provider}}" }
        },
        {
          "id": "nav-perps-home",
          "action": "call",
          "ref": "perps/navigate-perps-tab"
        }
      ],
      "entry": "ensure-testnet",
      "nodes": {
        "ensure-testnet": {
          "action": "call",
          "ref": "perps/ensure-perps-network",
          "params": { "network": "testnet", "provider": "hyperliquid" },
          "next": "nav-perps"
        },
        "nav-perps": {
          "action": "call",
          "ref": "perps/navigate-perps-tab",
          "next": "screenshot-home"
        },
        "screenshot-home": {
          "action": "screenshot",
          "filename": "01-perps-home",
          "next": "open-long-eth"
        },
        "open-long-eth": {
          "action": "call",
          "ref": "perps/open-long-position",
          "params": { "symbol": "ETH", "side": "long", "amount": "10" },
          "next": "screenshot-position"
        },
        "screenshot-position": {
          "action": "screenshot",
          "filename": "02-eth-long-open",
          "next": "close-eth"
        },
        "close-eth": {
          "action": "call",
          "ref": "perps/close-position",
          "params": { "symbol": "ETH", "percent": "100" },
          "next": "screenshot-closed"
        },
        "screenshot-closed": {
          "action": "screenshot",
          "filename": "03-eth-position-closed",
          "next": "nav-btc-market"
        },
        "nav-btc-market": {
          "action": "call",
          "ref": "perps/navigate-to-market-detail",
          "params": { "symbol": "BTC" },
          "next": "screenshot-btc"
        },
        "screenshot-btc": {
          "action": "screenshot",
          "filename": "04-btc-market-detail",
          "next": "nav-back-perps"
        },
        "nav-back-perps": {
          "action": "call",
          "ref": "perps/navigate-perps-tab",
          "next": "screenshot-final"
        },
        "screenshot-final": {
          "action": "screenshot",
          "filename": "05-perps-home-final",
          "next": "done"
        },
        "done": {
          "action": "end",
          "status": "pass",
          "message": "Full trade lifecycle completed: testnet setup, ETH open/close, BTC market navigation"
        }
      }
    }
  }
}

Screenshots/Recordings

Hosted asset folder:

  • https://github.com/abretonc7s/mm-extension-farm-artifacts/tree/main/reviews/41558/comparison-table

Before

Variant Home Market Detail Order Entry Remove Margin Close
Extension Before Extension before home Extension before market detail Extension before order entry Extension before remove margin Extension before close

After

Variant Home Market Detail Order Entry Remove Margin Close
Extension After Extension after home Extension after market detail Extension after order entry Extension after remove margin Extension after close
Mobile Mobile home Mobile market detail Mobile order entry Mobile remove margin Mobile close

Validation status

Current review state:

  • Extension focused parity recipe temp/agentic/recipes/teams/perps/recipes/pr-41558-decimal-formatting.json: passed.
  • Extension full smoke recipe temp/agentic/recipes/domains/perps/recipes/full-trade-lifecycle.json: passed.
  • Extension direct parity extraction across the key screens set: passed (15/15).
  • Mobile reference decimal key-screens recipe on mm-1: scripts/perps/agentic/teams/perps/recipes/reference-decimal-key-screens.json passed (71/71).

Fresh parity read:

  • Market/detail formatting shape is aligned across the major symbols.
  • ETH position detail is aligned closely.
  • Close-position values are aligned closely.
  • The remaining observed differences are considered acceptable for review signoff:
    • withdraw ETA wording (~5 min vs 5 minutes)
    • remove-margin available display ($0 USDC vs $0)
    • reverse modal fee shown vs placeholder

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Touches multiple perps trading surfaces and core calculation hooks (fees, liquidation price) and adds new background RPC calls/fallback behavior, which could affect displayed amounts and user decisions. Changes are mostly formatting/parity work but span several key flows (order entry, market detail, close/reverse/margin).

Overview
Perps UI now relies on @metamask/perps-controller formatting helpers (e.g., formatPerpsFiat, formatPositionSize, funding/PnL formatters and price-range presets) across market detail, order entry, close/reverse, margin edit, TP/SL, and balance dropdown, shifting display output toward mobile parity (notably fewer forced trailing decimals) and adding several data-testids.

Order calculations are updated to use controller-style size/margin computations and a new debounced usePerpsLiquidationPrice hook that calls perpsCalculateLiquidationPrice, with a local fallback formula if the RPC returns no value. usePerpsOrderFees now falls back to base fee rates (and computed fee amounts) on RPC failure/timeout instead of returning undefined.

Tooling/build updates include a temporary Jest transformIgnorePatterns exception to transpile the perps-controller’s ESM dependency chain during tests, and LavaMoat MV3 policy updates to allow Intl.NumberFormat for @metamask/perps-controller.

Reviewed by Cursor Bugbot for commit 50c32c3. Bugbot is set up for automated code reviews on this repo. Configure here.

Create a clean base branch from current main that contains only the perps controller upgrade, decimal-logic changes, and required non-UI integration support so the UI formatting work can live entirely on the stacked branch.

Constraint: Base PR must contain no ui/ changes at all
Rejected: Continue using the original long-lived branch as PR A | three-dot history still surfaces UI files without a force-push or a replacement PR
Confidence: high
Scope-risk: moderate
Directive: Keep this branch non-UI; all ui/ changes should stack on top in the formatting branch
Tested: Targeted Jest for perps infrastructure + perps-controller-init; ESLint on touched non-UI files
Not-tested: Full repo-wide CI and full branch-wide validation
Create a clean UI-only stacked branch on top of the non-UI controller base so all user-facing decimal behavior, display formatting, and related tests are reviewed in one place.

Constraint: This replacement formatting branch must contain only ui/ files
Rejected: Keep using the older stacked formatting branch | it still carried non-UI files from the previous split attempt
Confidence: high
Scope-risk: narrow
Directive: Use this branch/PR for all UI-facing perps decimal and display review; do not review those changes on the non-UI base PR
Tested: ESLint on all touched ui/ files
Not-tested: Full UI Jest/recipe rerun on the replacement branch
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-perps Perps team label Apr 16, 2026
@metamaskbotv2

metamaskbotv2 Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

✨ Files requiring CODEOWNER review ✨

👨‍🔧 @MetaMask/perps (24 files, +616 -353)
  • 📁 ui/
    • 📁 components/
      • 📁 app/
        • 📁 perps/
          • 📁 close-position/
            • 📄 close-position-modal.test.tsx +16 -0
            • 📄 close-position-modal.tsx +25 -27
          • 📁 edit-margin/
            • 📄 edit-margin-modal-content.tsx +34 -28
          • 📁 order-entry/
            • 📁 components/
              • 📁 auto-close-section/
                • 📄 auto-close-section.tsx +12 -13
              • 📁 close-amount-section/
                • 📄 close-amount-section.tsx +12 -5
              • 📁 order-summary/
                • 📄 order-summary.tsx +15 -3
              • 📄 order-entry.test.tsx +30 -0
              • 📄 order-entry.tsx +4 -0
              • 📄 order-entry.types.ts +4 -0
          • 📁 perps-balance-dropdown/
            • 📄 perps-balance-dropdown.test.tsx +2 -2
            • 📄 perps-balance-dropdown.tsx +11 -4
          • 📁 reverse-position/
            • 📄 reverse-position-modal.test.tsx +14 -2
            • 📄 reverse-position-modal.tsx +13 -5
          • 📁 update-tpsl/
            • 📄 update-tpsl-modal-content.tsx +11 -11
          • 📁 utils/
            • 📄 formatPerpsDisplayPrice.ts +27 -0
            • 📄 index.ts +7 -4
    • 📁 hooks/
      • 📁 perps/
        • 📄 usePerpsLiquidationPrice.ts +93 -0
        • 📄 usePerpsOrderFees.test.ts +39 -5
        • 📄 usePerpsOrderFees.ts +28 -1
        • 📄 usePerpsOrderForm.test.ts +38 -11
        • 📄 usePerpsOrderForm.ts +105 -71
    • 📁 pages/
      • 📁 perps/
        • 📄 perps-market-detail-page.test.tsx +2 -58
        • 📄 perps-market-detail-page.tsx +73 -45
        • 📄 perps-order-entry-page.test.tsx +1 -58

📜 @MetaMask/policy-reviewers (4 files, +20 -0)
  • 📁 lavamoat/
    • 📁 webpack/
      • 📁 mv3/
        • 📁 beta/
          • 📄 policy.json +5 -0
        • 📁 experimental/
          • 📄 policy.json +5 -0
        • 📁 flask/
          • 📄 policy.json +5 -0
        • 📁 main/
          • 📄 policy.json +5 -0

Tip

Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers.

@abretonc7s abretonc7s changed the base branch from fix/tat-2699-controller-decimal-base to fix/tat-2699-fix-perps-decimal-logic April 16, 2026 20:54
@abretonc7s abretonc7s marked this pull request as ready for review April 16, 2026 20:55
@abretonc7s abretonc7s requested a review from a team as a code owner April 16, 2026 20:55
Comment thread ui/pages/perps/perps-market-detail-page.tsx
Restore the display-price priority so the market detail header continues to track chart/live price updates instead of freezing on the initial market-data snapshot after the formatting refactor.

Constraint: Keep the fix scoped to the stale header-price regression reported on the UI-only PR
Rejected: Leave market.price first in the fallback chain | causes the live/chart branches to become unreachable once market data loads
Confidence: high
Scope-risk: narrow
Directive: When multiple perps price sources exist, prefer the live/chart source for active display and keep market snapshot as fallback only
Tested: ESLint ui/pages/perps/perps-market-detail-page.tsx; live perps recipe previously passed on this branch
Not-tested: Full targeted recipe rerun after this exact one-line priority fix
Comment thread ui/pages/perps/perps-order-entry-page.tsx
Comment thread ui/pages/perps/perps-order-entry-page.tsx
Comment thread ui/components/app/perps/edit-margin/edit-margin-modal-content.tsx Outdated
Fix the remaining UI review regressions on the decimal/display parity branch by restoring live/chart-first header price priority, avoiding premature non-close in-progress toasts, and restoring the explicit USDC suffix in edit-margin available balance.

Constraint: Keep the fix scoped to UI-only review regressions on the stacked perps parity branch
Rejected: Leave the Bugbot findings unresolved | they describe real UI regressions introduced by the formatting branch
Confidence: high
Scope-risk: narrow
Directive: When aligning extension with mobile formatting, preserve existing live-price precedence and user-visible denomination cues unless mobile explicitly differs
Tested: ESLint on touched UI files; live CDP recipe pr-41558-decimal-formatting (42/42)
Not-tested: Full branch CI rerun after push
Comment thread ui/hooks/perps/usePerpsOrderFees.ts Outdated
Comment thread ui/hooks/perps/usePerpsOrderForm.ts
Fix the remaining actionable UI review findings on the decimal/display parity branch by restoring live/chart-first display price precedence, suppressing premature non-close in-progress toasts, restoring the explicit USDC suffix in edit-margin available balance, and returning a full fallback fee result shape in usePerpsOrderFees.

Constraint: Keep the fixes scoped to the UI branch and leave the mobile-parity-consistent order-form pricing behavior unchanged
Rejected: Change usePerpsOrderForm price-source behavior | current mobile implementation also derives position size from display/fill price and values margin with mark/oracle price
Confidence: high
Scope-risk: narrow
Directive: Treat Bugbot findings as actionable only when they contradict intended/mobile behavior or produce incomplete hook result shapes
Tested: ESLint on touched UI files; Jest ui/hooks/perps/usePerpsOrderFees.test.ts; live CDP recipe pr-41558-decimal-formatting (42/42)
Not-tested: Full branch CI rerun after push
Comment thread ui/hooks/perps/usePerpsOrderForm.ts Outdated
Restore display-formatted asset symbols in usePerpsOrderForm so prefixed assets like HIP-3 markets render the same cleaned symbols across calculated position-size strings.

Constraint: Keep the fix scoped to the remaining actionable UI Bugbot finding
Rejected: Leave raw asset symbols in calculated display strings | produces inconsistent prefixed asset labels relative to sibling perps UI components
Confidence: high
Scope-risk: narrow
Directive: When a hook returns user-visible perps asset strings, prefer getDisplaySymbol over raw asset identifiers
Tested: Jest ui/hooks/perps/usePerpsOrderForm.test.ts --no-coverage; ESLint ui/hooks/perps/usePerpsOrderForm.ts
Not-tested: Full branch CI rerun after push
Comment thread ui/pages/perps/perps-order-entry-page.tsx
Constraint: Need a fresh CI run on the cleaned #41558 branch head because the currently displayed failures are from the older poisoned branch state.
Confidence: high
Scope-risk: narrow
Directive: Remove this commit only if CI can be retriggered another way without losing the clean branch state
Tested: None (CI trigger only)
Not-tested: Functional behavior unchanged
Restore the package baseline to current main, keep only the intended perps-controller bump, regenerate the lockfile, and apply the minimal smart-transactions type cast needed for the refreshed dependency graph to pass TypeScript.

Constraint: Minimize the diff to main while keeping the perps controller update intact
Rejected: Keep the older dependency baseline | produced missing geolocation and notification-services dependency-tree failures unrelated to the actual perps change
Confidence: high
Scope-risk: moderate
Directive: Treat package.json on this branch as main baseline plus only the intentional perps-controller bump unless a new failing check proves another dependency change is required
Tested: yarn install --mode=skip-build; yarn circular-deps:check; yarn lint:tsc; eslint on touched smart-transactions init file; targeted perps infrastructure/init Jest
Not-tested: Full CI run after push
…ogic' into fix/tat-2699-ui-decimal-display-parity
Reapply the non-close in-progress toast guard after syncing the UI branch onto the refreshed controller base so submission failures still clear the stale in-progress toast correctly.

Constraint: Preserve the successful UI recipe behavior while bringing the branch onto the latest non-UI base
Rejected: Leave the stash-only local fix uncommitted | would lose the error-path correction on the updated branch
Confidence: high
Scope-risk: narrow
Directive: After base syncs, re-check the non-close error path because it depends on both route-state navigation and local toast cleanup
Tested: ESLint on touched code; live CDP recipe pr-41558-decimal-formatting (42/42)
Not-tested: Full branch CI rerun after push
Comment thread ui/hooks/perps/usePerpsOrderForm.ts
Comment thread jest.config.js
Comment thread ui/hooks/perps/usePerpsOrderForm.ts
@metamaskbotv2

metamaskbotv2 Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor
Builds ready [802af3e]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24598472504 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • bridgeUserActions/bridge_load_asset_picker: -50%
  • bridgeUserActions/total: -16%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.6s
  • 🟡 loadNewAccount/LCP: p75 2.6s
  • 🟡 confirmTx/FCP: p75 2.6s
  • 🟡 confirmTx/LCP: p75 2.6s
  • 🟡 bridgeUserActions/FCP: p75 2.6s
  • 🟡 bridgeUserActions/LCP: p75 2.6s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -20%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -13%
  • startupStandardHome/setupStore: +21%
  • startupStandardHome/numNetworkReqs: -16%
  • startupStandardHome/uiStartup: -17%
  • startupStandardHome/load: -13%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/backgroundConnect: -33%
  • startupStandardHome/firstReactRender: -23%
  • startupStandardHome/loadScripts: -13%
  • startupStandardHome/numNetworkReqs: -44%
  • startupStandardHome/uiStartup: -11%
  • startupStandardHome/domInteractive: -56%
  • startupStandardHome/backgroundConnect: +13%
  • startupStandardHome/initialActions: +33%
  • startupStandardHome/numNetworkReqs: -29%
  • startupStandardHome/uiStartup: -16%
  • startupStandardHome/domInteractive: -37%
  • startupStandardHome/initialActions: -43%
  • startupStandardHome/setupStore: -57%
  • startupStandardHome/numNetworkReqs: -26%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -85%
  • onboardingImportWallet/metricsToWalletReadyScreen: -49%
  • onboardingImportWallet/doneButtonToHomeScreen: -77%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +26%
  • onboardingImportWallet/total: -44%
  • onboardingNewWallet/srpButtonToPwForm: -82%
  • onboardingNewWallet/createPwToRecoveryScreen: -23%
  • onboardingNewWallet/skipBackupToMetricsScreen: -70%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -15%
  • onboardingNewWallet/doneButtonToAssetList: -68%
  • onboardingNewWallet/total: -62%
  • assetDetails/assetClickToPriceChart: -47%
  • assetDetails/total: -47%
  • solanaAssetDetails/assetClickToPriceChart: -69%
  • solanaAssetDetails/total: -69%
  • importSrpHome/loginToHomeScreen: -12%
  • importSrpHome/openAccountMenuAfterLogin: -45%
  • importSrpHome/homeAfterImportWithNewWallet: -67%
  • importSrpHome/total: -61%
  • sendTransactions/reviewTransactionToConfirmationPage: +35%
  • sendTransactions/total: +33%
  • swap/openSwapPageFromHome: -96%
  • swap/fetchAndDisplaySwapQuotes: +32%
  • swap/total: +11%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 2.6s
  • 🟡 solanaAssetDetails/FCP: p75 2.6s
  • 🟡 importSrpHome/FCP: p75 2.6s
  • 🟡 sendTransactions/FCP: p75 2.6s
  • 🟡 sendTransactions/LCP: p75 2.6s
  • 🟡 swap/FCP: p75 2.7s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 2.86 KiB (0.03%)
  • common: 175 Bytes (0%)

- Revert jest.config transformIgnorePatterns addition (keeps diff minimal vs main).
- Apply yarn patch on @metamask/perps-controller 3.1.1 to expose
  ./formatters, ./calculations, and ./constants subpath exports.
  Temporary workaround — will be removed once the upstream fix lands
  in @metamask/perps-controller (tracked by TAT-2990).
Mirror mobile's usePerpsLiquidationPrice shape (lodash debounce with
optional debounceMs). For market orders, entryPrice tracks currentPrice
which updates per tick; without debouncing, perpsCalculateLiquidationPrice
fires on every update. Defaults to 300ms so calls coalesce during active
market conditions.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bf7c63e. Configure here.

Comment thread ui/hooks/perps/usePerpsLiquidationPrice.ts
@metamaskbotv2

metamaskbotv2 Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor
Builds ready [bf7c63e]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24599458203 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -21%
  • loadNewAccount/total: -21%
  • bridgeUserActions/bridge_load_asset_picker: -50%
  • bridgeUserActions/total: -15%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.5s
  • 🟡 confirmTx/FCP: p75 2.6s
  • 🟡 bridgeUserActions/INP: p75 256ms
  • 🟡 bridgeUserActions/FCP: p75 2.5s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -23%
  • startupStandardHome/load: -11%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -15%
  • startupStandardHome/setupStore: +14%
  • startupStandardHome/numNetworkReqs: -16%
  • startupStandardHome/uiStartup: -16%
  • startupStandardHome/load: -12%
  • startupStandardHome/domContentLoaded: -11%
  • startupStandardHome/firstPaint: +16%
  • startupStandardHome/backgroundConnect: -31%
  • startupStandardHome/firstReactRender: -19%
  • startupStandardHome/loadScripts: -11%
  • startupStandardHome/numNetworkReqs: -44%
  • startupStandardHome/domInteractive: -27%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/numNetworkReqs: -34%
  • startupStandardHome/uiStartup: -16%
  • startupStandardHome/domInteractive: -37%
  • startupStandardHome/initialActions: -43%
  • startupStandardHome/setupStore: -50%
  • startupStandardHome/numNetworkReqs: -29%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -85%
  • onboardingImportWallet/metricsToWalletReadyScreen: -49%
  • onboardingImportWallet/doneButtonToHomeScreen: -78%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +28%
  • onboardingImportWallet/total: -44%
  • onboardingNewWallet/srpButtonToPwForm: -79%
  • onboardingNewWallet/skipBackupToMetricsScreen: -69%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -16%
  • onboardingNewWallet/doneButtonToAssetList: -33%
  • onboardingNewWallet/total: -33%
  • assetDetails/assetClickToPriceChart: -80%
  • assetDetails/total: -80%
  • solanaAssetDetails/assetClickToPriceChart: -79%
  • solanaAssetDetails/total: -79%
  • importSrpHome/openAccountMenuAfterLogin: -64%
  • importSrpHome/homeAfterImportWithNewWallet: -66%
  • importSrpHome/total: -59%
  • sendTransactions/reviewTransactionToConfirmationPage: +38%
  • sendTransactions/total: +36%
  • swap/openSwapPageFromHome: -96%
  • swap/fetchAndDisplaySwapQuotes: +31%
  • swap/total: +11%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 2.6s
  • 🟡 solanaAssetDetails/FCP: p75 2.6s
  • 🟡 importSrpHome/FCP: p75 2.6s
  • 🟡 sendTransactions/FCP: p75 2.6s
  • 🟡 sendTransactions/LCP: p75 2.5s
  • 🟡 swap/FCP: p75 2.6s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • dappPageLoad/pageLoadTime: -20%
  • dappPageLoad/domContentLoaded: -22%
  • dappPageLoad/firstPaint: -18%
  • dappPageLoad/firstContentfulPaint: -18%
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 2.85 KiB (0.03%)
  • common: 283 Bytes (0%)

…2990)

@metamask/perps-controller's main entry statically imports @nktkas/hyperliquid
which pulls ESM-only @noble/hashes/sha3.js. Jest's default transformIgnorePatterns
skips node_modules, so any test that transitively renders perps UI fails with
"SyntaxError: Cannot use import statement outside a module" — across 13 test
suites spanning bridge, settings, notifications, account-overview, and more.

Temporary: allow Babel to transpile the narrow ESM chain during tests. Revert
once TAT-2990 lazy-loads the HyperLiquid SDK upstream so the main entry is
CJS-safe again.

Also reverts the short-lived yarn patch attempt on @metamask/perps-controller
(patch protocol did not register cleanly through Yarn Berry's lockfile).
@metamaskbotv2

metamaskbotv2 Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor
Builds ready [c380fd5]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24599955080 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • bridgeUserActions/bridge_load_page: -12%
  • bridgeUserActions/bridge_load_asset_picker: -52%
  • bridgeUserActions/total: -18%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.5s
  • 🟡 confirmTx/FCP: p75 2.6s
  • 🟡 bridgeUserActions/FCP: p75 2.6s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -17%
  • startupStandardHome/domInteractive: +15%
  • startupStandardHome/firstPaint: +13%
  • startupStandardHome/firstReactRender: -10%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/setupStore: +14%
  • startupStandardHome/numNetworkReqs: -16%
  • startupStandardHome/uiStartup: -20%
  • startupStandardHome/load: -15%
  • startupStandardHome/domContentLoaded: -14%
  • startupStandardHome/backgroundConnect: -34%
  • startupStandardHome/firstReactRender: -27%
  • startupStandardHome/loadScripts: -15%
  • startupStandardHome/setupStore: -13%
  • startupStandardHome/numNetworkReqs: -44%
  • startupStandardHome/uiStartup: -11%
  • startupStandardHome/domInteractive: -46%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/numNetworkReqs: -34%
  • startupStandardHome/uiStartup: -18%
  • startupStandardHome/domContentLoaded: -10%
  • startupStandardHome/domInteractive: -65%
  • startupStandardHome/initialActions: +14%
  • startupStandardHome/loadScripts: -10%
  • startupStandardHome/setupStore: -44%
  • startupStandardHome/numNetworkReqs: -34%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -84%
  • onboardingImportWallet/metricsToWalletReadyScreen: -11%
  • onboardingImportWallet/doneButtonToHomeScreen: -76%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +26%
  • onboardingImportWallet/total: -44%
  • onboardingNewWallet/srpButtonToPwForm: -77%
  • onboardingNewWallet/skipBackupToMetricsScreen: -67%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -14%
  • onboardingNewWallet/doneButtonToAssetList: -23%
  • onboardingNewWallet/total: -24%
  • assetDetails/assetClickToPriceChart: -34%
  • assetDetails/total: -34%
  • solanaAssetDetails/assetClickToPriceChart: -69%
  • solanaAssetDetails/total: -69%
  • importSrpHome/loginToHomeScreen: -13%
  • importSrpHome/openAccountMenuAfterLogin: -56%
  • importSrpHome/homeAfterImportWithNewWallet: -68%
  • importSrpHome/total: -60%
  • sendTransactions/selectTokenToSendFormLoaded: -10%
  • sendTransactions/reviewTransactionToConfirmationPage: +36%
  • sendTransactions/total: +34%
  • swap/openSwapPageFromHome: -96%
  • swap/fetchAndDisplaySwapQuotes: +31%
  • swap/total: +10%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 2.6s
  • 🟡 solanaAssetDetails/FCP: p75 2.6s
  • 🟡 importSrpHome/FCP: p75 2.6s
  • 🟡 sendTransactions/FCP: p75 2.6s
  • 🟡 swap/FCP: p75 2.5s
  • 🟡 swap/LCP: p75 2.5s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 2.85 KiB (0.03%)
  • common: 175 Bytes (0%)

- jest.integration.config.js: allowlist @metamask/perps-controller
  ESM chain (@nktkas/hyperliquid, @noble/hashes, @Scure, micro-*)
  mirroring the unit config fix. Required until the controller
  lazy-loads the HyperLiquid SDK upstream.
- perps-market-detail-page.test.tsx: replace hand-rolled perps-controller
  mock with jest.requireActual spread so newly added exports
  (formatPerpsFiat, PRICE_RANGES_*) resolve automatically.
- lavamoat/webpack/mv3/*/policy.json: whitelist Intl.NumberFormat for
  @metamask/perps-controller. Branch adds a new UI-side direct import
  of formatPerpsFiat via formatPerpsDisplayPrice.ts which pulls the
  controller into the MV3 UI bundle for the first time.
@metamaskbotv2

metamaskbotv2 Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor
Builds ready [dbf47a3]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24605866676 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -21%
  • loadNewAccount/total: -21%
  • bridgeUserActions/bridge_load_asset_picker: -56%
  • bridgeUserActions/total: -16%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.7s
  • 🟡 confirmTx/FCP: p75 2.7s
  • 🟡 bridgeUserActions/FCP: p75 2.7s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -21%
  • startupStandardHome/load: -10%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -14%
  • startupStandardHome/numNetworkReqs: -16%
  • startupStandardHome/uiStartup: -15%
  • startupStandardHome/load: -11%
  • startupStandardHome/domContentLoaded: -10%
  • startupStandardHome/domInteractive: +11%
  • startupStandardHome/backgroundConnect: -30%
  • startupStandardHome/firstReactRender: -19%
  • startupStandardHome/loadScripts: -11%
  • startupStandardHome/numNetworkReqs: -44%
  • startupStandardHome/domInteractive: -44%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/numNetworkReqs: -29%
  • startupStandardHome/uiStartup: -19%
  • startupStandardHome/load: -12%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/domInteractive: -70%
  • startupStandardHome/initialActions: -43%
  • startupStandardHome/loadScripts: -12%
  • startupStandardHome/setupStore: -60%
  • startupStandardHome/numNetworkReqs: -32%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -85%
  • onboardingImportWallet/metricsToWalletReadyScreen: -49%
  • onboardingImportWallet/doneButtonToHomeScreen: -79%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +27%
  • onboardingImportWallet/total: -43%
  • onboardingNewWallet/srpButtonToPwForm: -80%
  • onboardingNewWallet/skipBackupToMetricsScreen: -69%
  • onboardingNewWallet/doneButtonToAssetList: -33%
  • onboardingNewWallet/total: -33%
  • assetDetails/assetClickToPriceChart: -51%
  • assetDetails/total: -51%
  • solanaAssetDetails/assetClickToPriceChart: -70%
  • solanaAssetDetails/total: -70%
  • importSrpHome/loginToHomeScreen: -12%
  • importSrpHome/openAccountMenuAfterLogin: -69%
  • importSrpHome/homeAfterImportWithNewWallet: -67%
  • importSrpHome/total: -61%
  • sendTransactions/selectTokenToSendFormLoaded: +12%
  • sendTransactions/reviewTransactionToConfirmationPage: +36%
  • sendTransactions/total: +35%
  • swap/openSwapPageFromHome: -96%
  • swap/fetchAndDisplaySwapQuotes: +32%
  • swap/total: +11%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 2.6s
  • 🟡 solanaAssetDetails/FCP: p75 2.6s
  • 🔴 importSrpHome/FCP: p75 3.0s
  • 🟡 sendTransactions/INP: p75 216ms
  • 🟡 sendTransactions/FCP: p75 2.7s
  • 🟡 swap/FCP: p75 2.7s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 2.85 KiB (0.03%)
  • common: 175 Bytes (0%)

Same fix as perps-market-detail-page.test.tsx (previous commit):
the hand-rolled mock only stubbed PERPS_ERROR_CODES so the newly
added formatPerpsFiat export was undefined, causing 34 tests to
fail with "formatPerpsFiat is not a function" when the component
renders formatPerpsDisplayPrice. Replace with requireActual spread.

Validated: 161/161 across all 6 perps tests mocking the controller.
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
79.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@metamaskbotv2

metamaskbotv2 Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor
Builds ready [50c32c3]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24616506223 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -20%
  • loadNewAccount/total: -20%
  • bridgeUserActions/bridge_load_page: +25%
  • bridgeUserActions/bridge_load_asset_picker: -36%
  • bridgeUserActions/total: -12%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.6s
  • 🟡 confirmTx/FCP: p75 2.6s
  • 🟡 bridgeUserActions/INP: p75 216ms
  • 🟡 bridgeUserActions/FCP: p75 2.6s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -23%
  • startupStandardHome/load: -13%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/domInteractive: +12%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -16%
  • startupStandardHome/setupStore: +14%
  • startupStandardHome/numNetworkReqs: -37%
  • startupStandardHome/uiStartup: -24%
  • startupStandardHome/load: -19%
  • startupStandardHome/domContentLoaded: -19%
  • startupStandardHome/backgroundConnect: -39%
  • startupStandardHome/firstReactRender: -27%
  • startupStandardHome/loadScripts: -19%
  • startupStandardHome/setupStore: -20%
  • startupStandardHome/numNetworkReqs: -44%
  • startupStandardHome/domInteractive: -50%
  • startupStandardHome/backgroundConnect: +17%
  • startupStandardHome/initialActions: +33%
  • startupStandardHome/numNetworkReqs: -29%
  • startupStandardHome/uiStartup: -19%
  • startupStandardHome/load: -12%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/domInteractive: -67%
  • startupStandardHome/initialActions: -43%
  • startupStandardHome/loadScripts: -12%
  • startupStandardHome/setupStore: -54%
  • startupStandardHome/numNetworkReqs: -34%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -85%
  • onboardingImportWallet/confirmSrpToPwForm: -11%
  • onboardingImportWallet/metricsToWalletReadyScreen: -48%
  • onboardingImportWallet/doneButtonToHomeScreen: -77%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +27%
  • onboardingImportWallet/total: -45%
  • onboardingNewWallet/srpButtonToPwForm: -80%
  • onboardingNewWallet/skipBackupToMetricsScreen: -70%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -25%
  • onboardingNewWallet/doneButtonToAssetList: -33%
  • onboardingNewWallet/total: -33%
  • assetDetails/assetClickToPriceChart: -55%
  • assetDetails/total: -55%
  • solanaAssetDetails/assetClickToPriceChart: -72%
  • solanaAssetDetails/total: -72%
  • importSrpHome/loginToHomeScreen: -15%
  • importSrpHome/openAccountMenuAfterLogin: -72%
  • importSrpHome/homeAfterImportWithNewWallet: -68%
  • importSrpHome/total: -61%
  • sendTransactions/openSendPageFromHome: +67%
  • sendTransactions/selectTokenToSendFormLoaded: -18%
  • sendTransactions/reviewTransactionToConfirmationPage: +36%
  • sendTransactions/total: +34%
  • swap/openSwapPageFromHome: -96%
  • swap/fetchAndDisplaySwapQuotes: +32%
  • swap/total: +11%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 2.6s
  • 🟡 solanaAssetDetails/FCP: p75 2.6s
  • 🟡 importSrpHome/FCP: p75 2.6s
  • 🟡 importSrpHome/LCP: p75 2.6s
  • 🟡 sendTransactions/FCP: p75 2.7s
  • 🟡 swap/FCP: p75 2.6s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 2.85 KiB (0.03%)
  • common: 175 Bytes (0%)

@abretonc7s abretonc7s closed this Apr 20, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants