@wopr-network/platform-ui-core 1.27.7 → 1.27.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/next.config.ts +1 -2
  2. package/package.json +17 -17
  3. package/src/__tests__/account-switcher.test.tsx +21 -20
  4. package/src/__tests__/activity-page.test.tsx +2 -6
  5. package/src/__tests__/add-payment-method-dialog.test.tsx +9 -32
  6. package/src/__tests__/admin-api.test.ts +1 -6
  7. package/src/__tests__/admin-gpu-api.test.ts +1 -3
  8. package/src/__tests__/admin-marketplace-api.test.ts +1 -4
  9. package/src/__tests__/admin-middleware.test.ts +76 -83
  10. package/src/__tests__/affiliate-dashboard.test.tsx +3 -3
  11. package/src/__tests__/api-401-redirect.test.ts +46 -9
  12. package/src/__tests__/api-client.test.ts +3 -5
  13. package/src/__tests__/api-config.test.ts +22 -42
  14. package/src/__tests__/api-fleet-resources.test.ts +1 -2
  15. package/src/__tests__/api-fleet-trpc.test.ts +2 -8
  16. package/src/__tests__/api-null-guards.test.ts +3 -1
  17. package/src/__tests__/audit-log-table-pagination.test.tsx +2 -6
  18. package/src/__tests__/auth-password-reset.test.tsx +7 -21
  19. package/src/__tests__/auth-redirect.test.tsx +8 -2
  20. package/src/__tests__/auth.test.tsx +25 -23
  21. package/src/__tests__/auto-topup-card.test.tsx +4 -12
  22. package/src/__tests__/backups-tab.test.tsx +3 -4
  23. package/src/__tests__/billing-layout-nav-hidden.test.tsx +5 -37
  24. package/src/__tests__/billing-payment-org-invoices.test.tsx +2 -18
  25. package/src/__tests__/billing.test.tsx +8 -39
  26. package/src/__tests__/bot-settings/resources-tab.test.tsx +1 -3
  27. package/src/__tests__/bot-settings/storage-tab.test.tsx +1 -3
  28. package/src/__tests__/bot-settings/vps-upgrade-card.test.tsx +1 -3
  29. package/src/__tests__/bot-settings-restart.test.tsx +1 -3
  30. package/src/__tests__/bot-settings.test.tsx +2 -6
  31. package/src/__tests__/brand.test.ts +6 -26
  32. package/src/__tests__/buy-credits-panel.test.tsx +1 -3
  33. package/src/__tests__/buy-crypto-credits-panel.test.tsx +101 -119
  34. package/src/__tests__/capability-conflicts.test.ts +2 -8
  35. package/src/__tests__/capability-resolver.test.tsx +2 -12
  36. package/src/__tests__/channel-wizard.test.tsx +4 -17
  37. package/src/__tests__/chat/chat-panel.test.tsx +1 -4
  38. package/src/__tests__/chat-store.test.ts +5 -15
  39. package/src/__tests__/command-center.test.tsx +10 -12
  40. package/src/__tests__/compliance-retention-edit.test.tsx +3 -6
  41. package/src/__tests__/confirmation-tracker.test.tsx +3 -18
  42. package/src/__tests__/coupon-input.test.tsx +1 -3
  43. package/src/__tests__/create-instance.test.tsx +1 -3
  44. package/src/__tests__/credit-balance.test.tsx +4 -12
  45. package/src/__tests__/credits.test.tsx +32 -85
  46. package/src/__tests__/email-verification-banner.test.tsx +2 -6
  47. package/src/__tests__/error-boundaries.test.tsx +0 -1
  48. package/src/__tests__/fetch-pricing.test.ts +2 -1
  49. package/src/__tests__/field-oauth.test.tsx +2 -6
  50. package/src/__tests__/fixtures/mock-manifests-data.js +1 -3
  51. package/src/__tests__/fixtures/mock-manifests.ts +2 -4
  52. package/src/__tests__/fleet-health-timestamp.test.tsx +1 -8
  53. package/src/__tests__/fleet-health-update.test.tsx +1 -8
  54. package/src/__tests__/gpu-dashboard.test.tsx +2 -6
  55. package/src/__tests__/instance-detail.test.tsx +3 -9
  56. package/src/__tests__/instance-list.test.tsx +1 -5
  57. package/src/__tests__/layout-snapshots.test.tsx +64 -11
  58. package/src/__tests__/marketplace-admin.test.tsx +2 -6
  59. package/src/__tests__/marketplace.test.tsx +11 -35
  60. package/src/__tests__/merge-api-rates.test.ts +1 -6
  61. package/src/__tests__/middleware.test.ts +32 -219
  62. package/src/__tests__/next-config-headers.test.ts +1 -3
  63. package/src/__tests__/notifications.test.tsx +4 -11
  64. package/src/__tests__/oauth-buttons.test.tsx +36 -59
  65. package/src/__tests__/oauth-error-mapping.test.tsx +2 -6
  66. package/src/__tests__/observability.test.tsx +23 -36
  67. package/src/__tests__/onboarding-page.test.tsx +4 -6
  68. package/src/__tests__/org-billing-api.test.tsx +1 -6
  69. package/src/__tests__/plugin-install-flow.test.tsx +28 -58
  70. package/src/__tests__/plugin-registry.test.tsx +3 -11
  71. package/src/__tests__/plugin-tool-sync.test.ts +1 -3
  72. package/src/__tests__/plugins-catalog-error.test.tsx +2 -6
  73. package/src/__tests__/plugins-toggle-race.test.tsx +3 -5
  74. package/src/__tests__/portfolio-chart.test.tsx +2 -6
  75. package/src/__tests__/promotion-form.test.tsx +2 -6
  76. package/src/__tests__/promotions-list.test.tsx +1 -3
  77. package/src/__tests__/provider-key-api.test.ts +2 -1
  78. package/src/__tests__/resend-verification-button.test.tsx +8 -24
  79. package/src/__tests__/secrets-audit-pagination.test.tsx +1 -3
  80. package/src/__tests__/settings.test.tsx +11 -21
  81. package/src/__tests__/setup-checklist.test.tsx +3 -9
  82. package/src/__tests__/setup.ts +25 -6
  83. package/src/__tests__/snapshot-api.test.ts +2 -1
  84. package/src/__tests__/step-superpowers.test.tsx +1 -3
  85. package/src/__tests__/tenant-context.test.tsx +1 -6
  86. package/src/__tests__/tenant-keys-api.test.ts +3 -4
  87. package/src/__tests__/tenant-table-pagination.test.tsx +2 -6
  88. package/src/__tests__/terminal-log-cleanup.test.tsx +0 -1
  89. package/src/__tests__/transaction-history.test.tsx +190 -238
  90. package/src/__tests__/trpc-types.test.ts +2 -6
  91. package/src/__tests__/use-chat.test.ts +1 -3
  92. package/src/__tests__/use-plugin-setup-chat-stale-closure.test.ts +1 -4
  93. package/src/__tests__/use-sidecar-bridge.test.tsx +105 -0
  94. package/src/__tests__/use-webmcp.test.ts +1 -3
  95. package/src/__tests__/validate-elevenlabs-key.test.ts +2 -1
  96. package/src/__tests__/verify-page.test.tsx +4 -13
  97. package/src/__tests__/verify-redirect.test.tsx +2 -6
  98. package/src/app/(auth)/error.tsx +1 -7
  99. package/src/app/(auth)/forgot-password/page.tsx +4 -18
  100. package/src/app/(auth)/login/page.tsx +5 -22
  101. package/src/app/(auth)/reset-password/page.tsx +2 -12
  102. package/src/app/(auth)/signup/page.tsx +10 -44
  103. package/src/app/(auth)/verify/page.tsx +47 -0
  104. package/src/app/(dashboard)/billing/credits/page.tsx +14 -67
  105. package/src/app/(dashboard)/billing/error.tsx +2 -10
  106. package/src/app/(dashboard)/billing/layout.tsx +12 -62
  107. package/src/app/(dashboard)/billing/payment/page.tsx +17 -68
  108. package/src/app/(dashboard)/billing/plans/page.tsx +3 -9
  109. package/src/app/(dashboard)/billing/usage/hosted/page.tsx +8 -25
  110. package/src/app/(dashboard)/billing/usage/page.tsx +63 -103
  111. package/src/app/(dashboard)/changesets/[id]/changeset-detail-client.tsx +9 -27
  112. package/src/app/(dashboard)/changesets/[id]/error.tsx +2 -6
  113. package/src/app/(dashboard)/changesets/error.tsx +1 -7
  114. package/src/app/(dashboard)/chat/page.tsx +2 -6
  115. package/src/app/(dashboard)/dashboard/network/page.tsx +5 -19
  116. package/src/app/(dashboard)/error.tsx +1 -7
  117. package/src/app/(dashboard)/layout.tsx +15 -36
  118. package/src/app/(dashboard)/marketplace/[plugin]/page.tsx +14 -51
  119. package/src/app/(dashboard)/marketplace/error.tsx +1 -7
  120. package/src/app/(dashboard)/marketplace/page.tsx +6 -27
  121. package/src/app/(dashboard)/not-found.tsx +2 -5
  122. package/src/app/(dashboard)/onboarding/page.tsx +5 -22
  123. package/src/app/(dashboard)/settings/account/page.tsx +1 -6
  124. package/src/app/(dashboard)/settings/activity/page.tsx +8 -34
  125. package/src/app/(dashboard)/settings/api-keys/page.tsx +15 -60
  126. package/src/app/(dashboard)/settings/brain/page.tsx +9 -31
  127. package/src/app/(dashboard)/settings/error.tsx +2 -10
  128. package/src/app/(dashboard)/settings/notifications/page.tsx +2 -6
  129. package/src/app/(dashboard)/settings/org/page.tsx +13 -56
  130. package/src/app/(dashboard)/settings/page.tsx +1 -0
  131. package/src/app/(dashboard)/settings/profile/page.tsx +126 -73
  132. package/src/app/(dashboard)/settings/providers/page.tsx +21 -78
  133. package/src/app/(dashboard)/settings/secrets/page.tsx +13 -58
  134. package/src/app/(dashboard)/settings/security/page.tsx +31 -111
  135. package/src/app/admin/email-templates/email-templates-client.tsx +15 -58
  136. package/src/app/admin/error.tsx +1 -7
  137. package/src/app/admin/fleet-updates/error.tsx +1 -7
  138. package/src/app/admin/fleet-updates/fleet-updates-client.tsx +10 -50
  139. package/src/app/admin/layout.tsx +4 -0
  140. package/src/app/admin/payment-methods/page.tsx +9 -38
  141. package/src/app/admin/products/error.tsx +2 -7
  142. package/src/app/admin/products/page.tsx +1 -4
  143. package/src/app/admin/promotions/[id]/page.tsx +9 -38
  144. package/src/app/admin/promotions/page.tsx +9 -36
  145. package/src/app/admin/rate-overrides/page.tsx +9 -45
  146. package/src/app/auth/callback/[provider]/page.tsx +1 -8
  147. package/src/app/auth/verify/page.tsx +9 -36
  148. package/src/app/channels/error.tsx +2 -10
  149. package/src/app/channels/layout.tsx +9 -0
  150. package/src/app/channels/page.tsx +8 -20
  151. package/src/app/channels/setup/[plugin]/page.tsx +3 -5
  152. package/src/app/error.tsx +1 -7
  153. package/src/app/fleet/error.tsx +1 -7
  154. package/src/app/fleet/layout.tsx +5 -0
  155. package/src/app/fleet/settings/page.tsx +1 -3
  156. package/src/app/global-error.tsx +2 -10
  157. package/src/app/globals.css +1 -4
  158. package/src/app/instances/[id]/instance-detail-client.tsx +51 -125
  159. package/src/app/instances/error.tsx +2 -10
  160. package/src/app/instances/instance-list-client.tsx +20 -69
  161. package/src/app/instances/layout.tsx +9 -0
  162. package/src/app/instances/new/create-instance-client.tsx +10 -31
  163. package/src/app/layout.tsx +2 -10
  164. package/src/app/not-found.tsx +1 -3
  165. package/src/app/page.tsx +1 -2
  166. package/src/app/plugins/error.tsx +2 -10
  167. package/src/app/plugins/layout.tsx +5 -0
  168. package/src/app/plugins/page.tsx +16 -48
  169. package/src/app/pricing/error.tsx +1 -7
  170. package/src/app/privacy/page.tsx +93 -150
  171. package/src/app/status/error.tsx +1 -7
  172. package/src/app/terms/page.tsx +89 -144
  173. package/src/components/account-switcher.tsx +25 -52
  174. package/src/components/admin/accounting-dashboard.tsx +1 -3
  175. package/src/components/admin/admin-guard.tsx +1 -3
  176. package/src/components/admin/admin-nav.tsx +1 -3
  177. package/src/components/admin/affiliate-dashboard.tsx +25 -94
  178. package/src/components/admin/audit-log-table.tsx +13 -49
  179. package/src/components/admin/billing-health-dashboard.tsx +7 -25
  180. package/src/components/admin/bulk-actions-bar.test.tsx +1 -7
  181. package/src/components/admin/bulk-actions-bar.tsx +1 -3
  182. package/src/components/admin/bulk-export-dialog.test.tsx +1 -7
  183. package/src/components/admin/bulk-export-dialog.tsx +6 -32
  184. package/src/components/admin/bulk-grant-dialog.test.tsx +2 -6
  185. package/src/components/admin/bulk-grant-dialog.tsx +4 -15
  186. package/src/components/admin/bulk-preview-dialog.tsx +3 -12
  187. package/src/components/admin/bulk-reactivate-dialog.tsx +1 -7
  188. package/src/components/admin/bulk-select-all-banner.tsx +1 -6
  189. package/src/components/admin/bulk-suspend-dialog.tsx +5 -12
  190. package/src/components/admin/bulk-undo-toast.tsx +1 -2
  191. package/src/components/admin/compliance-dashboard.tsx +31 -101
  192. package/src/components/admin/gpu-dashboard.tsx +21 -70
  193. package/src/components/admin/grant-credits-dialog.tsx +4 -17
  194. package/src/components/admin/incident-dashboard.tsx +10 -25
  195. package/src/components/admin/inference-dashboard.tsx +14 -54
  196. package/src/components/admin/marketplace-admin.tsx +18 -60
  197. package/src/components/admin/migrations-dashboard.tsx +9 -42
  198. package/src/components/admin/onboarding-dashboard.tsx +14 -64
  199. package/src/components/admin/pool-config-dashboard.tsx +4 -10
  200. package/src/components/admin/products/fleet-form.tsx +2 -11
  201. package/src/components/admin/products/nav-editor.tsx +3 -10
  202. package/src/components/admin/promotions/promotion-form.tsx +9 -42
  203. package/src/components/admin/roles-dashboard.tsx +7 -34
  204. package/src/components/admin/suspend-dialog.tsx +4 -11
  205. package/src/components/admin/tenant-notes-panel.tsx +1 -3
  206. package/src/components/admin/tenant-row-actions.tsx +4 -20
  207. package/src/components/admin/tenant-table.tsx +12 -49
  208. package/src/components/auth/auth-redirect.tsx +11 -3
  209. package/src/components/auth/email-verification-result-banner.tsx +1 -3
  210. package/src/components/auth/resend-verification-button.tsx +2 -10
  211. package/src/components/auth/wopr-wordmark.tsx +1 -3
  212. package/src/components/billing/add-payment-method-dialog.tsx +1 -2
  213. package/src/components/billing/affiliate-dashboard.tsx +4 -16
  214. package/src/components/billing/amount-selector.tsx +1 -3
  215. package/src/components/billing/auto-topup-card.tsx +2 -11
  216. package/src/components/billing/buy-credits-panel.tsx +14 -17
  217. package/src/components/billing/byok-callout.tsx +6 -8
  218. package/src/components/billing/confirmation-tracker.tsx +4 -14
  219. package/src/components/billing/credit-balance-badge.tsx +22 -0
  220. package/src/components/billing/credit-balance.tsx +3 -9
  221. package/src/components/billing/crypto-checkout.tsx +5 -24
  222. package/src/components/billing/degraded-state-banner.tsx +1 -3
  223. package/src/components/billing/deposit-view.tsx +301 -41
  224. package/src/components/billing/dividend-banner.tsx +1 -3
  225. package/src/components/billing/dividend-eligibility.tsx +3 -12
  226. package/src/components/billing/dividend-pool-stats.tsx +6 -20
  227. package/src/components/billing/first-dividend-dialog.tsx +2 -2
  228. package/src/components/billing/org-billing-page.tsx +8 -31
  229. package/src/components/billing/payment-method-picker.tsx +2 -10
  230. package/src/components/billing/suspension-banner.tsx +2 -7
  231. package/src/components/billing/transaction-history.tsx +10 -58
  232. package/src/components/billing/unified-checkout.tsx +547 -0
  233. package/src/components/bot-settings/backups-tab.tsx +9 -33
  234. package/src/components/bot-settings/bot-settings-client.tsx +32 -134
  235. package/src/components/bot-settings/resources-tab.tsx +2 -9
  236. package/src/components/bot-settings/storage-tab.tsx +19 -48
  237. package/src/components/bot-settings/vps-info-panel.tsx +3 -11
  238. package/src/components/bot-settings/vps-upgrade-card.tsx +3 -4
  239. package/src/components/brand-hydrator.tsx +13 -0
  240. package/src/components/channel-wizard/field-interactive.tsx +1 -3
  241. package/src/components/channel-wizard/field-qr.tsx +10 -39
  242. package/src/components/channel-wizard/step-renderer.tsx +5 -28
  243. package/src/components/channel-wizard/wizard.tsx +6 -31
  244. package/src/components/chat/chat-message.tsx +1 -4
  245. package/src/components/chat/chat-panel.tsx +4 -18
  246. package/src/components/chat/chat-widget.tsx +3 -14
  247. package/src/components/dashboard/command-center.tsx +15 -61
  248. package/src/components/fleet/update-settings-card.tsx +7 -23
  249. package/src/components/instance-update-banner.tsx +130 -0
  250. package/src/components/instances/friends-tab.test.tsx +2 -9
  251. package/src/components/instances/friends-tab.tsx +18 -74
  252. package/src/components/instances/update-available-badge.tsx +2 -11
  253. package/src/components/landing/hero.tsx +3 -9
  254. package/src/components/landing/landing-page.tsx +1 -3
  255. package/src/components/landing/portfolio-chart.tsx +4 -9
  256. package/src/components/landing/story-sections.tsx +1 -3
  257. package/src/components/landing/terminal-sequence.tsx +4 -17
  258. package/src/components/marketplace/empty-state.tsx +2 -6
  259. package/src/components/marketplace/first-visit-hero.tsx +1 -3
  260. package/src/components/marketplace/install-wizard.tsx +20 -77
  261. package/src/components/marketplace/marketplace-tabs.tsx +1 -4
  262. package/src/components/marketplace/plugin-card.tsx +2 -9
  263. package/src/components/marketplace/superpower-content.tsx +1 -3
  264. package/src/components/marketplace/terminal-search.tsx +2 -8
  265. package/src/components/oauth-buttons.tsx +29 -14
  266. package/src/components/observability/fleet-health.tsx +5 -18
  267. package/src/components/observability/health-overview.tsx +7 -20
  268. package/src/components/observability/logs-viewer.tsx +8 -32
  269. package/src/components/observability/metrics-dashboard.tsx +2 -15
  270. package/src/components/onboarding/fallback-setup.tsx +6 -25
  271. package/src/components/onboarding/setup-checklist.tsx +18 -51
  272. package/src/components/onboarding/step-superpowers.tsx +1 -4
  273. package/src/components/plugin-setup/setup-chat-panel.tsx +6 -22
  274. package/src/components/pricing/dividend-calculator.tsx +6 -12
  275. package/src/components/pricing/dividend-stats.tsx +5 -17
  276. package/src/components/pricing/pricing-page.tsx +17 -36
  277. package/src/components/settings/create-org-wizard.tsx +2 -5
  278. package/src/components/sidebar.tsx +7 -42
  279. package/src/components/sidecar-frame.tsx +78 -0
  280. package/src/components/status/status-page.tsx +6 -28
  281. package/src/components/ui/alert-dialog.tsx +8 -25
  282. package/src/components/ui/badge.tsx +2 -8
  283. package/src/components/ui/banner.tsx +1 -6
  284. package/src/components/ui/card.tsx +5 -24
  285. package/src/components/ui/checkbox.tsx +1 -5
  286. package/src/components/ui/collapsible.tsx +3 -8
  287. package/src/components/ui/dialog.tsx +4 -10
  288. package/src/components/ui/dropdown-menu.tsx +9 -18
  289. package/src/components/ui/form.tsx +2 -16
  290. package/src/components/ui/popover.tsx +3 -23
  291. package/src/components/ui/progress.tsx +1 -5
  292. package/src/components/ui/radio-group.tsx +3 -15
  293. package/src/components/ui/select.tsx +4 -17
  294. package/src/components/ui/sheet.tsx +5 -19
  295. package/src/components/ui/skeleton.tsx +1 -7
  296. package/src/components/ui/table.tsx +5 -22
  297. package/src/components/ui/tabs.tsx +3 -13
  298. package/src/components/ui/tooltip.tsx +1 -1
  299. package/src/components/unified-sidebar.tsx +493 -0
  300. package/src/hooks/__tests__/use-fleet-sse.test.ts +1 -4
  301. package/src/hooks/__tests__/use-save-queue.test.ts +2 -8
  302. package/src/hooks/use-credit-balance.ts +27 -0
  303. package/src/hooks/use-my-org-role.ts +1 -3
  304. package/src/hooks/use-plugin-registry.ts +8 -14
  305. package/src/hooks/use-plugin-setup-chat.ts +2 -5
  306. package/src/hooks/use-sidecar-bridge.tsx +148 -0
  307. package/src/hooks/use-webmcp.ts +1 -4
  308. package/src/lib/__tests__/admin-api.test.ts +1 -3
  309. package/src/lib/__tests__/api-bot-crud.test.ts +8 -18
  310. package/src/lib/__tests__/api-fetch.test.ts +4 -16
  311. package/src/lib/__tests__/org-billing-api.test.ts +1 -3
  312. package/src/lib/__tests__/pricing-data.test.ts +0 -8
  313. package/src/lib/__tests__/settings-api.test.ts +1 -3
  314. package/src/lib/admin-affiliate-api.ts +2 -7
  315. package/src/lib/admin-api.ts +6 -26
  316. package/src/lib/admin-incident-api.ts +11 -19
  317. package/src/lib/admin-marketplace-api.ts +1 -5
  318. package/src/lib/api-config.test.ts +5 -50
  319. package/src/lib/api.ts +143 -122
  320. package/src/lib/auth-client.ts +1 -2
  321. package/src/lib/bot-settings-data.ts +11 -36
  322. package/src/lib/brand-config.ts +56 -115
  323. package/src/lib/brand.ts +2 -15
  324. package/src/lib/chat/use-chat.ts +2 -7
  325. package/src/lib/cost-comparison-data.test.ts +1 -3
  326. package/src/lib/cost-comparison-data.ts +1 -4
  327. package/src/lib/errors.ts +1 -4
  328. package/src/lib/fetch-utils.test.ts +26 -9
  329. package/src/lib/fetch-utils.ts +40 -11
  330. package/src/lib/logger.ts +2 -0
  331. package/src/lib/marketplace-data.ts +3 -11
  332. package/src/lib/oauth-errors.ts +2 -4
  333. package/src/lib/onboarding-data.ts +3 -11
  334. package/src/lib/org-api.ts +2 -10
  335. package/src/lib/org-billing-api.ts +5 -19
  336. package/src/lib/plugin/tool-definitions.ts +1 -2
  337. package/src/lib/require-auth.ts +57 -0
  338. package/src/lib/settings-api.ts +1 -4
  339. package/src/lib/sidecar-routes.ts +43 -0
  340. package/src/lib/trpc-server.ts +49 -0
  341. package/src/lib/trpc-types.ts +4 -6
  342. package/src/lib/trpc.tsx +12 -4
  343. package/src/lib/validate-redirect-url.ts +1 -4
  344. package/src/lib/webmcp/marketplace-onboarding-tools.ts +6 -16
  345. package/src/lib/webmcp/register.ts +1 -4
  346. package/src/lib/webmcp/tools.ts +2 -9
  347. package/src/proxy.ts +35 -212
  348. package/src/types/missing-deps.d.ts +2 -8
  349. package/tsconfig.json +1 -8
  350. package/biome.json +0 -52
  351. package/src/__tests__/__snapshots__/layout-snapshots.test.tsx.snap +0 -741
  352. package/src/__tests__/billing-byok-callout.test.tsx +0 -76
  353. package/src/lib/__tests__/__snapshots__/pricing-data.test.ts.snap +0 -112
@@ -1,73 +1,113 @@
1
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
1
2
  import { render, screen, waitFor } from "@testing-library/react";
2
3
  import userEvent from "@testing-library/user-event";
4
+ import { createElement, type ReactNode } from "react";
3
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
4
- import type { CreditHistoryResponse } from "@/lib/api";
6
+ import { trpcVanillaProxy } from "./setup.js";
5
7
 
6
- const mockGetCreditHistory = vi.fn<(cursor?: string) => Promise<CreditHistoryResponse>>();
8
+ // Mock tRPC hook return value
9
+ const mockUseQuery = vi.fn();
10
+ const mockRefetch = vi.fn();
7
11
 
8
- vi.mock("@/lib/api", () => ({
9
- getCreditHistory: (...args: unknown[]) => mockGetCreditHistory(args[0] as string | undefined),
12
+ vi.mock("@/lib/trpc", () => ({
13
+ trpc: {
14
+ billing: {
15
+ creditsDailySummary: {
16
+ useQuery: (...args: unknown[]) => mockUseQuery(...args),
17
+ },
18
+ },
19
+ },
20
+ trpcVanilla: trpcVanillaProxy,
10
21
  }));
11
22
 
12
23
  // Must import AFTER vi.mock
13
24
  const { TransactionHistory } = await import("@/components/billing/transaction-history");
14
25
 
26
+ const NANO = 1_000_000_000;
27
+
28
+ function createWrapper() {
29
+ const queryClient = new QueryClient({
30
+ defaultOptions: { queries: { retry: false } },
31
+ });
32
+ return function Wrapper({ children }: { children: ReactNode }) {
33
+ return createElement(QueryClientProvider, { client: queryClient }, children);
34
+ };
35
+ }
36
+
15
37
  describe("TransactionHistory", () => {
16
38
  beforeEach(() => {
17
- mockGetCreditHistory.mockReset();
39
+ mockUseQuery.mockReset();
40
+ mockRefetch.mockReset();
18
41
  });
19
42
 
20
43
  it("shows loading skeletons initially", () => {
21
- // Never resolve — keeps component in loading state
22
- // biome-ignore lint/suspicious/noEmptyBlockStatements: intentionally never-resolving promise for loading state test
23
- mockGetCreditHistory.mockReturnValue(new Promise(() => {}));
24
- render(<TransactionHistory />);
44
+ mockUseQuery.mockReturnValue({
45
+ data: undefined,
46
+ isLoading: true,
47
+ error: null,
48
+ refetch: mockRefetch,
49
+ });
50
+ render(<TransactionHistory />, { wrapper: createWrapper() });
25
51
  expect(screen.getByText("Transaction History")).toBeInTheDocument();
26
- // 4 skeleton rows are rendered (no transaction text visible)
27
52
  expect(screen.queryByText("No transactions yet.")).toBeNull();
28
53
  });
29
54
 
30
55
  it("renders empty state when no transactions", async () => {
31
- mockGetCreditHistory.mockResolvedValue({ transactions: [], nextCursor: null });
32
- render(<TransactionHistory />);
56
+ mockUseQuery.mockReturnValue({
57
+ data: { rows: [] },
58
+ isLoading: false,
59
+ error: null,
60
+ refetch: mockRefetch,
61
+ });
62
+ render(<TransactionHistory />, { wrapper: createWrapper() });
33
63
  await waitFor(() => {
34
64
  expect(screen.getByText("No transactions yet.")).toBeInTheDocument();
35
65
  });
36
66
  });
37
67
 
38
68
  it("renders transaction descriptions", async () => {
39
- mockGetCreditHistory.mockResolvedValue({
40
- transactions: [
41
- {
42
- id: "tx-1",
43
- type: "purchase",
44
- description: "Credit top-up",
45
- amount: 25.0,
46
- createdAt: "2025-06-15T10:00:00Z",
47
- },
48
- ],
49
- nextCursor: null,
69
+ mockUseQuery.mockReturnValue({
70
+ data: {
71
+ rows: [
72
+ {
73
+ id: "tx-1",
74
+ entryType: "purchase",
75
+ description: "Credit top-up",
76
+ signedAmountNano: 25 * NANO,
77
+ entryCount: 1,
78
+ postedAt: "2025-06-15T10:00:00Z",
79
+ },
80
+ ],
81
+ },
82
+ isLoading: false,
83
+ error: null,
84
+ refetch: mockRefetch,
50
85
  });
51
- render(<TransactionHistory />);
86
+ render(<TransactionHistory />, { wrapper: createWrapper() });
52
87
  await waitFor(() => {
53
88
  expect(screen.getByText("Credit top-up")).toBeInTheDocument();
54
89
  });
55
90
  });
56
91
 
57
92
  it("renders positive amounts with + prefix and emerald color", async () => {
58
- mockGetCreditHistory.mockResolvedValue({
59
- transactions: [
60
- {
61
- id: "tx-1",
62
- type: "purchase",
63
- description: "Top-up",
64
- amount: 50.0,
65
- createdAt: "2025-06-15T10:00:00Z",
66
- },
67
- ],
68
- nextCursor: null,
93
+ mockUseQuery.mockReturnValue({
94
+ data: {
95
+ rows: [
96
+ {
97
+ id: "tx-1",
98
+ entryType: "purchase",
99
+ description: "Top-up",
100
+ signedAmountNano: 50 * NANO,
101
+ entryCount: 1,
102
+ postedAt: "2025-06-15T10:00:00Z",
103
+ },
104
+ ],
105
+ },
106
+ isLoading: false,
107
+ error: null,
108
+ refetch: mockRefetch,
69
109
  });
70
- render(<TransactionHistory />);
110
+ render(<TransactionHistory />, { wrapper: createWrapper() });
71
111
  await waitFor(() => {
72
112
  const amountEl = screen.getByText("+$50.00");
73
113
  expect(amountEl).toBeInTheDocument();
@@ -76,19 +116,24 @@ describe("TransactionHistory", () => {
76
116
  });
77
117
 
78
118
  it("renders negative amounts with - prefix and red color", async () => {
79
- mockGetCreditHistory.mockResolvedValue({
80
- transactions: [
81
- {
82
- id: "tx-1",
83
- type: "bot_runtime",
84
- description: "Bot usage",
85
- amount: -3.5,
86
- createdAt: "2025-06-15T10:00:00Z",
87
- },
88
- ],
89
- nextCursor: null,
119
+ mockUseQuery.mockReturnValue({
120
+ data: {
121
+ rows: [
122
+ {
123
+ id: "tx-1",
124
+ entryType: "bot_runtime",
125
+ description: "Bot usage",
126
+ signedAmountNano: -3.5 * NANO,
127
+ entryCount: 1,
128
+ postedAt: "2025-06-15T10:00:00Z",
129
+ },
130
+ ],
131
+ },
132
+ isLoading: false,
133
+ error: null,
134
+ refetch: mockRefetch,
90
135
  });
91
- render(<TransactionHistory />);
136
+ render(<TransactionHistory />, { wrapper: createWrapper() });
92
137
  await waitFor(() => {
93
138
  const amountEl = screen.getByText("-$3.50");
94
139
  expect(amountEl).toBeInTheDocument();
@@ -97,61 +142,72 @@ describe("TransactionHistory", () => {
97
142
  });
98
143
 
99
144
  it("renders correct type badge labels", async () => {
100
- mockGetCreditHistory.mockResolvedValue({
101
- transactions: [
102
- {
103
- id: "tx-1",
104
- type: "purchase",
105
- description: "a",
106
- amount: 10,
107
- createdAt: "2025-01-01T00:00:00Z",
108
- },
109
- {
110
- id: "tx-2",
111
- type: "signup_credit",
112
- description: "b",
113
- amount: 5,
114
- createdAt: "2025-01-01T00:00:00Z",
115
- },
116
- {
117
- id: "tx-3",
118
- type: "bot_runtime",
119
- description: "c",
120
- amount: -2,
121
- createdAt: "2025-01-01T00:00:00Z",
122
- },
123
- {
124
- id: "tx-4",
125
- type: "refund",
126
- description: "d",
127
- amount: 3,
128
- createdAt: "2025-01-01T00:00:00Z",
129
- },
130
- {
131
- id: "tx-5",
132
- type: "bonus",
133
- description: "e",
134
- amount: 1,
135
- createdAt: "2025-01-01T00:00:00Z",
136
- },
137
- {
138
- id: "tx-6",
139
- type: "adjustment",
140
- description: "f",
141
- amount: -1,
142
- createdAt: "2025-01-01T00:00:00Z",
143
- },
144
- {
145
- id: "tx-7",
146
- type: "community_dividend",
147
- description: "g",
148
- amount: 2,
149
- createdAt: "2025-01-01T00:00:00Z",
150
- },
151
- ],
152
- nextCursor: null,
145
+ mockUseQuery.mockReturnValue({
146
+ data: {
147
+ rows: [
148
+ {
149
+ id: "tx-1",
150
+ entryType: "purchase",
151
+ description: "a",
152
+ signedAmountNano: 10 * NANO,
153
+ entryCount: 1,
154
+ postedAt: "2025-01-01T00:00:00Z",
155
+ },
156
+ {
157
+ id: "tx-2",
158
+ entryType: "signup_credit",
159
+ description: "b",
160
+ signedAmountNano: 5 * NANO,
161
+ entryCount: 1,
162
+ postedAt: "2025-01-01T00:00:00Z",
163
+ },
164
+ {
165
+ id: "tx-3",
166
+ entryType: "bot_runtime",
167
+ description: "c",
168
+ signedAmountNano: -2 * NANO,
169
+ entryCount: 1,
170
+ postedAt: "2025-01-01T00:00:00Z",
171
+ },
172
+ {
173
+ id: "tx-4",
174
+ entryType: "refund",
175
+ description: "d",
176
+ signedAmountNano: 3 * NANO,
177
+ entryCount: 1,
178
+ postedAt: "2025-01-01T00:00:00Z",
179
+ },
180
+ {
181
+ id: "tx-5",
182
+ entryType: "bonus",
183
+ description: "e",
184
+ signedAmountNano: 1 * NANO,
185
+ entryCount: 1,
186
+ postedAt: "2025-01-01T00:00:00Z",
187
+ },
188
+ {
189
+ id: "tx-6",
190
+ entryType: "adjustment",
191
+ description: "f",
192
+ signedAmountNano: -1 * NANO,
193
+ entryCount: 1,
194
+ postedAt: "2025-01-01T00:00:00Z",
195
+ },
196
+ {
197
+ id: "tx-7",
198
+ entryType: "community_dividend",
199
+ description: "g",
200
+ signedAmountNano: 2 * NANO,
201
+ entryCount: 1,
202
+ postedAt: "2025-01-01T00:00:00Z",
203
+ },
204
+ ],
205
+ },
206
+ isLoading: false,
207
+ error: null,
208
+ refetch: mockRefetch,
153
209
  });
154
- render(<TransactionHistory />);
210
+ render(<TransactionHistory />, { wrapper: createWrapper() });
155
211
  await waitFor(() => {
156
212
  expect(screen.getByText("Purchase")).toBeInTheDocument();
157
213
  expect(screen.getByText("Signup credit")).toBeInTheDocument();
@@ -164,28 +220,37 @@ describe("TransactionHistory", () => {
164
220
  });
165
221
 
166
222
  it("renders formatted dates", async () => {
167
- mockGetCreditHistory.mockResolvedValue({
168
- transactions: [
169
- {
170
- id: "tx-1",
171
- type: "purchase",
172
- description: "Top-up",
173
- amount: 10,
174
- createdAt: "2025-06-15T10:00:00Z",
175
- },
176
- ],
177
- nextCursor: null,
223
+ mockUseQuery.mockReturnValue({
224
+ data: {
225
+ rows: [
226
+ {
227
+ id: "tx-1",
228
+ entryType: "purchase",
229
+ description: "Top-up",
230
+ signedAmountNano: 10 * NANO,
231
+ entryCount: 1,
232
+ postedAt: "2025-06-15T10:00:00Z",
233
+ },
234
+ ],
235
+ },
236
+ isLoading: false,
237
+ error: null,
238
+ refetch: mockRefetch,
178
239
  });
179
- render(<TransactionHistory />);
240
+ render(<TransactionHistory />, { wrapper: createWrapper() });
180
241
  await waitFor(() => {
181
- // toLocaleDateString("en-US", { month: "short", day: "numeric" }) → "Jun 15"
182
242
  expect(screen.getByText("Jun 15")).toBeInTheDocument();
183
243
  });
184
244
  });
185
245
 
186
246
  it("shows error state with retry button", async () => {
187
- mockGetCreditHistory.mockRejectedValue(new Error("Network error"));
188
- render(<TransactionHistory />);
247
+ mockUseQuery.mockReturnValue({
248
+ data: undefined,
249
+ isLoading: false,
250
+ error: new Error("Network error"),
251
+ refetch: mockRefetch,
252
+ });
253
+ render(<TransactionHistory />, { wrapper: createWrapper() });
189
254
  await waitFor(() => {
190
255
  expect(screen.getByText("Failed to load transactions.")).toBeInTheDocument();
191
256
  expect(screen.getByText("Retry")).toBeInTheDocument();
@@ -194,132 +259,19 @@ describe("TransactionHistory", () => {
194
259
 
195
260
  it("retries loading on retry button click", async () => {
196
261
  const user = userEvent.setup();
197
- // First call fails, second succeeds
198
- mockGetCreditHistory
199
- .mockRejectedValueOnce(new Error("fail"))
200
- .mockResolvedValueOnce({ transactions: [], nextCursor: null });
262
+ mockUseQuery.mockReturnValue({
263
+ data: undefined,
264
+ isLoading: false,
265
+ error: new Error("fail"),
266
+ refetch: mockRefetch,
267
+ });
201
268
 
202
- render(<TransactionHistory />);
269
+ render(<TransactionHistory />, { wrapper: createWrapper() });
203
270
  await waitFor(() => {
204
271
  expect(screen.getByText("Retry")).toBeInTheDocument();
205
272
  });
206
273
 
207
274
  await user.click(screen.getByText("Retry"));
208
- await waitFor(() => {
209
- expect(screen.getByText("No transactions yet.")).toBeInTheDocument();
210
- });
211
- expect(mockGetCreditHistory).toHaveBeenCalledTimes(2);
212
- });
213
-
214
- it("shows 'Load more' button when cursor exists", async () => {
215
- mockGetCreditHistory.mockResolvedValue({
216
- transactions: [
217
- {
218
- id: "tx-1",
219
- type: "purchase",
220
- description: "Top-up",
221
- amount: 10,
222
- createdAt: "2025-01-01T00:00:00Z",
223
- },
224
- ],
225
- nextCursor: "next-page-cursor",
226
- });
227
- render(<TransactionHistory />);
228
- await waitFor(() => {
229
- expect(screen.getByText("Load more")).toBeInTheDocument();
230
- });
231
- });
232
-
233
- it("does not show 'Load more' when cursor is null", async () => {
234
- mockGetCreditHistory.mockResolvedValue({
235
- transactions: [
236
- {
237
- id: "tx-1",
238
- type: "purchase",
239
- description: "Top-up",
240
- amount: 10,
241
- createdAt: "2025-01-01T00:00:00Z",
242
- },
243
- ],
244
- nextCursor: null,
245
- });
246
- render(<TransactionHistory />);
247
- await waitFor(() => {
248
- expect(screen.getByText("Top-up")).toBeInTheDocument();
249
- });
250
- expect(screen.queryByText("Load more")).toBeNull();
251
- });
252
-
253
- it("loads more transactions on 'Load more' click", async () => {
254
- const user = userEvent.setup();
255
- mockGetCreditHistory
256
- .mockResolvedValueOnce({
257
- transactions: [
258
- {
259
- id: "tx-1",
260
- type: "purchase",
261
- description: "First batch",
262
- amount: 10,
263
- createdAt: "2025-01-01T00:00:00Z",
264
- },
265
- ],
266
- nextCursor: "cursor-2",
267
- })
268
- .mockResolvedValueOnce({
269
- transactions: [
270
- {
271
- id: "tx-2",
272
- type: "refund",
273
- description: "Second batch",
274
- amount: 5,
275
- createdAt: "2025-01-02T00:00:00Z",
276
- },
277
- ],
278
- nextCursor: null,
279
- });
280
-
281
- render(<TransactionHistory />);
282
- await waitFor(() => {
283
- expect(screen.getByText("First batch")).toBeInTheDocument();
284
- });
285
-
286
- await user.click(screen.getByText("Load more"));
287
- await waitFor(() => {
288
- expect(screen.getByText("Second batch")).toBeInTheDocument();
289
- });
290
- // Both batches visible
291
- expect(screen.getByText("First batch")).toBeInTheDocument();
292
- // Cursor was passed to second call
293
- expect(mockGetCreditHistory).toHaveBeenCalledWith("cursor-2");
294
- });
295
-
296
- it("shows inline error when load-more fails but keeps existing transactions", async () => {
297
- const user = userEvent.setup();
298
- mockGetCreditHistory
299
- .mockResolvedValueOnce({
300
- transactions: [
301
- {
302
- id: "tx-1",
303
- type: "purchase",
304
- description: "Existing",
305
- amount: 10,
306
- createdAt: "2025-01-01T00:00:00Z",
307
- },
308
- ],
309
- nextCursor: "cursor-2",
310
- })
311
- .mockRejectedValueOnce(new Error("fail"));
312
-
313
- render(<TransactionHistory />);
314
- await waitFor(() => {
315
- expect(screen.getByText("Existing")).toBeInTheDocument();
316
- });
317
-
318
- await user.click(screen.getByText("Load more"));
319
- await waitFor(() => {
320
- expect(screen.getByText("Failed to load more transactions.")).toBeInTheDocument();
321
- });
322
- // Original transaction still visible
323
- expect(screen.getByText("Existing")).toBeInTheDocument();
275
+ expect(mockRefetch).toHaveBeenCalledTimes(1);
324
276
  });
325
277
  });
@@ -70,9 +70,7 @@ describe("trpc-types AppRouter contract", () => {
70
70
  type _CheckActivate = Assert<"activate" extends keyof Promos ? true : false>;
71
71
  type _CheckPause = Assert<"pause" extends keyof Promos ? true : false>;
72
72
  type _CheckCancel = Assert<"cancel" extends keyof Promos ? true : false>;
73
- type _CheckGenerateCouponBatch = Assert<
74
- "generateCouponBatch" extends keyof Promos ? true : false
75
- >;
73
+ type _CheckGenerateCouponBatch = Assert<"generateCouponBatch" extends keyof Promos ? true : false>;
76
74
  // Runtime assertion is intentionally trivial — the real gate is tsc --noEmit
77
75
  // which fails if any Assert<...> type above resolves to `false`.
78
76
  expect(true).toBe(true);
@@ -82,9 +80,7 @@ describe("trpc-types AppRouter contract", () => {
82
80
  type Caps = AppRouter["_def"]["record"]["capabilities"];
83
81
  type _CheckStoreKey = Assert<"storeKey" extends keyof Caps ? true : false>;
84
82
  type _CheckTestKey = Assert<"testKey" extends keyof Caps ? true : false>;
85
- type _CheckListCapabilitySettings = Assert<
86
- "listCapabilitySettings" extends keyof Caps ? true : false
87
- >;
83
+ type _CheckListCapabilitySettings = Assert<"listCapabilitySettings" extends keyof Caps ? true : false>;
88
84
  type _CheckListCapabilityMeta = Assert<"listCapabilityMeta" extends keyof Caps ? true : false>;
89
85
  // Runtime assertion is intentionally trivial — the real gate is tsc --noEmit
90
86
  // which fails if any Assert<...> type above resolves to `false`.
@@ -222,9 +222,7 @@ describe("useChat", () => {
222
222
  expect(result.current.messages[0].role).toBe("user");
223
223
  expect(result.current.messages[0].content).toBe("test");
224
224
  expect(result.current.messages[1].role).toBe("bot");
225
- expect(result.current.messages[1].content).toBe(
226
- "Sorry, your message could not be sent. Please try again.",
227
- );
225
+ expect(result.current.messages[1].content).toBe("Sorry, your message could not be sent. Please try again.");
228
226
 
229
227
  sse.close();
230
228
  });
@@ -24,10 +24,7 @@ describe("usePluginSetupChat sendMessage stale closure", () => {
24
24
  result.current.sendMessage("hello");
25
25
  });
26
26
 
27
- expect(apiFetch).toHaveBeenCalledWith(
28
- "/chat/setup/message",
29
- expect.objectContaining({ method: "POST" }),
30
- );
27
+ expect(apiFetch).toHaveBeenCalledWith("/chat/setup/message", expect.objectContaining({ method: "POST" }));
31
28
  const firstCall = (apiFetch as ReturnType<typeof vi.fn>).mock.calls[0][1] as { body: string };
32
29
  const firstBody = JSON.parse(firstCall.body) as Record<string, unknown>;
33
30
  expect(firstBody.pluginId).toBe("plugin-A");
@@ -0,0 +1,105 @@
1
+ import { act, render } from "@testing-library/react";
2
+ import { useEffect } from "react";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+
5
+ import { SidecarBridgeProvider, useSidecarBridge } from "@/hooks/use-sidecar-bridge";
6
+
7
+ function IframeRegistrar({ iframe }: { iframe: HTMLIFrameElement }) {
8
+ const { setIframeRef } = useSidecarBridge();
9
+ useEffect(() => {
10
+ setIframeRef(iframe);
11
+ return () => setIframeRef(null);
12
+ }, [iframe, setIframeRef]);
13
+ return null;
14
+ }
15
+
16
+ function makeIframeWithSpy() {
17
+ const postMessage = vi.fn();
18
+ const iframe = {
19
+ contentWindow: { postMessage } as unknown as Window,
20
+ } as unknown as HTMLIFrameElement;
21
+ return { iframe, postMessage };
22
+ }
23
+
24
+ function fireReady() {
25
+ act(() => {
26
+ window.dispatchEvent(
27
+ new MessageEvent("message", {
28
+ data: { type: "ready" },
29
+ origin: window.location.origin,
30
+ }),
31
+ );
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Initial deep-link forwarding was moved out of `ready` — it now travels
37
+ * through `SidecarFrame`'s iframe src as `?initial-path=…`, which the
38
+ * sidecar's CompanyRootRedirect reads on first render. The ready-time
39
+ * postMessage approach was removed because it raced with the sidecar's
40
+ * own root redirect.
41
+ */
42
+ describe("SidecarBridgeProvider", () => {
43
+ const originalUrl = window.location.pathname + window.location.search + window.location.hash;
44
+
45
+ beforeEach(() => {
46
+ window.history.replaceState(null, "", "/dashboard");
47
+ });
48
+
49
+ afterEach(() => {
50
+ window.history.replaceState(null, "", originalUrl);
51
+ });
52
+
53
+ it("does not forward on ready — deep links travel via iframe src", () => {
54
+ window.history.replaceState(null, "", "/issues/IRA-10");
55
+ const { iframe, postMessage } = makeIframeWithSpy();
56
+
57
+ render(
58
+ <SidecarBridgeProvider>
59
+ <IframeRegistrar iframe={iframe} />
60
+ </SidecarBridgeProvider>,
61
+ );
62
+
63
+ fireReady();
64
+
65
+ expect(postMessage).not.toHaveBeenCalled();
66
+ });
67
+
68
+ it("ignores duplicate ready messages without erroring", () => {
69
+ window.history.replaceState(null, "", "/dashboard");
70
+ const { iframe, postMessage } = makeIframeWithSpy();
71
+
72
+ render(
73
+ <SidecarBridgeProvider>
74
+ <IframeRegistrar iframe={iframe} />
75
+ </SidecarBridgeProvider>,
76
+ );
77
+
78
+ fireReady();
79
+ fireReady();
80
+
81
+ expect(postMessage).not.toHaveBeenCalled();
82
+ });
83
+
84
+ it("still updates shell URL on routeChanged", () => {
85
+ window.history.replaceState(null, "", "/");
86
+ const { iframe } = makeIframeWithSpy();
87
+
88
+ render(
89
+ <SidecarBridgeProvider>
90
+ <IframeRegistrar iframe={iframe} />
91
+ </SidecarBridgeProvider>,
92
+ );
93
+
94
+ act(() => {
95
+ window.dispatchEvent(
96
+ new MessageEvent("message", {
97
+ data: { type: "routeChanged", path: "/LED/issues/LED-1" },
98
+ origin: window.location.origin,
99
+ }),
100
+ );
101
+ });
102
+
103
+ expect(window.location.pathname).toBe("/issues/LED-1");
104
+ });
105
+ });
@@ -30,9 +30,7 @@ describe("useWebMCP", () => {
30
30
  beforeEach(() => {
31
31
  vi.resetAllMocks();
32
32
  mockRegisterWebMCPTools.mockReturnValue(true);
33
- vi.mocked(useSession).mockReturnValue({ data: { user: mockSession.user } } as ReturnType<
34
- typeof useSession
35
- >);
33
+ vi.mocked(useSession).mockReturnValue({ data: { user: mockSession.user } } as ReturnType<typeof useSession>);
36
34
  });
37
35
 
38
36
  it("registers tools when user is authenticated", () => {