@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
package/src/lib/api.ts CHANGED
@@ -234,11 +234,7 @@ export function parseChannelsFromEnv(env: Record<string, string> | undefined): s
234
234
  export function parsePluginsFromEnv(env: Record<string, string> | undefined): PluginInfo[] {
235
235
  if (!env) return [];
236
236
  const ids = new Set<string>();
237
- for (const key of [
238
- envKey("PLUGINS_OTHER"),
239
- envKey("PLUGINS_VOICE"),
240
- envKey("PLUGINS_PROVIDERS"),
241
- ]) {
237
+ for (const key of [envKey("PLUGINS_OTHER"), envKey("PLUGINS_VOICE"), envKey("PLUGINS_PROVIDERS")]) {
242
238
  const raw = env[key];
243
239
  if (raw) {
244
240
  for (const id of raw
@@ -345,10 +341,14 @@ export async function createInstance(data: {
345
341
  provider: string;
346
342
  channels: string[];
347
343
  plugins: string[];
344
+ /** Product-specific data passed through to provisioning. */
345
+ extra?: Record<string, unknown>;
348
346
  }): Promise<Instance> {
347
+ const { extra, ...rest } = data;
349
348
  const result = await trpcVanilla.fleet.createInstance.mutate({
350
- ...data,
349
+ ...rest,
351
350
  image: data.image ?? "ghcr.io/wopr-network/wopr:latest",
351
+ extra,
352
352
  });
353
353
  const profile = result as Record<string, unknown>;
354
354
  return {
@@ -453,11 +453,29 @@ export async function listChannels(botId: string): Promise<ChannelInfo[]> {
453
453
 
454
454
  export async function controlInstance(
455
455
  id: string,
456
- action: "start" | "stop" | "restart" | "destroy",
456
+ action: "start" | "stop" | "restart" | "destroy" | "roll",
457
457
  ): Promise<void> {
458
458
  await trpcVanilla.fleet.controlInstance.mutate({ id, action });
459
459
  }
460
460
 
461
+ /**
462
+ * Result of checking whether an instance is running the latest image.
463
+ * `latestImageId` is null if the tag isn't resolvable locally; in that
464
+ * case we treat the instance as up to date (no newer version known).
465
+ */
466
+ export interface InstanceVersionCheck {
467
+ upToDate: boolean;
468
+ currentImageId: string;
469
+ latestImageId: string | null;
470
+ tag: string;
471
+ }
472
+
473
+ /** Whether a newer image has been pulled since this instance started. */
474
+ export async function instanceVersionCheck(id: string): Promise<InstanceVersionCheck | null> {
475
+ const result = (await trpcVanilla.fleet.instanceVersionCheck.query({ id })) as InstanceVersionCheck | null;
476
+ return result;
477
+ }
478
+
461
479
  /** PATCH /fleet/bots/:id — Update bot env config. */
462
480
  export async function updateInstanceConfig(id: string, env: Record<string, string>): Promise<void> {
463
481
  await fleetFetch(`/bots/${id}`, {
@@ -490,10 +508,7 @@ export async function getInstanceSecretKeys(id: string): Promise<string[]> {
490
508
  }
491
509
 
492
510
  /** PUT /fleet/bots/:id/secrets — Write secret values. */
493
- export async function updateInstanceSecrets(
494
- id: string,
495
- secrets: Record<string, string>,
496
- ): Promise<void> {
511
+ export async function updateInstanceSecrets(id: string, secrets: Record<string, string>): Promise<void> {
497
512
  await fleetFetch(`/bots/${id}/secrets`, {
498
513
  method: "PUT",
499
514
  body: JSON.stringify({ secrets }),
@@ -501,11 +516,7 @@ export async function updateInstanceSecrets(
501
516
  }
502
517
 
503
518
  /** Toggle a plugin's enabled/disabled state on a bot instance. */
504
- export async function toggleInstancePlugin(
505
- botId: string,
506
- pluginId: string,
507
- enabled: boolean,
508
- ): Promise<void> {
519
+ export async function toggleInstancePlugin(botId: string, pluginId: string, enabled: boolean): Promise<void> {
509
520
  await fleetFetch(`/bots/${botId}/plugins/${pluginId}`, {
510
521
  method: "PATCH",
511
522
  body: JSON.stringify({ enabled }),
@@ -818,14 +829,10 @@ export interface Organization {
818
829
  // --- Settings API ---
819
830
 
820
831
  export async function getProfile(): Promise<UserProfile> {
821
- // NOTE: add tRPC procedure
822
832
  return apiFetch<UserProfile>("/settings/profile");
823
833
  }
824
834
 
825
- export async function updateProfile(
826
- data: Partial<Pick<UserProfile, "name" | "email">>,
827
- ): Promise<UserProfile> {
828
- // NOTE: add tRPC procedure
835
+ export async function updateProfile(data: Partial<Pick<UserProfile, "name" | "email">>): Promise<UserProfile> {
829
836
  return apiFetch<UserProfile>("/settings/profile", {
830
837
  method: "PATCH",
831
838
  body: JSON.stringify(data),
@@ -833,38 +840,29 @@ export async function updateProfile(
833
840
  }
834
841
 
835
842
  export async function uploadAvatar(file: File): Promise<UserProfile> {
836
- const tenantId = getActiveTenantId();
837
- const form = new FormData();
838
- form.append("avatar", file);
839
- const res = await fetch(`${API_BASE_URL}/settings/profile/avatar`, {
840
- method: "POST",
841
- credentials: "include",
842
- headers: {
843
- ...(tenantId ? { "x-tenant-id": tenantId } : {}),
844
- },
845
- body: form,
843
+ const dataUrl = await new Promise<string>((resolve, reject) => {
844
+ const reader = new FileReader();
845
+ reader.onload = () => resolve(reader.result as string);
846
+ reader.onerror = () => reject(new Error("Failed to read file"));
847
+ reader.readAsDataURL(file);
848
+ });
849
+ return apiFetch<UserProfile>("/settings/profile", {
850
+ method: "PATCH",
851
+ body: JSON.stringify({ image: dataUrl }),
846
852
  });
847
- if (res.status === 401) {
848
- handleUnauthorized();
849
- }
850
- if (!res.ok) {
851
- const body = await res.json().catch(() => ({}));
852
- throw new ApiError(res.status, res.statusText, (body as { error?: string }).error ?? undefined);
853
- }
854
- return res.json() as Promise<UserProfile>;
855
853
  }
856
854
 
857
- export async function changePassword(data: {
858
- currentPassword: string;
859
- newPassword: string;
860
- }): Promise<void> {
861
- // NOTE: add tRPC procedure
862
- await apiFetch("/settings/profile/password", { method: "POST", body: JSON.stringify(data) });
855
+ export async function changePassword(data: { currentPassword: string; newPassword: string }): Promise<void> {
856
+ await apiFetch<void>("/settings/change-password", {
857
+ method: "POST",
858
+ body: JSON.stringify(data),
859
+ });
863
860
  }
864
861
 
865
862
  export async function deleteAccount(): Promise<void> {
866
- // NOTE: add tRPC procedure
867
- await apiFetch("/settings/profile", { method: "DELETE" });
863
+ await apiFetch<void>("/settings/delete-account", {
864
+ method: "DELETE",
865
+ });
868
866
  }
869
867
 
870
868
  export async function listProviderKeys(): Promise<ProviderKey[]> {
@@ -972,9 +970,7 @@ export async function createSecret(data: {
972
970
 
973
971
  // NOTE: migrate to tRPC when secrets router is extended
974
972
  /** POST /settings/secrets/:id/rotate — Rotate a secret. */
975
- export async function rotateSecret(
976
- id: string,
977
- ): Promise<{ secret: SecretSummary; plaintextValue: string }> {
973
+ export async function rotateSecret(id: string): Promise<{ secret: SecretSummary; plaintextValue: string }> {
978
974
  return apiFetch<{ secret: SecretSummary; plaintextValue: string }>(
979
975
  `/settings/secrets/${encodeURIComponent(id)}/rotate`,
980
976
  { method: "POST" },
@@ -1225,6 +1221,7 @@ export type CreditTransactionType =
1225
1221
  | "purchase"
1226
1222
  | "signup_credit"
1227
1223
  | "bot_runtime"
1224
+ | "adapter_usage"
1228
1225
  | "refund"
1229
1226
  | "bonus"
1230
1227
  | "adjustment"
@@ -1234,6 +1231,7 @@ export interface CreditTransaction {
1234
1231
  id: string;
1235
1232
  type: CreditTransactionType;
1236
1233
  description: string;
1234
+ /** Amount in dollars. Positive = credit (green), negative = debit (red). */
1237
1235
  amount: number;
1238
1236
  createdAt: string;
1239
1237
  }
@@ -1285,39 +1283,75 @@ export async function getCreditBalance(): Promise<CreditBalance> {
1285
1283
  };
1286
1284
  }
1287
1285
 
1288
- function mapTransactionType(backendType: string): CreditTransactionType {
1286
+ function mapEntryType(entryType: string): CreditTransactionType {
1289
1287
  const map: Record<string, CreditTransactionType> = {
1290
- grant: "purchase",
1288
+ purchase: "purchase",
1289
+ signup_credit: "signup_credit",
1290
+ bot_runtime: "bot_runtime",
1291
+ adapter_usage: "adapter_usage",
1291
1292
  refund: "refund",
1293
+ bonus: "bonus",
1292
1294
  correction: "adjustment",
1293
1295
  community_dividend: "community_dividend",
1296
+ // Legacy mappings
1297
+ grant: "purchase",
1294
1298
  };
1295
- return map[backendType] ?? "adjustment";
1299
+ return map[entryType] ?? "adjustment";
1300
+ }
1301
+
1302
+ /** Nanodollars per dollar (10^9). */
1303
+ const NANO_PER_DOLLAR = 1_000_000_000;
1304
+
1305
+ /** Clean up ledger descriptions for user-facing display. */
1306
+ function cleanDescription(raw: string, entryType: string, entryCount: number, amountDollars: number): string {
1307
+ // Aggregated usage: "LLM Inference — 25 requests"
1308
+ if (entryCount > 1) return `${raw} — ${entryCount} requests`;
1309
+ // Stripe purchases: strip session ID noise
1310
+ if (entryType === "purchase" && raw.includes("session:")) {
1311
+ const dollars = Math.abs(amountDollars).toFixed(2);
1312
+ return `Credit purchase — $${dollars}`;
1313
+ }
1314
+ // Welcome bonus / signup credit
1315
+ if (raw.toLowerCase().includes("welcome bonus") || raw.toLowerCase().includes("email verification")) {
1316
+ return "Signup credit";
1317
+ }
1318
+ return raw;
1319
+ }
1320
+
1321
+ /**
1322
+ * Fetch transaction history from the SQL-aggregated endpoint.
1323
+ * Inference costs are GROUP BY day + SUM'd in the DB.
1324
+ * Credits (purchases, refunds, bonuses) are returned individually.
1325
+ */
1326
+ /** Map raw tRPC creditsDailySummary rows to CreditTransaction[]. Reusable by both vanilla and React Query callers. */
1327
+ export function mapTransactionRows(
1328
+ rows: Array<{
1329
+ id: string;
1330
+ entryType: string;
1331
+ description: string;
1332
+ postedAt: string;
1333
+ signedAmountNano: number;
1334
+ entryCount: number;
1335
+ }>,
1336
+ ): CreditTransaction[] {
1337
+ return rows.map((r) => {
1338
+ let type = mapEntryType(r.entryType);
1339
+ const amount = r.signedAmountNano / NANO_PER_DOLLAR;
1340
+ if (
1341
+ r.description.toLowerCase().includes("welcome bonus") ||
1342
+ r.description.toLowerCase().includes("email verification")
1343
+ ) {
1344
+ type = "signup_credit";
1345
+ }
1346
+ const description = cleanDescription(r.description, r.entryType, r.entryCount, amount);
1347
+ return { id: r.id, type, description, amount, createdAt: r.postedAt };
1348
+ });
1296
1349
  }
1297
1350
 
1298
1351
  export async function getCreditHistory(_cursor?: string): Promise<CreditHistoryResponse> {
1299
- const res = await trpcVanilla.billing.creditsHistory.query({});
1300
- const entries = Array.isArray(res?.entries) ? res.entries : [];
1301
- return {
1302
- transactions: (
1303
- entries as Array<{
1304
- id?: string;
1305
- type?: string;
1306
- reason?: string;
1307
- amount_cents?: number;
1308
- created_at?: number;
1309
- }>
1310
- ).map((e) => ({
1311
- id: e.id ?? "",
1312
- type: mapTransactionType(e.type ?? ""),
1313
- description: e.reason ?? "",
1314
- amount: (e.amount_cents ?? 0) / 100,
1315
- createdAt: e.created_at
1316
- ? new Date(e.created_at * 1000).toISOString()
1317
- : new Date().toISOString(),
1318
- })),
1319
- nextCursor: null, // NOTE(WOP-687): implement cursor-based pagination
1320
- };
1352
+ const res = await trpcVanilla.billing.creditsDailySummary.query({});
1353
+ const rows = Array.isArray(res?.rows) ? res.rows : [];
1354
+ return { transactions: mapTransactionRows(rows), nextCursor: null };
1321
1355
  }
1322
1356
 
1323
1357
  export async function getCreditOptions(): Promise<CreditOption[]> {
@@ -1361,6 +1395,14 @@ export interface CheckoutResult {
1361
1395
  token: string;
1362
1396
  chain: string;
1363
1397
  referenceId: string;
1398
+ /** "native" or "erc20" */
1399
+ type?: string;
1400
+ /** ERC-20 contract address (null for native tokens). */
1401
+ contractAddress?: string | null;
1402
+ /** Token decimals. */
1403
+ decimals?: number;
1404
+ /** Expected amount in native base units. */
1405
+ expectedAmount?: string;
1364
1406
  priceCents?: number;
1365
1407
  }
1366
1408
 
@@ -1375,12 +1417,16 @@ export interface ChargeStatusResult {
1375
1417
  status: "pending" | "partial" | "confirmed" | "expired" | "failed";
1376
1418
  amountExpectedCents: number;
1377
1419
  amountReceivedCents: number;
1420
+ /** Native crypto amount expected (base units as string). */
1421
+ expectedAmount?: string | null;
1422
+ /** Native crypto amount received so far (base units as string). */
1423
+ receivedAmount?: string | null;
1424
+ token?: string;
1425
+ decimals?: number;
1378
1426
  confirmations: number;
1379
1427
  confirmationsRequired: number;
1380
1428
  txHash?: string;
1381
1429
  credited: boolean;
1382
- /** @deprecated Use amountExpectedCents. Removed next major. */
1383
- amountUsdCents: number;
1384
1430
  }
1385
1431
 
1386
1432
  export async function getChargeStatus(referenceId: string): Promise<ChargeStatusResult> {
@@ -1410,16 +1456,11 @@ export async function adminListPaymentMethods(): Promise<PaymentMethodAdmin[]> {
1410
1456
  return trpcVanilla.billing.adminListPaymentMethods.query(undefined);
1411
1457
  }
1412
1458
 
1413
- export async function adminUpsertPaymentMethod(
1414
- method: PaymentMethodAdmin,
1415
- ): Promise<{ ok: boolean }> {
1459
+ export async function adminUpsertPaymentMethod(method: PaymentMethodAdmin): Promise<{ ok: boolean }> {
1416
1460
  return trpcVanilla.billing.adminUpsertPaymentMethod.mutate(method);
1417
1461
  }
1418
1462
 
1419
- export async function adminTogglePaymentMethod(
1420
- id: string,
1421
- enabled: boolean,
1422
- ): Promise<{ ok: boolean }> {
1463
+ export async function adminTogglePaymentMethod(id: string, enabled: boolean): Promise<{ ok: boolean }> {
1423
1464
  return trpcVanilla.billing.adminTogglePaymentMethod.mutate({ id, enabled });
1424
1465
  }
1425
1466
 
@@ -1679,9 +1720,7 @@ export async function validateDeepgramKey(key: string): Promise<KeyValidationRes
1679
1720
  const { testProviderKey: testProviderKeyViaTrpc } = await import("./settings-api");
1680
1721
  try {
1681
1722
  const result = await testProviderKeyViaTrpc("transcription", key);
1682
- return result.valid
1683
- ? { valid: true }
1684
- : { valid: false, message: "Invalid API key. Please check and try again." };
1723
+ return result.valid ? { valid: true } : { valid: false, message: "Invalid API key. Please check and try again." };
1685
1724
  } catch (e) {
1686
1725
  log.warn("Key validation request failed", e);
1687
1726
  return { valid: false, message: "Could not validate key. Please try again." };
@@ -1689,9 +1728,7 @@ export async function validateDeepgramKey(key: string): Promise<KeyValidationRes
1689
1728
  }
1690
1729
 
1691
1730
  export async function validateElevenLabsKey(key: string): Promise<KeyValidationResult> {
1692
- const { testProviderKey, saveProviderKey: saveProviderKeyViaTrpc } = await import(
1693
- "./settings-api"
1694
- );
1731
+ const { testProviderKey, saveProviderKey: saveProviderKeyViaTrpc } = await import("./settings-api");
1695
1732
  try {
1696
1733
  const result = await testProviderKey("elevenlabs", key);
1697
1734
  if (result.valid) {
@@ -1778,21 +1815,17 @@ export async function createSnapshot(
1778
1815
  instanceId: string,
1779
1816
  name?: string,
1780
1817
  ): Promise<{ snapshot: Snapshot; estimatedMonthlyCost: string }> {
1781
- return apiFetch<{ snapshot: Snapshot; estimatedMonthlyCost: string }>(
1782
- `/bots/${instanceId}/snapshots`,
1783
- {
1784
- method: "POST",
1785
- body: JSON.stringify(name ? { name } : {}),
1786
- },
1787
- );
1818
+ return apiFetch<{ snapshot: Snapshot; estimatedMonthlyCost: string }>(`/bots/${instanceId}/snapshots`, {
1819
+ method: "POST",
1820
+ body: JSON.stringify(name ? { name } : {}),
1821
+ });
1788
1822
  }
1789
1823
 
1790
1824
  /** Restore an instance from a snapshot. Uses the /instances/ route. */
1791
1825
  export async function restoreSnapshot(instanceId: string, snapshotId: string): Promise<void> {
1792
- await apiFetch<{ ok: boolean; restored: string }>(
1793
- `/instances/${instanceId}/snapshots/${snapshotId}/restore`,
1794
- { method: "POST" },
1795
- );
1826
+ await apiFetch<{ ok: boolean; restored: string }>(`/instances/${instanceId}/snapshots/${snapshotId}/restore`, {
1827
+ method: "POST",
1828
+ });
1796
1829
  }
1797
1830
 
1798
1831
  /** Delete a snapshot. Backend returns 204 no content. */
@@ -1856,10 +1889,9 @@ export async function listFriends(instanceId: string): Promise<Friend[]> {
1856
1889
  }
1857
1890
 
1858
1891
  export async function listDiscoveredBots(instanceId: string): Promise<DiscoveredBot[]> {
1859
- const data = await apiFetch<{ discovered: DiscoveredBot[] }>(
1860
- `/instances/${instanceId}/friends/discovered`,
1861
- { method: "GET" },
1862
- );
1892
+ const data = await apiFetch<{ discovered: DiscoveredBot[] }>(`/instances/${instanceId}/friends/discovered`, {
1893
+ method: "GET",
1894
+ });
1863
1895
  return data.discovered;
1864
1896
  }
1865
1897
 
@@ -1871,10 +1903,9 @@ export async function sendFriendRequest(instanceId: string, targetBotId: string)
1871
1903
  }
1872
1904
 
1873
1905
  export async function listFriendRequests(instanceId: string): Promise<FriendRequest[]> {
1874
- const data = await apiFetch<{ requests: FriendRequest[] }>(
1875
- `/instances/${instanceId}/friends/requests`,
1876
- { method: "GET" },
1877
- );
1906
+ const data = await apiFetch<{ requests: FriendRequest[] }>(`/instances/${instanceId}/friends/requests`, {
1907
+ method: "GET",
1908
+ });
1878
1909
  return data.requests;
1879
1910
  }
1880
1911
 
@@ -1913,10 +1944,7 @@ export async function getAutoAcceptConfig(instanceId: string): Promise<AutoAccep
1913
1944
  });
1914
1945
  }
1915
1946
 
1916
- export async function updateAutoAcceptConfig(
1917
- instanceId: string,
1918
- config: AutoAcceptConfig,
1919
- ): Promise<void> {
1947
+ export async function updateAutoAcceptConfig(instanceId: string, config: AutoAcceptConfig): Promise<void> {
1920
1948
  await apiFetch<{ ok: boolean }>(`/instances/${instanceId}/friends/auto-accept`, {
1921
1949
  method: "PUT",
1922
1950
  body: JSON.stringify(config),
@@ -1940,10 +1968,7 @@ export interface LoginHistoryResponse {
1940
1968
  hasMore: boolean;
1941
1969
  }
1942
1970
 
1943
- export async function fetchLoginHistory(params: {
1944
- limit?: number;
1945
- offset?: number;
1946
- }): Promise<LoginHistoryResponse> {
1971
+ export async function fetchLoginHistory(params: { limit?: number; offset?: number }): Promise<LoginHistoryResponse> {
1947
1972
  const query = new URLSearchParams();
1948
1973
  if (params.limit != null) query.set("limit", String(params.limit));
1949
1974
  if (params.offset != null) query.set("offset", String(params.offset));
@@ -2011,11 +2036,7 @@ export interface VpsUpgradeResult {
2011
2036
  }
2012
2037
 
2013
2038
  /** Initiate a VPS upgrade for a bot. Returns the raw Response for status inspection (409, 402). */
2014
- export async function upgradeToVps(
2015
- botId: string,
2016
- successUrl: string,
2017
- cancelUrl: string,
2018
- ): Promise<Response> {
2039
+ export async function upgradeToVps(botId: string, successUrl: string, cancelUrl: string): Promise<Response> {
2019
2040
  return apiFetchRaw(`/fleet/bots/${botId}/upgrade-to-vps`, {
2020
2041
  method: "POST",
2021
2042
  body: JSON.stringify({ successUrl, cancelUrl }),
@@ -7,5 +7,4 @@ export const authClient = createAuthClient({
7
7
  plugins: [twoFactorClient()],
8
8
  });
9
9
 
10
- export const { useSession, signIn, signUp, signOut, linkSocial, unlinkAccount, listAccounts } =
11
- authClient;
10
+ export const { useSession, signIn, signUp, signOut, linkSocial, unlinkAccount, listAccounts } = authClient;
@@ -139,24 +139,17 @@ export async function getBotSettings(botId: string): Promise<BotSettings> {
139
139
  return apiFetch<BotSettings>(`/fleet/bots/${botId}/settings`);
140
140
  }
141
141
 
142
- export async function updateBotIdentity(
143
- botId: string,
144
- identity: BotIdentity,
145
- ): Promise<BotIdentity> {
142
+ export async function updateBotIdentity(botId: string, identity: BotIdentity): Promise<BotIdentity> {
146
143
  return apiFetch<BotIdentity>(`/fleet/bots/${botId}/identity`, {
147
144
  method: "PUT",
148
145
  body: JSON.stringify(identity),
149
146
  });
150
147
  }
151
148
 
152
- export async function activateSuperpower(
153
- botId: string,
154
- superpowerId: string,
155
- ): Promise<{ success: boolean }> {
156
- return apiFetch<{ success: boolean }>(
157
- `/fleet/bots/${botId}/capabilities/${superpowerId}/activate`,
158
- { method: "POST" },
159
- );
149
+ export async function activateSuperpower(botId: string, superpowerId: string): Promise<{ success: boolean }> {
150
+ return apiFetch<{ success: boolean }>(`/fleet/bots/${botId}/capabilities/${superpowerId}/activate`, {
151
+ method: "POST",
152
+ });
160
153
  }
161
154
 
162
155
  // --- Storage tier types ---
@@ -199,10 +192,7 @@ export async function getResourceTier(botId: string): Promise<{ tier: string }>
199
192
  return apiFetch<{ tier: string }>(`/fleet/bots/${botId}/resource-tier`);
200
193
  }
201
194
 
202
- export async function setResourceTier(
203
- botId: string,
204
- tier: string,
205
- ): Promise<{ tier: string; dailyCostCents: number }> {
195
+ export async function setResourceTier(botId: string, tier: string): Promise<{ tier: string; dailyCostCents: number }> {
206
196
  return apiFetch<{ tier: string; dailyCostCents: number }>(`/fleet/bots/${botId}/resource-tier`, {
207
197
  method: "PUT",
208
198
  body: JSON.stringify({ tier }),
@@ -248,11 +238,7 @@ export async function disconnectChannel(botId: string, channelId: string): Promi
248
238
  }
249
239
 
250
240
  /** Toggle a plugin's enabled/disabled state */
251
- export async function togglePlugin(
252
- botId: string,
253
- pluginId: string,
254
- enabled: boolean,
255
- ): Promise<void> {
241
+ export async function togglePlugin(botId: string, pluginId: string, enabled: boolean): Promise<void> {
256
242
  await apiFetch(`/fleet/bots/${botId}/plugins/${pluginId}`, {
257
243
  method: "PATCH",
258
244
  body: JSON.stringify({ enabled }),
@@ -280,10 +266,7 @@ export async function uninstallPlugin(botId: string, pluginId: string): Promise<
280
266
  }
281
267
 
282
268
  /** Fetch channel configuration */
283
- export async function getChannelConfig(
284
- botId: string,
285
- channelId: string,
286
- ): Promise<Record<string, string>> {
269
+ export async function getChannelConfig(botId: string, channelId: string): Promise<Record<string, string>> {
287
270
  return apiFetch<Record<string, string>>(`/fleet/bots/${botId}/channels/${channelId}/config`);
288
271
  }
289
272
 
@@ -300,10 +283,7 @@ export async function updateChannelConfig(
300
283
  }
301
284
 
302
285
  /** Fetch plugin configuration */
303
- export async function getPluginConfig(
304
- botId: string,
305
- pluginId: string,
306
- ): Promise<Record<string, string>> {
286
+ export async function getPluginConfig(botId: string, pluginId: string): Promise<Record<string, string>> {
307
287
  return apiFetch<Record<string, string>>(`/fleet/bots/${botId}/plugins/${pluginId}/config`);
308
288
  }
309
289
 
@@ -320,13 +300,8 @@ export async function updatePluginConfig(
320
300
  }
321
301
 
322
302
  /** Fetch superpower configuration */
323
- export async function getSuperpowerConfig(
324
- botId: string,
325
- superpowerId: string,
326
- ): Promise<Record<string, string>> {
327
- return apiFetch<Record<string, string>>(
328
- `/fleet/bots/${botId}/capabilities/${superpowerId}/config`,
329
- );
303
+ export async function getSuperpowerConfig(botId: string, superpowerId: string): Promise<Record<string, string>> {
304
+ return apiFetch<Record<string, string>>(`/fleet/bots/${botId}/capabilities/${superpowerId}/config`);
330
305
  }
331
306
 
332
307
  /** Save superpower configuration */