@wopr-network/platform-ui-core 1.27.8 → 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 +4 -14
  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
@@ -16,12 +16,7 @@ vi.mock("@/lib/api", () => ({
16
16
  }));
17
17
 
18
18
  import type { AutoAcceptConfig, DiscoveredBot, Friend, FriendRequest } from "@/lib/api";
19
- import {
20
- getAutoAcceptConfig,
21
- listDiscoveredBots,
22
- listFriendRequests,
23
- listFriends,
24
- } from "@/lib/api";
19
+ import { getAutoAcceptConfig, listDiscoveredBots, listFriendRequests, listFriends } from "@/lib/api";
25
20
  import { FriendsTab } from "./friends-tab";
26
21
 
27
22
  const mockListFriends = listFriends as ReturnType<typeof vi.fn>;
@@ -88,9 +83,7 @@ describe("FriendsTab", () => {
88
83
 
89
84
  render(<FriendsTab instanceId={INSTANCE_ID} />);
90
85
  await waitFor(() => {
91
- expect(
92
- screen.getByText("No friends yet. Discover bots on the network below."),
93
- ).toBeInTheDocument();
86
+ expect(screen.getByText("No friends yet. Discover bots on the network below.")).toBeInTheDocument();
94
87
  });
95
88
  });
96
89
 
@@ -11,14 +11,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover
11
11
  import { Separator } from "@/components/ui/separator";
12
12
  import { Skeleton } from "@/components/ui/skeleton";
13
13
  import { Switch } from "@/components/ui/switch";
14
- import {
15
- Table,
16
- TableBody,
17
- TableCell,
18
- TableHead,
19
- TableHeader,
20
- TableRow,
21
- } from "@/components/ui/table";
14
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
22
15
  import type { AutoAcceptConfig, DiscoveredBot, Friend, FriendRequest } from "@/lib/api";
23
16
  import {
24
17
  acceptFriendRequest,
@@ -143,16 +136,12 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
143
136
  setActionError(null);
144
137
  const updated = current.includes(cap) ? current.filter((c) => c !== cap) : [...current, cap];
145
138
  // Optimistic update
146
- setFriends((prev) =>
147
- prev.map((f) => (f.id === friendId ? { ...f, sharedCapabilities: updated } : f)),
148
- );
139
+ setFriends((prev) => prev.map((f) => (f.id === friendId ? { ...f, sharedCapabilities: updated } : f)));
149
140
  try {
150
141
  await updateFriendCapabilities(instanceId, friendId, updated);
151
142
  } catch (err) {
152
143
  // Rollback
153
- setFriends((prev) =>
154
- prev.map((f) => (f.id === friendId ? { ...f, sharedCapabilities: current } : f)),
155
- );
144
+ setFriends((prev) => prev.map((f) => (f.id === friendId ? { ...f, sharedCapabilities: current } : f)));
156
145
  setActionError(toUserMessage(err, "Failed to update capabilities"));
157
146
  }
158
147
  }
@@ -196,12 +185,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
196
185
  return (
197
186
  <div className="space-y-6">
198
187
  {Array.from({ length: 4 }, (_, i) => `friends-sk-${i}`).map((skId, i) => (
199
- <motion.div
200
- key={skId}
201
- initial={{ opacity: 0 }}
202
- animate={{ opacity: 1 }}
203
- transition={{ delay: i * 0.05 }}
204
- >
188
+ <motion.div key={skId} initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: i * 0.05 }}>
205
189
  <Skeleton className="h-24 w-full rounded-sm" />
206
190
  </motion.div>
207
191
  ))}
@@ -211,9 +195,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
211
195
 
212
196
  if (error) {
213
197
  return (
214
- <div className="rounded-md border border-red-500/25 bg-red-500/10 px-4 py-3 text-sm text-red-500">
215
- {error}
216
- </div>
198
+ <div className="rounded-md border border-red-500/25 bg-red-500/10 px-4 py-3 text-sm text-red-500">{error}</div>
217
199
  );
218
200
  }
219
201
 
@@ -269,9 +251,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
269
251
  transition={{ duration: 0.15 }}
270
252
  className="transition-colors hover:bg-muted/50 even:bg-muted/20 border-b last:border-b-0"
271
253
  >
272
- <TableCell className="font-medium text-sm text-foreground">
273
- {friend.name}
274
- </TableCell>
254
+ <TableCell className="font-medium text-sm text-foreground">{friend.name}</TableCell>
275
255
  <TableCell>
276
256
  <FriendStatusBadge status={friend.status} />
277
257
  </TableCell>
@@ -285,13 +265,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
285
265
  key={cap}
286
266
  variant="outline"
287
267
  className="rounded-sm border-terminal/20 bg-terminal/5 text-terminal-dim text-xs px-1.5 py-0.5 cursor-pointer hover:bg-terminal/10 transition-colors duration-150"
288
- onClick={() =>
289
- handleToggleCapability(
290
- friend.id,
291
- friend.sharedCapabilities,
292
- cap,
293
- )
294
- }
268
+ onClick={() => handleToggleCapability(friend.id, friend.sharedCapabilities, cap)}
295
269
  >
296
270
  {cap} <X className="ml-0.5 size-3 inline" />
297
271
  </Badge>
@@ -299,9 +273,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
299
273
  )}
300
274
  <CapabilityAddPopover
301
275
  existing={friend.sharedCapabilities}
302
- onAdd={(cap) =>
303
- handleToggleCapability(friend.id, friend.sharedCapabilities, cap)
304
- }
276
+ onAdd={(cap) => handleToggleCapability(friend.id, friend.sharedCapabilities, cap)}
305
277
  />
306
278
  </div>
307
279
  </TableCell>
@@ -367,9 +339,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
367
339
  transition={{ duration: 0.15 }}
368
340
  className="transition-colors hover:bg-muted/50 border-l-2 border-l-terminal border-b last:border-b-0"
369
341
  >
370
- <TableCell className="font-medium text-sm text-foreground">
371
- {req.fromName}
372
- </TableCell>
342
+ <TableCell className="font-medium text-sm text-foreground">{req.fromName}</TableCell>
373
343
  <TableCell className="hidden md:table-cell text-xs text-muted-foreground">
374
344
  {formatRelativeTime(req.createdAt)}
375
345
  </TableCell>
@@ -429,9 +399,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
429
399
  transition={{ duration: 0.15 }}
430
400
  className="transition-colors hover:bg-muted/50 opacity-80 border-b last:border-b-0"
431
401
  >
432
- <TableCell className="font-medium text-sm text-foreground">
433
- {req.toName}
434
- </TableCell>
402
+ <TableCell className="font-medium text-sm text-foreground">{req.toName}</TableCell>
435
403
  <TableCell className="hidden md:table-cell text-xs text-muted-foreground">
436
404
  {formatRelativeTime(req.createdAt)}
437
405
  </TableCell>
@@ -474,15 +442,13 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
474
442
  <div className="flex flex-col items-center justify-center py-8 gap-3">
475
443
  <Radio className="size-12 text-muted-foreground/50" />
476
444
  <p className="text-sm text-muted-foreground italic">
477
- No bots discovered on the network. Your bot may need to be online to discover
478
- peers.
445
+ No bots discovered on the network. Your bot may need to be online to discover peers.
479
446
  </p>
480
447
  </div>
481
448
  ) : (
482
449
  <div className="rounded-sm border">
483
450
  <div className="px-3 py-1.5 border-b text-xs text-muted-foreground">
484
- Showing {discovered.length} bot{discovered.length !== 1 ? "s" : ""} on your local
485
- network
451
+ Showing {discovered.length} bot{discovered.length !== 1 ? "s" : ""} on your local network
486
452
  </div>
487
453
  <Table>
488
454
  <TableHeader>
@@ -494,13 +460,8 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
494
460
  </TableHeader>
495
461
  <TableBody>
496
462
  {discovered.map((bot) => (
497
- <TableRow
498
- key={bot.id}
499
- className="transition-colors hover:bg-terminal/5 even:bg-muted/20"
500
- >
501
- <TableCell className="font-medium text-sm text-foreground">
502
- {bot.name}
503
- </TableCell>
463
+ <TableRow key={bot.id} className="transition-colors hover:bg-terminal/5 even:bg-muted/20">
464
+ <TableCell className="font-medium text-sm text-foreground">{bot.name}</TableCell>
504
465
  <TableCell className="hidden md:table-cell">
505
466
  <div className="flex flex-wrap gap-1">
506
467
  {bot.capabilities.map((cap) => (
@@ -516,12 +477,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
516
477
  </TableCell>
517
478
  <TableCell className="text-right">
518
479
  {sendingTo === bot.id ? (
519
- <Button
520
- size="sm"
521
- variant="ghost"
522
- className="text-muted-foreground"
523
- disabled
524
- >
480
+ <Button size="sm" variant="ghost" className="text-muted-foreground" disabled>
525
481
  <Loader2 className="size-3.5 animate-spin md:mr-1" />
526
482
  <span className="hidden md:inline">Pending...</span>
527
483
  </Button>
@@ -585,10 +541,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
585
541
  >
586
542
  <div className="bg-secondary rounded-sm p-4 mt-3 space-y-3">
587
543
  <div className="space-y-1">
588
- <label
589
- htmlFor="cap-rules"
590
- className="text-xs font-medium text-muted-foreground"
591
- >
544
+ <label htmlFor="cap-rules" className="text-xs font-medium text-muted-foreground">
592
545
  Required capabilities (comma-separated)
593
546
  </label>
594
547
  <Input
@@ -601,10 +554,7 @@ export function FriendsTab({ instanceId }: { instanceId: string }) {
601
554
  />
602
555
  </div>
603
556
  <div className="space-y-1">
604
- <label
605
- htmlFor="max-friends"
606
- className="text-xs font-medium text-muted-foreground"
607
- >
557
+ <label htmlFor="max-friends" className="text-xs font-medium text-muted-foreground">
608
558
  Max friends
609
559
  </label>
610
560
  <Input
@@ -658,13 +608,7 @@ function FriendStatusBadge({ status }: { status: "online" | "offline" | "unknown
658
608
  );
659
609
  }
660
610
 
661
- function CapabilityAddPopover({
662
- existing,
663
- onAdd,
664
- }: {
665
- existing: string[];
666
- onAdd: (cap: string) => void;
667
- }) {
611
+ function CapabilityAddPopover({ existing, onAdd }: { existing: string[]; onAdd: (cap: string) => void }) {
668
612
  const [value, setValue] = useState("");
669
613
 
670
614
  function handleAdd() {
@@ -36,12 +36,7 @@ interface UpdateAvailableBadgeProps {
36
36
  onUpdated?: () => void;
37
37
  }
38
38
 
39
- export function UpdateAvailableBadge({
40
- instanceId,
41
- instanceName,
42
- changelog,
43
- onUpdated,
44
- }: UpdateAvailableBadgeProps) {
39
+ export function UpdateAvailableBadge({ instanceId, instanceName, changelog, onUpdated }: UpdateAvailableBadgeProps) {
45
40
  const [pulling, setPulling] = useState(false);
46
41
 
47
42
  async function handleUpdate() {
@@ -96,11 +91,7 @@ export function UpdateAvailableBadge({
96
91
 
97
92
  <AlertDialogFooter>
98
93
  <AlertDialogCancel>Later</AlertDialogCancel>
99
- <AlertDialogAction
100
- onClick={handleUpdate}
101
- disabled={pulling}
102
- className="bg-amber-600 hover:bg-amber-700"
103
- >
94
+ <AlertDialogAction onClick={handleUpdate} disabled={pulling} className="bg-amber-600 hover:bg-amber-700">
104
95
  {pulling ? (
105
96
  <>
106
97
  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
@@ -18,10 +18,7 @@ export function Hero() {
18
18
  />
19
19
 
20
20
  {/* Radial glow pulse */}
21
- <div
22
- className="pointer-events-none absolute inset-0 flex items-center justify-center"
23
- aria-hidden="true"
24
- >
21
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center" aria-hidden="true">
25
22
  <div className="animate-gentle-pulse h-[600px] w-[600px] rounded-full bg-terminal/5 blur-[120px]" />
26
23
  </div>
27
24
 
@@ -34,8 +31,7 @@ export function Hero() {
34
31
  </h1>
35
32
 
36
33
  <p className="mt-8 max-w-2xl text-lg text-muted-foreground md:text-xl">
37
- A $5/month supercomputer that runs your business. No really. We know because we run ours
38
- on one.
34
+ A $5/month supercomputer that runs your business. No really. We know because we run ours on one.
39
35
  </p>
40
36
 
41
37
  <div className="mt-12 flex flex-col items-center gap-4 sm:flex-row">
@@ -44,9 +40,7 @@ export function Hero() {
44
40
  </Button>
45
41
  </div>
46
42
 
47
- <span className="mt-4 text-sm text-muted-foreground">
48
- Starting at $5/month. Less than Netflix.
49
- </span>
43
+ <span className="mt-4 text-sm text-muted-foreground">Starting at $5/month. Less than Netflix.</span>
50
44
  </div>
51
45
  </section>
52
46
  );
@@ -15,9 +15,7 @@ function CtaBlock({ className }: { className?: string }) {
15
15
  <Button variant="terminal" size="lg" asChild>
16
16
  <Link href="/signup">Start for free</Link>
17
17
  </Button>
18
- <span className="mt-4 font-mono text-xs text-terminal/40">
19
- Your {productName()} is waiting.
20
- </span>
18
+ <span className="mt-4 font-mono text-xs text-terminal/40">Your {productName()} is waiting.</span>
21
19
  </div>
22
20
  );
23
21
  }
@@ -136,8 +136,7 @@ export function PortfolioChart({ onMilestoneRef, onFadeStartRef }: PortfolioChar
136
136
  // Wire milestone ref
137
137
  useEffect(() => {
138
138
  if (onMilestoneRef && "current" in onMilestoneRef) {
139
- (onMilestoneRef as React.MutableRefObject<((label: string) => void) | null>).current =
140
- handleMilestone;
139
+ (onMilestoneRef as React.MutableRefObject<((label: string) => void) | null>).current = handleMilestone;
141
140
  }
142
141
  return () => {
143
142
  if (onMilestoneRef && "current" in onMilestoneRef) {
@@ -222,15 +221,12 @@ export function PortfolioChart({ onMilestoneRef, onFadeStartRef }: PortfolioChar
222
221
  // Smooth the viewport anchor — EMA tracks trend, not raw noise
223
222
  // Faster at start (less history), slower as chart matures
224
223
  const emaAlpha = Math.max(0.02, 0.15 - s.milestoneCount * 0.002);
225
- s.smoothedValue =
226
- s.count < 2 ? s.value : s.smoothedValue * (1 - emaAlpha) + s.value * emaAlpha;
224
+ s.smoothedValue = s.count < 2 ? s.value : s.smoothedValue * (1 - emaAlpha) + s.value * emaAlpha;
227
225
 
228
226
  // Viewport — zooms in gently early, then zooms WAY out as milestones accumulate
229
227
  const yRange = 30 + s.milestoneCount * 8;
230
228
  const xSpan =
231
- s.milestoneCount < 30
232
- ? Math.max(300, 500 - s.milestoneCount * 4)
233
- : 380 + (s.milestoneCount - 30) * 150;
229
+ s.milestoneCount < 30 ? Math.max(300, 500 - s.milestoneCount * 4) : 380 + (s.milestoneCount - 30) * 150;
234
230
  const xRight = s.t;
235
231
  const xLeft = s.t - xSpan;
236
232
 
@@ -274,8 +270,7 @@ export function PortfolioChart({ onMilestoneRef, onFadeStartRef }: PortfolioChar
274
270
 
275
271
  // End-of-sequence fade: triggered when terminal enters final-typing.
276
272
  const FADE_DURATION = 2000; // ms
277
- const lineAlpha =
278
- s.fadeStartTime < 0 ? 1 : Math.max(0, 1 - (now - s.fadeStartTime) / FADE_DURATION);
273
+ const lineAlpha = s.fadeStartTime < 0 ? 1 : Math.max(0, 1 - (now - s.fadeStartTime) / FADE_DURATION);
279
274
 
280
275
  if (lineAlpha > 0.01) {
281
276
  // Layer 1: Bloom
@@ -40,9 +40,7 @@ export function StorySections() {
40
40
  }}
41
41
  >
42
42
  <h2 className="font-mono text-lg font-bold text-terminal sm:text-xl">{story.heading}</h2>
43
- <p className="mt-4 font-mono text-sm leading-relaxed text-terminal/60 sm:text-base">
44
- {story.body}
45
- </p>
43
+ <p className="mt-4 font-mono text-sm leading-relaxed text-terminal/60 sm:text-base">{story.body}</p>
46
44
  </motion.div>
47
45
  ))}
48
46
  </section>
@@ -58,15 +58,7 @@ function getTextBlur(lineIndex: number): number {
58
58
  return Math.min(8, Math.max(0, (lineIndex - 18) * 0.22));
59
59
  }
60
60
 
61
- type AnimState =
62
- | "idle"
63
- | "typing"
64
- | "pause"
65
- | "backspacing"
66
- | "final-typing"
67
- | "cursor-death"
68
- | "blinking"
69
- | "done";
61
+ type AnimState = "idle" | "typing" | "pause" | "backspacing" | "final-typing" | "cursor-death" | "blinking" | "done";
70
62
 
71
63
  export function TerminalSequence({ onComplete, onMilestone, onFadeStart }: TerminalSequenceProps) {
72
64
  const [lines, setLines] = useState<string[]>([]);
@@ -345,10 +337,7 @@ export function TerminalSequence({ onComplete, onMilestone, onFadeStart }: Termi
345
337
  />
346
338
 
347
339
  {/* Radial glow pulse */}
348
- <div
349
- className="pointer-events-none absolute inset-0 flex items-center justify-center"
350
- aria-hidden="true"
351
- >
340
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center" aria-hidden="true">
352
341
  <div className="animate-gentle-pulse h-[600px] w-[600px] rounded-full bg-terminal/5 blur-[120px]" />
353
342
  </div>
354
343
 
@@ -379,10 +368,8 @@ export function TerminalSequence({ onComplete, onMilestone, onFadeStart }: Termi
379
368
  old lines overflow upward and are clipped + faded by the mask */}
380
369
  <div className="absolute bottom-0 flex w-full flex-col">
381
370
  {lines.map((line, i) => (
382
- <div
383
- key={`${i}-${line}`}
384
- className={animationDone ? "text-terminal" : "text-terminal/30"}
385
- >
371
+ // biome-ignore lint/suspicious/noArrayIndexKey: static list, index key is safe
372
+ <div key={`${i}-${line}`} className={animationDone ? "text-terminal" : "text-terminal/30"}>
386
373
  {line || "\u00A0"}
387
374
  </div>
388
375
  ))}
@@ -31,16 +31,12 @@ export function MarketplaceEmptyState({ hasSearch, searchTerm }: EmptyStateProps
31
31
  {hasSearch ? (
32
32
  <>
33
33
  <p className="text-lg font-medium">No results for &ldquo;{searchTerm}&rdquo;</p>
34
- <p className="mt-1 text-sm text-muted-foreground">
35
- Try a different search term or browse by category.
36
- </p>
34
+ <p className="mt-1 text-sm text-muted-foreground">Try a different search term or browse by category.</p>
37
35
  </>
38
36
  ) : (
39
37
  <>
40
38
  <p className="text-lg font-medium">Your {productName()} could do more...</p>
41
- <p className="mt-1 text-sm text-muted-foreground">
42
- Add plugins to give your bot superpowers.
43
- </p>
39
+ <p className="mt-1 text-sm text-muted-foreground">Add plugins to give your bot superpowers.</p>
44
40
  <div className="mt-6 flex flex-wrap justify-center gap-3">
45
41
  {suggestedPlugins.map((p) => (
46
42
  <Link
@@ -85,9 +85,7 @@ export function FirstVisitHero({ superpowers, onDismiss }: FirstVisitHeroProps)
85
85
  {sp.name[0]}
86
86
  </div>
87
87
  <h2 className="text-lg font-bold">{sp.superpowerHeadline ?? sp.name}</h2>
88
- <p className="mt-1 text-sm text-muted-foreground">
89
- {sp.superpowerTagline ?? sp.description}
90
- </p>
88
+ <p className="mt-1 text-sm text-muted-foreground">{sp.superpowerTagline ?? sp.description}</p>
91
89
  </div>
92
90
  </motion.button>
93
91
  ))}
@@ -6,24 +6,11 @@ import { z } from "zod";
6
6
  import { CapabilityProviderPicker } from "@/components/capability/CapabilityResolver";
7
7
  import { Badge } from "@/components/ui/badge";
8
8
  import { Button } from "@/components/ui/button";
9
- import {
10
- Card,
11
- CardContent,
12
- CardDescription,
13
- CardFooter,
14
- CardHeader,
15
- CardTitle,
16
- } from "@/components/ui/card";
9
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
17
10
  import { Input } from "@/components/ui/input";
18
11
  import { Label } from "@/components/ui/label";
19
12
  import { Progress } from "@/components/ui/progress";
20
- import {
21
- Select,
22
- SelectContent,
23
- SelectItem,
24
- SelectTrigger,
25
- SelectValue,
26
- } from "@/components/ui/select";
13
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
27
14
  import { Skeleton } from "@/components/ui/skeleton";
28
15
  import { Switch } from "@/components/ui/switch";
29
16
  import { useCapabilityMeta } from "@/hooks/use-capability-meta";
@@ -143,12 +130,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
143
130
 
144
131
  // Auto-skip conflicts phase if no conflicts and not loading
145
132
  useEffect(() => {
146
- if (
147
- currentPhase === "conflicts" &&
148
- conflicts.length === 0 &&
149
- !conflictsLoading &&
150
- !conflictsError
151
- ) {
133
+ if (currentPhase === "conflicts" && conflicts.length === 0 && !conflictsLoading && !conflictsError) {
152
134
  setCurrentPhaseIndex((i) => i + 1);
153
135
  }
154
136
  }, [currentPhase, conflicts, conflictsLoading, conflictsError]);
@@ -159,8 +141,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
159
141
  const stepsBeforeSetup = phases.filter(
160
142
  (p) => p !== "setup" && p !== "complete" && phases.indexOf(p) < currentPhaseIndex,
161
143
  ).length;
162
- const totalSteps =
163
- phases.filter((p) => p !== "setup" && p !== "complete").length + setupSteps.length + 1;
144
+ const totalSteps = phases.filter((p) => p !== "setup" && p !== "complete").length + setupSteps.length + 1;
164
145
  const currentStepNumber =
165
146
  currentPhase === "setup"
166
147
  ? stepsBeforeSetup + setupStepIndex + 1
@@ -218,9 +199,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
218
199
  } else {
219
200
  // Object-level errors (refinements, superRefine, union discriminants) have empty path.
220
201
  // Collect under _form so they render in a general error area.
221
- stepErrors._form = stepErrors._form
222
- ? `${stepErrors._form}. ${issue.message}`
223
- : issue.message;
202
+ stepErrors._form = stepErrors._form ? `${stepErrors._form}. ${issue.message}` : issue.message;
224
203
  }
225
204
  }
226
205
  setErrors(stepErrors);
@@ -347,9 +326,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
347
326
  error={conflictsError}
348
327
  plugin={plugin}
349
328
  overrides={primaryOverrides}
350
- onChoose={(capability, pluginId) =>
351
- setPrimaryOverrides((prev) => ({ ...prev, [capability]: pluginId }))
352
- }
329
+ onChoose={(capability, pluginId) => setPrimaryOverrides((prev) => ({ ...prev, [capability]: pluginId }))}
353
330
  />
354
331
  )}
355
332
  {currentPhase === "providers" && (
@@ -360,12 +337,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
360
337
  />
361
338
  )}
362
339
  {currentPhase === "setup" && currentSetupStep && (
363
- <SetupStepForm
364
- step={currentSetupStep}
365
- values={values}
366
- errors={errors}
367
- onChange={handleChange}
368
- />
340
+ <SetupStepForm step={currentSetupStep} values={values} errors={errors} onChange={handleChange} />
369
341
  )}
370
342
  {currentPhase === "complete" && (
371
343
  <div className="py-4 text-center">
@@ -373,9 +345,7 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
373
345
  <span className="text-2xl text-emerald-500">&#10003;</span>
374
346
  </div>
375
347
  <p className="font-medium">Plugin installed successfully</p>
376
- <p className="mt-1 text-sm text-muted-foreground">
377
- {plugin.name} is now active on your instance.
378
- </p>
348
+ <p className="mt-1 text-sm text-muted-foreground">{plugin.name} is now active on your instance.</p>
379
349
  </div>
380
350
  )}
381
351
  </CardContent>
@@ -383,28 +353,16 @@ export function InstallWizard({ plugin, onComplete, onCancel }: InstallWizardPro
383
353
  <CardFooter className="flex justify-between">
384
354
  <div>
385
355
  {isFirstStep ? (
386
- <Button
387
- data-onboarding-id="marketplace.wizard.cancel"
388
- variant="ghost"
389
- onClick={onCancel}
390
- >
356
+ <Button data-onboarding-id="marketplace.wizard.cancel" variant="ghost" onClick={onCancel}>
391
357
  Cancel
392
358
  </Button>
393
359
  ) : (
394
- <Button
395
- data-onboarding-id="marketplace.wizard.back"
396
- variant="ghost"
397
- onClick={handleBack}
398
- >
360
+ <Button data-onboarding-id="marketplace.wizard.back" variant="ghost" onClick={handleBack}>
399
361
  Back
400
362
  </Button>
401
363
  )}
402
364
  </div>
403
- <Button
404
- data-onboarding-id="marketplace.wizard.continue"
405
- onClick={handleNext}
406
- disabled={isContinueDisabled}
407
- >
365
+ <Button data-onboarding-id="marketplace.wizard.continue" onClick={handleNext} disabled={isContinueDisabled}>
408
366
  {currentPhase === "complete" ? "Done" : "Continue"}
409
367
  </Button>
410
368
  </CardFooter>
@@ -471,9 +429,7 @@ function BotSelector({
471
429
  onClick={() => onSelect(bot.id)}
472
430
  className={cn(
473
431
  "w-full rounded-lg border p-3 text-left h-auto transition-colors hover:bg-transparent",
474
- selectedBotId === bot.id
475
- ? "border-primary bg-primary/5"
476
- : "border-border hover:border-primary/50",
432
+ selectedBotId === bot.id ? "border-primary bg-primary/5" : "border-border hover:border-primary/50",
477
433
  )}
478
434
  >
479
435
  <div className="flex items-center justify-between">
@@ -535,9 +491,7 @@ function RequirementsCheck({ plugin, botId }: { plugin: PluginManifest; botId: s
535
491
 
536
492
  return (
537
493
  <div className="space-y-3">
538
- <p className="text-sm text-muted-foreground">
539
- This plugin requires the following dependencies:
540
- </p>
494
+ <p className="text-sm text-muted-foreground">This plugin requires the following dependencies:</p>
541
495
  {isLoading ? (
542
496
  <div className="space-y-2">
543
497
  <p className="text-xs text-muted-foreground">Checking installed plugins...</p>
@@ -558,18 +512,14 @@ function RequirementsCheck({ plugin, botId }: { plugin: PluginManifest; botId: s
558
512
  <Badge variant="outline" className="text-[10px]">
559
513
  {req.id}
560
514
  </Badge>
561
- {req.status === "missing" && (
562
- <span className="text-xs text-destructive">Not installed</span>
563
- )}
515
+ {req.status === "missing" && <span className="text-xs text-destructive">Not installed</span>}
564
516
  </li>
565
517
  ))}
566
518
  </ul>
567
519
  )}
568
520
  {!isLoading && results.some((r) => r.status === "missing") && (
569
521
  <div className="mt-3 rounded-sm border border-destructive/25 bg-destructive/5 p-3">
570
- <p className="text-sm text-destructive">
571
- Install the missing dependencies before continuing.
572
- </p>
522
+ <p className="text-sm text-destructive">Install the missing dependencies before continuing.</p>
573
523
  </div>
574
524
  )}
575
525
  {plugin.install.length > 0 && (
@@ -608,9 +558,7 @@ function SetupStepForm({
608
558
  Open external link
609
559
  </a>
610
560
  )}
611
- {!step.instruction && !step.externalUrl && (
612
- <p className="text-sm text-muted-foreground">{step.description}</p>
613
- )}
561
+ {!step.instruction && !step.externalUrl && <p className="text-sm text-muted-foreground">{step.description}</p>}
614
562
  </div>
615
563
  );
616
564
  }
@@ -679,8 +627,8 @@ function CapabilityConflicts({
679
627
  <div className="rounded-sm border border-amber-500/25 bg-amber-500/5 p-3">
680
628
  <p className="text-sm font-medium text-amber-500">Capability Conflict Detected</p>
681
629
  <p className="mt-1 text-xs text-muted-foreground">
682
- {plugin.name} provides capabilities already provided by installed plugins. Choose which
683
- plugin should be the primary provider for each.
630
+ {plugin.name} provides capabilities already provided by installed plugins. Choose which plugin should be the
631
+ primary provider for each.
684
632
  </p>
685
633
  </div>
686
634
  {conflicts.map((conflict) => {
@@ -689,10 +637,7 @@ function CapabilityConflicts({
689
637
  return (
690
638
  <div key={conflict.capability} className="rounded-sm border p-4">
691
639
  <div className="mb-3 flex items-center gap-2">
692
- <Badge
693
- variant="outline"
694
- className={cn("text-[10px]", capColor.bg, capColor.text, capColor.border)}
695
- >
640
+ <Badge variant="outline" className={cn("text-[10px]", capColor.bg, capColor.text, capColor.border)}>
696
641
  {conflict.capability}
697
642
  </Badge>
698
643
  <span className="text-sm text-muted-foreground">provided by both plugins</span>
@@ -740,9 +685,7 @@ function ConfigFieldInput({
740
685
  <div className="flex items-center justify-between">
741
686
  <div>
742
687
  <Label>{field.label}</Label>
743
- {field.description && (
744
- <p className="text-xs text-muted-foreground">{field.description}</p>
745
- )}
688
+ {field.description && <p className="text-xs text-muted-foreground">{field.description}</p>}
746
689
  </div>
747
690
  <Switch
748
691
  checked={value === true || value === "true"}
@@ -38,10 +38,7 @@ export function MarketplaceTabs({ selected, onSelect, counts }: MarketplaceTabsP
38
38
  )}
39
39
  <Badge
40
40
  variant={isSelected ? "default" : "outline"}
41
- className={cn(
42
- "relative cursor-pointer text-xs font-medium transition-colors",
43
- isSelected && "shadow-sm",
44
- )}
41
+ className={cn("relative cursor-pointer text-xs font-medium transition-colors", isSelected && "shadow-sm")}
45
42
  >
46
43
  {tab.label}
47
44
  {count > 0 && <span className="ml-1 opacity-60">{count}</span>}