availsync 0.1.0

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 (460) hide show
  1. package/.adal/skills/stripe-best-practices/SKILL.md +42 -0
  2. package/.adal/skills/stripe-best-practices/references/billing.md +36 -0
  3. package/.adal/skills/stripe-best-practices/references/connect.md +48 -0
  4. package/.adal/skills/stripe-best-practices/references/payments.md +79 -0
  5. package/.adal/skills/stripe-best-practices/references/security.md +109 -0
  6. package/.adal/skills/stripe-best-practices/references/treasury.md +16 -0
  7. package/.adal/skills/stripe-projects/SKILL.md +139 -0
  8. package/.adal/skills/upgrade-stripe/SKILL.md +185 -0
  9. package/.agents/skills/stripe-best-practices/SKILL.md +42 -0
  10. package/.agents/skills/stripe-best-practices/references/billing.md +36 -0
  11. package/.agents/skills/stripe-best-practices/references/connect.md +48 -0
  12. package/.agents/skills/stripe-best-practices/references/payments.md +79 -0
  13. package/.agents/skills/stripe-best-practices/references/security.md +109 -0
  14. package/.agents/skills/stripe-best-practices/references/treasury.md +16 -0
  15. package/.agents/skills/stripe-projects/SKILL.md +139 -0
  16. package/.agents/skills/upgrade-stripe/SKILL.md +185 -0
  17. package/.augment/skills/stripe-best-practices/SKILL.md +42 -0
  18. package/.augment/skills/stripe-best-practices/references/billing.md +36 -0
  19. package/.augment/skills/stripe-best-practices/references/connect.md +48 -0
  20. package/.augment/skills/stripe-best-practices/references/payments.md +79 -0
  21. package/.augment/skills/stripe-best-practices/references/security.md +109 -0
  22. package/.augment/skills/stripe-best-practices/references/treasury.md +16 -0
  23. package/.augment/skills/stripe-projects/SKILL.md +139 -0
  24. package/.augment/skills/upgrade-stripe/SKILL.md +185 -0
  25. package/.bob/skills/stripe-best-practices/SKILL.md +42 -0
  26. package/.bob/skills/stripe-best-practices/references/billing.md +36 -0
  27. package/.bob/skills/stripe-best-practices/references/connect.md +48 -0
  28. package/.bob/skills/stripe-best-practices/references/payments.md +79 -0
  29. package/.bob/skills/stripe-best-practices/references/security.md +109 -0
  30. package/.bob/skills/stripe-best-practices/references/treasury.md +16 -0
  31. package/.bob/skills/stripe-projects/SKILL.md +139 -0
  32. package/.bob/skills/upgrade-stripe/SKILL.md +185 -0
  33. package/.claude/settings.local.json +7 -0
  34. package/.claude/skills/stripe-best-practices/SKILL.md +42 -0
  35. package/.claude/skills/stripe-best-practices/references/billing.md +36 -0
  36. package/.claude/skills/stripe-best-practices/references/connect.md +48 -0
  37. package/.claude/skills/stripe-best-practices/references/payments.md +79 -0
  38. package/.claude/skills/stripe-best-practices/references/security.md +109 -0
  39. package/.claude/skills/stripe-best-practices/references/treasury.md +16 -0
  40. package/.claude/skills/stripe-projects/SKILL.md +139 -0
  41. package/.claude/skills/upgrade-stripe/SKILL.md +185 -0
  42. package/.codebuddy/skills/stripe-best-practices/SKILL.md +42 -0
  43. package/.codebuddy/skills/stripe-best-practices/references/billing.md +36 -0
  44. package/.codebuddy/skills/stripe-best-practices/references/connect.md +48 -0
  45. package/.codebuddy/skills/stripe-best-practices/references/payments.md +79 -0
  46. package/.codebuddy/skills/stripe-best-practices/references/security.md +109 -0
  47. package/.codebuddy/skills/stripe-best-practices/references/treasury.md +16 -0
  48. package/.codebuddy/skills/stripe-projects/SKILL.md +139 -0
  49. package/.codebuddy/skills/upgrade-stripe/SKILL.md +185 -0
  50. package/.commandcode/skills/stripe-best-practices/SKILL.md +42 -0
  51. package/.commandcode/skills/stripe-best-practices/references/billing.md +36 -0
  52. package/.commandcode/skills/stripe-best-practices/references/connect.md +48 -0
  53. package/.commandcode/skills/stripe-best-practices/references/payments.md +79 -0
  54. package/.commandcode/skills/stripe-best-practices/references/security.md +109 -0
  55. package/.commandcode/skills/stripe-best-practices/references/treasury.md +16 -0
  56. package/.commandcode/skills/stripe-projects/SKILL.md +139 -0
  57. package/.commandcode/skills/upgrade-stripe/SKILL.md +185 -0
  58. package/.continue/skills/stripe-best-practices/SKILL.md +42 -0
  59. package/.continue/skills/stripe-best-practices/references/billing.md +36 -0
  60. package/.continue/skills/stripe-best-practices/references/connect.md +48 -0
  61. package/.continue/skills/stripe-best-practices/references/payments.md +79 -0
  62. package/.continue/skills/stripe-best-practices/references/security.md +109 -0
  63. package/.continue/skills/stripe-best-practices/references/treasury.md +16 -0
  64. package/.continue/skills/stripe-projects/SKILL.md +139 -0
  65. package/.continue/skills/upgrade-stripe/SKILL.md +185 -0
  66. package/.cortex/skills/stripe-best-practices/SKILL.md +42 -0
  67. package/.cortex/skills/stripe-best-practices/references/billing.md +36 -0
  68. package/.cortex/skills/stripe-best-practices/references/connect.md +48 -0
  69. package/.cortex/skills/stripe-best-practices/references/payments.md +79 -0
  70. package/.cortex/skills/stripe-best-practices/references/security.md +109 -0
  71. package/.cortex/skills/stripe-best-practices/references/treasury.md +16 -0
  72. package/.cortex/skills/stripe-projects/SKILL.md +139 -0
  73. package/.cortex/skills/upgrade-stripe/SKILL.md +185 -0
  74. package/.crush/skills/stripe-best-practices/SKILL.md +42 -0
  75. package/.crush/skills/stripe-best-practices/references/billing.md +36 -0
  76. package/.crush/skills/stripe-best-practices/references/connect.md +48 -0
  77. package/.crush/skills/stripe-best-practices/references/payments.md +79 -0
  78. package/.crush/skills/stripe-best-practices/references/security.md +109 -0
  79. package/.crush/skills/stripe-best-practices/references/treasury.md +16 -0
  80. package/.crush/skills/stripe-projects/SKILL.md +139 -0
  81. package/.crush/skills/upgrade-stripe/SKILL.md +185 -0
  82. package/.env.example +20 -0
  83. package/.factory/skills/stripe-best-practices/SKILL.md +42 -0
  84. package/.factory/skills/stripe-best-practices/references/billing.md +36 -0
  85. package/.factory/skills/stripe-best-practices/references/connect.md +48 -0
  86. package/.factory/skills/stripe-best-practices/references/payments.md +79 -0
  87. package/.factory/skills/stripe-best-practices/references/security.md +109 -0
  88. package/.factory/skills/stripe-best-practices/references/treasury.md +16 -0
  89. package/.factory/skills/stripe-projects/SKILL.md +139 -0
  90. package/.factory/skills/upgrade-stripe/SKILL.md +185 -0
  91. package/.goose/skills/stripe-best-practices/SKILL.md +42 -0
  92. package/.goose/skills/stripe-best-practices/references/billing.md +36 -0
  93. package/.goose/skills/stripe-best-practices/references/connect.md +48 -0
  94. package/.goose/skills/stripe-best-practices/references/payments.md +79 -0
  95. package/.goose/skills/stripe-best-practices/references/security.md +109 -0
  96. package/.goose/skills/stripe-best-practices/references/treasury.md +16 -0
  97. package/.goose/skills/stripe-projects/SKILL.md +139 -0
  98. package/.goose/skills/upgrade-stripe/SKILL.md +185 -0
  99. package/.iflow/skills/stripe-best-practices/SKILL.md +42 -0
  100. package/.iflow/skills/stripe-best-practices/references/billing.md +36 -0
  101. package/.iflow/skills/stripe-best-practices/references/connect.md +48 -0
  102. package/.iflow/skills/stripe-best-practices/references/payments.md +79 -0
  103. package/.iflow/skills/stripe-best-practices/references/security.md +109 -0
  104. package/.iflow/skills/stripe-best-practices/references/treasury.md +16 -0
  105. package/.iflow/skills/stripe-projects/SKILL.md +139 -0
  106. package/.iflow/skills/upgrade-stripe/SKILL.md +185 -0
  107. package/.junie/skills/stripe-best-practices/SKILL.md +42 -0
  108. package/.junie/skills/stripe-best-practices/references/billing.md +36 -0
  109. package/.junie/skills/stripe-best-practices/references/connect.md +48 -0
  110. package/.junie/skills/stripe-best-practices/references/payments.md +79 -0
  111. package/.junie/skills/stripe-best-practices/references/security.md +109 -0
  112. package/.junie/skills/stripe-best-practices/references/treasury.md +16 -0
  113. package/.junie/skills/stripe-projects/SKILL.md +139 -0
  114. package/.junie/skills/upgrade-stripe/SKILL.md +185 -0
  115. package/.kilocode/skills/stripe-best-practices/SKILL.md +42 -0
  116. package/.kilocode/skills/stripe-best-practices/references/billing.md +36 -0
  117. package/.kilocode/skills/stripe-best-practices/references/connect.md +48 -0
  118. package/.kilocode/skills/stripe-best-practices/references/payments.md +79 -0
  119. package/.kilocode/skills/stripe-best-practices/references/security.md +109 -0
  120. package/.kilocode/skills/stripe-best-practices/references/treasury.md +16 -0
  121. package/.kilocode/skills/stripe-projects/SKILL.md +139 -0
  122. package/.kilocode/skills/upgrade-stripe/SKILL.md +185 -0
  123. package/.kiro/skills/stripe-best-practices/SKILL.md +42 -0
  124. package/.kiro/skills/stripe-best-practices/references/billing.md +36 -0
  125. package/.kiro/skills/stripe-best-practices/references/connect.md +48 -0
  126. package/.kiro/skills/stripe-best-practices/references/payments.md +79 -0
  127. package/.kiro/skills/stripe-best-practices/references/security.md +109 -0
  128. package/.kiro/skills/stripe-best-practices/references/treasury.md +16 -0
  129. package/.kiro/skills/stripe-projects/SKILL.md +139 -0
  130. package/.kiro/skills/upgrade-stripe/SKILL.md +185 -0
  131. package/.kode/skills/stripe-best-practices/SKILL.md +42 -0
  132. package/.kode/skills/stripe-best-practices/references/billing.md +36 -0
  133. package/.kode/skills/stripe-best-practices/references/connect.md +48 -0
  134. package/.kode/skills/stripe-best-practices/references/payments.md +79 -0
  135. package/.kode/skills/stripe-best-practices/references/security.md +109 -0
  136. package/.kode/skills/stripe-best-practices/references/treasury.md +16 -0
  137. package/.kode/skills/stripe-projects/SKILL.md +139 -0
  138. package/.kode/skills/upgrade-stripe/SKILL.md +185 -0
  139. package/.mcpjam/skills/stripe-best-practices/SKILL.md +42 -0
  140. package/.mcpjam/skills/stripe-best-practices/references/billing.md +36 -0
  141. package/.mcpjam/skills/stripe-best-practices/references/connect.md +48 -0
  142. package/.mcpjam/skills/stripe-best-practices/references/payments.md +79 -0
  143. package/.mcpjam/skills/stripe-best-practices/references/security.md +109 -0
  144. package/.mcpjam/skills/stripe-best-practices/references/treasury.md +16 -0
  145. package/.mcpjam/skills/stripe-projects/SKILL.md +139 -0
  146. package/.mcpjam/skills/upgrade-stripe/SKILL.md +185 -0
  147. package/.mux/skills/stripe-best-practices/SKILL.md +42 -0
  148. package/.mux/skills/stripe-best-practices/references/billing.md +36 -0
  149. package/.mux/skills/stripe-best-practices/references/connect.md +48 -0
  150. package/.mux/skills/stripe-best-practices/references/payments.md +79 -0
  151. package/.mux/skills/stripe-best-practices/references/security.md +109 -0
  152. package/.mux/skills/stripe-best-practices/references/treasury.md +16 -0
  153. package/.mux/skills/stripe-projects/SKILL.md +139 -0
  154. package/.mux/skills/upgrade-stripe/SKILL.md +185 -0
  155. package/.neovate/skills/stripe-best-practices/SKILL.md +42 -0
  156. package/.neovate/skills/stripe-best-practices/references/billing.md +36 -0
  157. package/.neovate/skills/stripe-best-practices/references/connect.md +48 -0
  158. package/.neovate/skills/stripe-best-practices/references/payments.md +79 -0
  159. package/.neovate/skills/stripe-best-practices/references/security.md +109 -0
  160. package/.neovate/skills/stripe-best-practices/references/treasury.md +16 -0
  161. package/.neovate/skills/stripe-projects/SKILL.md +139 -0
  162. package/.neovate/skills/upgrade-stripe/SKILL.md +185 -0
  163. package/.nixpacksignore +14 -0
  164. package/.openhands/skills/stripe-best-practices/SKILL.md +42 -0
  165. package/.openhands/skills/stripe-best-practices/references/billing.md +36 -0
  166. package/.openhands/skills/stripe-best-practices/references/connect.md +48 -0
  167. package/.openhands/skills/stripe-best-practices/references/payments.md +79 -0
  168. package/.openhands/skills/stripe-best-practices/references/security.md +109 -0
  169. package/.openhands/skills/stripe-best-practices/references/treasury.md +16 -0
  170. package/.openhands/skills/stripe-projects/SKILL.md +139 -0
  171. package/.openhands/skills/upgrade-stripe/SKILL.md +185 -0
  172. package/.pi/skills/stripe-best-practices/SKILL.md +42 -0
  173. package/.pi/skills/stripe-best-practices/references/billing.md +36 -0
  174. package/.pi/skills/stripe-best-practices/references/connect.md +48 -0
  175. package/.pi/skills/stripe-best-practices/references/payments.md +79 -0
  176. package/.pi/skills/stripe-best-practices/references/security.md +109 -0
  177. package/.pi/skills/stripe-best-practices/references/treasury.md +16 -0
  178. package/.pi/skills/stripe-projects/SKILL.md +139 -0
  179. package/.pi/skills/upgrade-stripe/SKILL.md +185 -0
  180. package/.pochi/skills/stripe-best-practices/SKILL.md +42 -0
  181. package/.pochi/skills/stripe-best-practices/references/billing.md +36 -0
  182. package/.pochi/skills/stripe-best-practices/references/connect.md +48 -0
  183. package/.pochi/skills/stripe-best-practices/references/payments.md +79 -0
  184. package/.pochi/skills/stripe-best-practices/references/security.md +109 -0
  185. package/.pochi/skills/stripe-best-practices/references/treasury.md +16 -0
  186. package/.pochi/skills/stripe-projects/SKILL.md +139 -0
  187. package/.pochi/skills/upgrade-stripe/SKILL.md +185 -0
  188. package/.qoder/skills/stripe-best-practices/SKILL.md +42 -0
  189. package/.qoder/skills/stripe-best-practices/references/billing.md +36 -0
  190. package/.qoder/skills/stripe-best-practices/references/connect.md +48 -0
  191. package/.qoder/skills/stripe-best-practices/references/payments.md +79 -0
  192. package/.qoder/skills/stripe-best-practices/references/security.md +109 -0
  193. package/.qoder/skills/stripe-best-practices/references/treasury.md +16 -0
  194. package/.qoder/skills/stripe-projects/SKILL.md +139 -0
  195. package/.qoder/skills/upgrade-stripe/SKILL.md +185 -0
  196. package/.qwen/skills/stripe-best-practices/SKILL.md +42 -0
  197. package/.qwen/skills/stripe-best-practices/references/billing.md +36 -0
  198. package/.qwen/skills/stripe-best-practices/references/connect.md +48 -0
  199. package/.qwen/skills/stripe-best-practices/references/payments.md +79 -0
  200. package/.qwen/skills/stripe-best-practices/references/security.md +109 -0
  201. package/.qwen/skills/stripe-best-practices/references/treasury.md +16 -0
  202. package/.qwen/skills/stripe-projects/SKILL.md +139 -0
  203. package/.qwen/skills/upgrade-stripe/SKILL.md +185 -0
  204. package/.roo/skills/stripe-best-practices/SKILL.md +42 -0
  205. package/.roo/skills/stripe-best-practices/references/billing.md +36 -0
  206. package/.roo/skills/stripe-best-practices/references/connect.md +48 -0
  207. package/.roo/skills/stripe-best-practices/references/payments.md +79 -0
  208. package/.roo/skills/stripe-best-practices/references/security.md +109 -0
  209. package/.roo/skills/stripe-best-practices/references/treasury.md +16 -0
  210. package/.roo/skills/stripe-projects/SKILL.md +139 -0
  211. package/.roo/skills/upgrade-stripe/SKILL.md +185 -0
  212. package/.trae/skills/stripe-best-practices/SKILL.md +42 -0
  213. package/.trae/skills/stripe-best-practices/references/billing.md +36 -0
  214. package/.trae/skills/stripe-best-practices/references/connect.md +48 -0
  215. package/.trae/skills/stripe-best-practices/references/payments.md +79 -0
  216. package/.trae/skills/stripe-best-practices/references/security.md +109 -0
  217. package/.trae/skills/stripe-best-practices/references/treasury.md +16 -0
  218. package/.trae/skills/stripe-projects/SKILL.md +139 -0
  219. package/.trae/skills/upgrade-stripe/SKILL.md +185 -0
  220. package/.vibe/skills/stripe-best-practices/SKILL.md +42 -0
  221. package/.vibe/skills/stripe-best-practices/references/billing.md +36 -0
  222. package/.vibe/skills/stripe-best-practices/references/connect.md +48 -0
  223. package/.vibe/skills/stripe-best-practices/references/payments.md +79 -0
  224. package/.vibe/skills/stripe-best-practices/references/security.md +109 -0
  225. package/.vibe/skills/stripe-best-practices/references/treasury.md +16 -0
  226. package/.vibe/skills/stripe-projects/SKILL.md +139 -0
  227. package/.vibe/skills/upgrade-stripe/SKILL.md +185 -0
  228. package/.windsurf/skills/stripe-best-practices/SKILL.md +42 -0
  229. package/.windsurf/skills/stripe-best-practices/references/billing.md +36 -0
  230. package/.windsurf/skills/stripe-best-practices/references/connect.md +48 -0
  231. package/.windsurf/skills/stripe-best-practices/references/payments.md +79 -0
  232. package/.windsurf/skills/stripe-best-practices/references/security.md +109 -0
  233. package/.windsurf/skills/stripe-best-practices/references/treasury.md +16 -0
  234. package/.windsurf/skills/stripe-projects/SKILL.md +139 -0
  235. package/.windsurf/skills/upgrade-stripe/SKILL.md +185 -0
  236. package/.zencoder/skills/stripe-best-practices/SKILL.md +42 -0
  237. package/.zencoder/skills/stripe-best-practices/references/billing.md +36 -0
  238. package/.zencoder/skills/stripe-best-practices/references/connect.md +48 -0
  239. package/.zencoder/skills/stripe-best-practices/references/payments.md +79 -0
  240. package/.zencoder/skills/stripe-best-practices/references/security.md +109 -0
  241. package/.zencoder/skills/stripe-best-practices/references/treasury.md +16 -0
  242. package/.zencoder/skills/stripe-projects/SKILL.md +139 -0
  243. package/.zencoder/skills/upgrade-stripe/SKILL.md +185 -0
  244. package/AUDIT.md +95 -0
  245. package/BLOCKERS.md +0 -0
  246. package/COOLIFY.md +51 -0
  247. package/MCP_SETUP.md +23 -0
  248. package/PRODUCTION_CHECKLIST.md +246 -0
  249. package/README.md +47 -0
  250. package/ROADMAP.md +91 -0
  251. package/docs/superpowers/plans/2026-05-11-availsync-frontend-sales-flow.md +2445 -0
  252. package/frontend/.env.example +2 -0
  253. package/frontend/app/admin/layout.tsx +13 -0
  254. package/frontend/app/admin/page.tsx +747 -0
  255. package/frontend/app/app/activity/page.tsx +257 -0
  256. package/frontend/app/app/agents/[agentId]/page.tsx +21 -0
  257. package/frontend/app/app/agents/page.tsx +1155 -0
  258. package/frontend/app/app/audit/page.tsx +225 -0
  259. package/frontend/app/app/availability/page.tsx +840 -0
  260. package/frontend/app/app/holds/page.tsx +262 -0
  261. package/frontend/app/app/layout.tsx +19 -0
  262. package/frontend/app/app/onboarding/page.tsx +10 -0
  263. package/frontend/app/app/onboarding/verify/page.tsx +309 -0
  264. package/frontend/app/app/page.tsx +508 -0
  265. package/frontend/app/app/settings/page.tsx +399 -0
  266. package/frontend/app/app/work/page.tsx +426 -0
  267. package/frontend/app/changelog/page.tsx +93 -0
  268. package/frontend/app/checkout/page.tsx +25 -0
  269. package/frontend/app/docs/api/page.tsx +157 -0
  270. package/frontend/app/docs/page.tsx +296 -0
  271. package/frontend/app/docs/pilot/page.tsx +127 -0
  272. package/frontend/app/docs/quickstart/page.tsx +318 -0
  273. package/frontend/app/docs/reliability/page.tsx +78 -0
  274. package/frontend/app/docs/sdk/node/page.tsx +166 -0
  275. package/frontend/app/globals.css +57 -0
  276. package/frontend/app/icon.png +0 -0
  277. package/frontend/app/layout.tsx +87 -0
  278. package/frontend/app/login/page.tsx +14 -0
  279. package/frontend/app/page.tsx +47 -0
  280. package/frontend/app/pricing/page.tsx +66 -0
  281. package/frontend/app/privacy/page.tsx +52 -0
  282. package/frontend/app/robots.ts +26 -0
  283. package/frontend/app/security/page.tsx +74 -0
  284. package/frontend/app/signup/page.tsx +14 -0
  285. package/frontend/app/sitemap.ts +14 -0
  286. package/frontend/app/terms/page.tsx +51 -0
  287. package/frontend/components/brand/AvailsyncLogo.tsx +56 -0
  288. package/frontend/components/checkout/CheckoutClient.tsx +100 -0
  289. package/frontend/components/dashboard/AgentForm.tsx +59 -0
  290. package/frontend/components/dashboard/AppShell.tsx +291 -0
  291. package/frontend/components/dashboard/AvailabilityChecker.tsx +117 -0
  292. package/frontend/components/dashboard/AvailabilityWindowForm.tsx +40 -0
  293. package/frontend/components/dashboard/HoldForm.tsx +133 -0
  294. package/frontend/components/dashboard/MetricCard.tsx +10 -0
  295. package/frontend/components/login/LoginForm.tsx +95 -0
  296. package/frontend/components/marketing/AgentCoordinationStory.tsx +1530 -0
  297. package/frontend/components/marketing/Faq.tsx +41 -0
  298. package/frontend/components/marketing/Hero.tsx +73 -0
  299. package/frontend/components/marketing/HowItWorks.tsx +28 -0
  300. package/frontend/components/marketing/ObserveModeTeaser.tsx +41 -0
  301. package/frontend/components/marketing/PricingTeaser.tsx +23 -0
  302. package/frontend/components/marketing/ProblemSolution.tsx +36 -0
  303. package/frontend/components/marketing/SiteFooter.tsx +59 -0
  304. package/frontend/components/marketing/SiteHeader.tsx +45 -0
  305. package/frontend/components/marketing/UseCases.tsx +27 -0
  306. package/frontend/components/onboarding/OnboardingClient.tsx +278 -0
  307. package/frontend/components/pricing/PricingCards.tsx +65 -0
  308. package/frontend/components/privacy/CookieConsent.tsx +230 -0
  309. package/frontend/components/privacy/CookieSettingsButton.tsx +15 -0
  310. package/frontend/components/seo/JsonLd.tsx +10 -0
  311. package/frontend/components/signup/SignupForm.tsx +55 -0
  312. package/frontend/components/ui/Badge.tsx +23 -0
  313. package/frontend/components/ui/Button.tsx +37 -0
  314. package/frontend/components/ui/Card.tsx +11 -0
  315. package/frontend/components/ui/ConfirmDialog.tsx +77 -0
  316. package/frontend/components/ui/EmptyState.tsx +24 -0
  317. package/frontend/components/ui/Input.tsx +14 -0
  318. package/frontend/components/ui/KeyDisplay.tsx +49 -0
  319. package/frontend/components/ui/Select.tsx +14 -0
  320. package/frontend/components/ui/Skeleton.tsx +24 -0
  321. package/frontend/components/ui/Tabs.tsx +19 -0
  322. package/frontend/components/ui/Textarea.tsx +14 -0
  323. package/frontend/components/ui/Toast.tsx +78 -0
  324. package/frontend/components/waitlist/WaitlistDialog.tsx +128 -0
  325. package/frontend/lib/api.ts +1282 -0
  326. package/frontend/lib/billing.ts +6 -0
  327. package/frontend/lib/cookieConsent.ts +113 -0
  328. package/frontend/lib/format.ts +16 -0
  329. package/frontend/lib/plans.ts +62 -0
  330. package/frontend/lib/schemas.ts +108 -0
  331. package/frontend/lib/seo.ts +376 -0
  332. package/frontend/lib/setupGuides.ts +630 -0
  333. package/frontend/lib/storage.ts +30 -0
  334. package/frontend/next-env.d.ts +6 -0
  335. package/frontend/next.config.mjs +13 -0
  336. package/frontend/package-lock.json +14409 -0
  337. package/frontend/package.json +41 -0
  338. package/frontend/playwright.config.ts +20 -0
  339. package/frontend/postcss.config.mjs +8 -0
  340. package/frontend/public/.gitkeep +0 -0
  341. package/frontend/public/brand/availsync-logo-board.png +0 -0
  342. package/frontend/public/brand/availsync-logo-dark.png +0 -0
  343. package/frontend/public/brand/availsync-mark-dark.png +0 -0
  344. package/frontend/public/brand/availsync-wordmark-dark.png +0 -0
  345. package/frontend/public/marketing/hero-agent-coordination.png +0 -0
  346. package/frontend/tailwind.config.ts +53 -0
  347. package/frontend/tests/smoke.spec.ts +89 -0
  348. package/frontend/tsconfig.json +23 -0
  349. package/jest.config.js +7 -0
  350. package/nixpacks.toml +11 -0
  351. package/package.json +53 -0
  352. package/packages/mcp/LICENSE +21 -0
  353. package/packages/mcp/README.md +60 -0
  354. package/packages/mcp/jest.config.cjs +8 -0
  355. package/packages/mcp/package.json +54 -0
  356. package/packages/mcp/src/helpers.ts +38 -0
  357. package/packages/mcp/src/index.test.ts +60 -0
  358. package/packages/mcp/src/index.ts +387 -0
  359. package/packages/mcp/tsconfig.json +20 -0
  360. package/packages/mcp/tsconfig.test.json +12 -0
  361. package/packages/node/LICENSE +21 -0
  362. package/packages/node/README.md +120 -0
  363. package/packages/node/jest.config.cjs +8 -0
  364. package/packages/node/package.json +46 -0
  365. package/packages/node/src/index.test.ts +360 -0
  366. package/packages/node/src/index.ts +402 -0
  367. package/packages/node/tsconfig.json +20 -0
  368. package/packages/node/tsconfig.test.json +12 -0
  369. package/plan.md +923 -0
  370. package/skills/stripe-best-practices/SKILL.md +42 -0
  371. package/skills/stripe-best-practices/references/billing.md +36 -0
  372. package/skills/stripe-best-practices/references/connect.md +48 -0
  373. package/skills/stripe-best-practices/references/payments.md +79 -0
  374. package/skills/stripe-best-practices/references/security.md +109 -0
  375. package/skills/stripe-best-practices/references/treasury.md +16 -0
  376. package/skills/stripe-projects/SKILL.md +139 -0
  377. package/skills/upgrade-stripe/SKILL.md +185 -0
  378. package/skills-lock.json +20 -0
  379. package/src/core/availability.ts +178 -0
  380. package/src/core/conflict.ts +209 -0
  381. package/src/core/work.ts +490 -0
  382. package/src/db/client.ts +17 -0
  383. package/src/db/migrations/001_init.sql +88 -0
  384. package/src/db/migrations/002_stripe.sql +2 -0
  385. package/src/db/migrations/003_workspace_auth.sql +19 -0
  386. package/src/db/migrations/004_agent_mcp_status.sql +2 -0
  387. package/src/db/migrations/005_hold_event_actor.sql +4 -0
  388. package/src/db/migrations/006_agent_activity.sql +35 -0
  389. package/src/db/migrations/007_work_coordination.sql +60 -0
  390. package/src/db/migrations/008_work_claim_leases.sql +20 -0
  391. package/src/db/migrations/009_billing_subscription_state.sql +23 -0
  392. package/src/db/migrations/010_agent_api_key_prefix.sql +10 -0
  393. package/src/db/migrations/011_org_verified_and_work_event_retention.sql +11 -0
  394. package/src/db/migrations/012_agent_enforcement_mode.sql +12 -0
  395. package/src/db/migrations/013_support_tickets.sql +21 -0
  396. package/src/db/migrations/014_paid_plan_waitlist.sql +23 -0
  397. package/src/db/migrations/015_agent_last_seen.sql +2 -0
  398. package/src/db/migrations.ts +164 -0
  399. package/src/db/run-migrations.ts +13 -0
  400. package/src/index.ts +183 -0
  401. package/src/lib/activity.ts +137 -0
  402. package/src/lib/apiKeys.ts +32 -0
  403. package/src/lib/appInfo.ts +26 -0
  404. package/src/lib/billingConfig.ts +3 -0
  405. package/src/lib/env.ts +75 -0
  406. package/src/lib/logger.ts +8 -0
  407. package/src/lib/plans.ts +204 -0
  408. package/src/mcp/server.js +5 -0
  409. package/src/mcp/server.ts +350 -0
  410. package/src/middleware/auth.ts +342 -0
  411. package/src/middleware/requestId.ts +16 -0
  412. package/src/routes/account.ts +168 -0
  413. package/src/routes/activity.ts +126 -0
  414. package/src/routes/admin.ts +514 -0
  415. package/src/routes/audit.ts +68 -0
  416. package/src/routes/auth.ts +203 -0
  417. package/src/routes/availability.ts +325 -0
  418. package/src/routes/billing.ts +406 -0
  419. package/src/routes/conflicts.ts +131 -0
  420. package/src/routes/holds.ts +437 -0
  421. package/src/routes/mcp.ts +57 -0
  422. package/src/routes/metrics.ts +39 -0
  423. package/src/routes/onboarding.ts +273 -0
  424. package/src/routes/orgs.ts +981 -0
  425. package/src/routes/preferences.ts +132 -0
  426. package/src/routes/session.ts +16 -0
  427. package/src/routes/support.ts +77 -0
  428. package/src/routes/value.ts +186 -0
  429. package/src/routes/waitlist.ts +63 -0
  430. package/src/routes/work.ts +1578 -0
  431. package/src/server.ts +36 -0
  432. package/src/types/index.ts +109 -0
  433. package/tests/integration/activity.route.test.ts +103 -0
  434. package/tests/integration/admin.route.test.ts +143 -0
  435. package/tests/integration/agent-keys.route.test.ts +237 -0
  436. package/tests/integration/availability.route.test.ts +125 -0
  437. package/tests/integration/billing.route.test.ts +393 -0
  438. package/tests/integration/conflicts.route.test.ts +131 -0
  439. package/tests/integration/flows.test.ts +154 -0
  440. package/tests/integration/helpers.ts +134 -0
  441. package/tests/integration/holds.route.test.ts +185 -0
  442. package/tests/integration/metrics.route.test.ts +100 -0
  443. package/tests/integration/onboarding.verify.route.test.ts +163 -0
  444. package/tests/integration/preferences.route.test.ts +53 -0
  445. package/tests/integration/session.route.test.ts +97 -0
  446. package/tests/integration/system.route.test.ts +92 -0
  447. package/tests/integration/value.route.test.ts +235 -0
  448. package/tests/integration/work.route.test.ts +745 -0
  449. package/tests/setup.ts +4 -0
  450. package/tests/smoke.sh +62 -0
  451. package/tests/unit/auth.test.ts +114 -0
  452. package/tests/unit/availability.test.ts +149 -0
  453. package/tests/unit/conflict.test.ts +118 -0
  454. package/tests/unit/env.test.ts +69 -0
  455. package/tests/unit/migrations.test.ts +135 -0
  456. package/tests/unit/request-id.test.ts +37 -0
  457. package/tmp-mobile-agents.png +0 -0
  458. package/tmp-next-mobile.err.log +10 -0
  459. package/tmp-next-mobile.log +5 -0
  460. package/tsconfig.json +16 -0
@@ -0,0 +1,399 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { useSearchParams } from 'next/navigation';
5
+ import { clearSession, loadSession, type StoredSession } from '@/lib/storage';
6
+ import { getBillingStatus, getBillingPortal, createCheckout, deleteWorkspaceAccount } from '@/lib/api';
7
+ import { billingUpgradesEnabled } from '@/lib/billing';
8
+ import { findPlan } from '@/lib/plans';
9
+ import { Badge } from '@/components/ui/Badge';
10
+ import { useToast } from '@/components/ui/Toast';
11
+ import { Copy } from 'lucide-react';
12
+ import { Suspense } from 'react';
13
+ import { WaitlistDialog } from '@/components/waitlist/WaitlistDialog';
14
+
15
+ function SettingsContent() {
16
+ const { toast } = useToast();
17
+ const searchParams = useSearchParams();
18
+ const initialTab = searchParams.get('tab') || 'account';
19
+ const [tab, setTab] = useState(initialTab);
20
+ const [session, setSession] = useState<StoredSession | null>(null);
21
+ const [deleteConfirmation, setDeleteConfirmation] = useState('');
22
+ const [deletingWorkspace, setDeletingWorkspace] = useState(false);
23
+ const [waitlistPlan, setWaitlistPlan] = useState<'individual' | 'team' | null>(null);
24
+ const [billing, setBilling] = useState<{
25
+ plan: 'free' | 'individual' | 'team';
26
+ subscription_status: string;
27
+ renewal_date: string | null;
28
+ cancel_at_period_end: boolean;
29
+ billing_email: string | null;
30
+ limits: {
31
+ agents: number | null;
32
+ protected_resources: number;
33
+ active_work_claims: number;
34
+ api_calls_month: number;
35
+ activity_retention_days: number;
36
+ };
37
+ usage: {
38
+ agents: number;
39
+ protected_resources: number;
40
+ active_work_claims: number;
41
+ api_calls_month: number;
42
+ activity_retention_days: number;
43
+ };
44
+ upgrade_reasons: Array<{
45
+ limit_type: string;
46
+ usage: number;
47
+ limit: number;
48
+ state: 'near' | 'reached';
49
+ upgrade_plan: 'individual' | 'team' | null;
50
+ }>;
51
+ agents_used: number;
52
+ agent_limit: number;
53
+ stripe_customer_id: boolean;
54
+ stripe_subscription_id: boolean;
55
+ billing_upgrades_enabled: boolean;
56
+ } | null>(null);
57
+
58
+ useEffect(() => {
59
+ const s = loadSession();
60
+ setSession(s);
61
+ if (s) {
62
+ getBillingStatus().then(setBilling).catch(() => {});
63
+ }
64
+ }, []);
65
+
66
+ useEffect(() => {
67
+ if (searchParams.get('checkout') === 'success') {
68
+ toast('Billing updated', 'success');
69
+ }
70
+ }, [searchParams, toast]);
71
+
72
+ const handleUpgrade = async (plan: 'individual' | 'team') => {
73
+ if (!session) return;
74
+ const upgradesEnabled = billing?.billing_upgrades_enabled ?? billingUpgradesEnabled();
75
+ if (!upgradesEnabled) {
76
+ setWaitlistPlan(plan);
77
+ return;
78
+ }
79
+
80
+ try {
81
+ const result = await createCheckout({ plan, org_id: session.orgId });
82
+ if (result.url) {
83
+ window.location.href = result.url;
84
+ }
85
+ } catch (err) {
86
+ toast((err as Error).message, 'error');
87
+ }
88
+ };
89
+
90
+ const handleManageBilling = async () => {
91
+ if (!session) return;
92
+ try {
93
+ const result = await getBillingPortal();
94
+ window.location.href = result.url;
95
+ } catch (err) {
96
+ toast((err as Error).message, 'error');
97
+ }
98
+ };
99
+
100
+ const showCopied = (label: string) => {
101
+ toast(`${label} copied`, 'success');
102
+ };
103
+
104
+ const handleDeleteWorkspace = async () => {
105
+ if (deleteConfirmation !== 'DELETE') return;
106
+ if (!window.confirm('This permanently deletes the workspace and cancels any active subscription. Continue?')) {
107
+ return;
108
+ }
109
+
110
+ setDeletingWorkspace(true);
111
+ try {
112
+ await deleteWorkspaceAccount({ confirmation: 'DELETE' });
113
+ clearSession();
114
+ window.location.href = '/?workspace=deleted';
115
+ } catch (err) {
116
+ toast((err as Error).message, 'error');
117
+ setDeletingWorkspace(false);
118
+ }
119
+ };
120
+
121
+ const appUrl = typeof window === 'undefined' ? '' : window.location.origin;
122
+ const tabs = ['account', 'billing', 'api'];
123
+ const upgradesEnabled = billing?.billing_upgrades_enabled ?? billingUpgradesEnabled();
124
+
125
+ return (
126
+ <div className="w-full max-w-none p-4 sm:p-6">
127
+ <h1 className="text-title font-semibold text-text-primary mb-6">Settings</h1>
128
+
129
+ {/* Tab bar */}
130
+ <div className="flex items-center gap-0 border-b border-border mb-6">
131
+ {tabs.map((t) => (
132
+ <button
133
+ key={t}
134
+ onClick={() => setTab(t)}
135
+ className={`px-4 py-2 text-body font-medium capitalize transition-colors border-b-2 -mb-px ${
136
+ tab === t
137
+ ? 'border-accent text-text-primary'
138
+ : 'border-transparent text-text-tertiary hover:text-text-secondary'
139
+ }`}
140
+ >
141
+ {t}
142
+ </button>
143
+ ))}
144
+ </div>
145
+
146
+ {/* Account tab */}
147
+ {tab === 'account' && (
148
+ <div className="space-y-6">
149
+ <div className="rounded border border-border bg-surface p-4">
150
+ <label className="block text-label uppercase text-text-tertiary mb-1">Organization ID</label>
151
+ <div className="font-mono text-body text-text-secondary">{session?.orgId || '-'}</div>
152
+ </div>
153
+ <div className="rounded border border-error/30 bg-error/5 p-4">
154
+ <h3 className="text-heading font-medium text-error mb-1">Danger zone</h3>
155
+ <p className="text-body leading-6 text-text-secondary">
156
+ Permanently delete this workspace, revoke all agent API keys, remove runtime data,
157
+ and cancel any active Stripe subscription immediately.
158
+ </p>
159
+ {billing?.stripe_subscription_id && billing.subscription_status !== 'canceled' && (
160
+ <div className="mt-3 rounded border border-warning/40 bg-warning/10 px-3 py-2 text-body text-warning">
161
+ This workspace has a Stripe subscription. Deletion will try to cancel it before any data is removed.
162
+ </div>
163
+ )}
164
+ <div className="mt-4 grid gap-3 md:grid-cols-[1fr_auto] md:items-end">
165
+ <label className="block">
166
+ <span className="mb-1 block text-label uppercase text-text-tertiary">Type DELETE to confirm</span>
167
+ <input
168
+ value={deleteConfirmation}
169
+ onChange={(event) => setDeleteConfirmation(event.target.value)}
170
+ className="w-full rounded border border-border bg-bg px-3 py-2 font-mono text-body text-text-primary outline-none focus:border-border-focus"
171
+ placeholder="DELETE"
172
+ autoComplete="off"
173
+ />
174
+ </label>
175
+ <button
176
+ onClick={handleDeleteWorkspace}
177
+ disabled={deleteConfirmation !== 'DELETE' || deletingWorkspace}
178
+ className="rounded border border-error/40 bg-error/10 px-4 py-2 text-body font-medium text-error transition-colors hover:bg-error/15 disabled:cursor-not-allowed disabled:opacity-40"
179
+ >
180
+ {deletingWorkspace ? 'Deleting...' : 'Delete workspace'}
181
+ </button>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ )}
186
+
187
+ {/* Billing tab */}
188
+ {tab === 'billing' && (
189
+ <div className="space-y-6">
190
+ <div className="rounded border border-border bg-surface p-4">
191
+ <div className="flex flex-wrap items-center justify-between gap-3 mb-4">
192
+ <div className="flex items-center gap-3">
193
+ <span className="text-body text-text-secondary">Current plan:</span>
194
+ <Badge variant={billing?.plan === 'free' ? 'neutral' : 'accent'}>
195
+ {billing ? findPlan(billing.plan).name : 'Free'}
196
+ </Badge>
197
+ {billing?.subscription_status && (
198
+ <Badge variant={billing.subscription_status === 'active' ? 'success' : 'neutral'}>
199
+ {billing.subscription_status}
200
+ </Badge>
201
+ )}
202
+ </div>
203
+ {billing?.cancel_at_period_end && (
204
+ <span className="text-body text-warning">Cancels at period end</span>
205
+ )}
206
+ </div>
207
+ <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
208
+ <UsageRow label="Agents" used={billing?.usage.agents ?? 0} limit={billing?.limits.agents ?? null} />
209
+ <UsageRow label="Protected resources" used={billing?.usage.protected_resources ?? 0} limit={billing?.limits.protected_resources ?? 2} />
210
+ <UsageRow label="Active work claims" used={billing?.usage.active_work_claims ?? 0} limit={billing?.limits.active_work_claims ?? 1} />
211
+ <UsageRow label="API calls this month" used={billing?.usage.api_calls_month ?? 0} limit={billing?.limits.api_calls_month ?? 1000} />
212
+ </div>
213
+ <div className="mt-3 text-body text-text-tertiary">
214
+ Pilot history target: {billing?.limits.activity_retention_days ?? 7} days
215
+ </div>
216
+ {!upgradesEnabled && (
217
+ <div className="mt-4 rounded border border-accent/30 bg-accent/10 px-3 py-2 text-body text-text-secondary">
218
+ Paid upgrades are currently waitlist-only. Free workspaces remain available while
219
+ we onboard early pilots.
220
+ </div>
221
+ )}
222
+ {billing?.renewal_date && (
223
+ <div className="text-body text-text-tertiary mt-1">
224
+ Next billing: {new Date(billing.renewal_date).toLocaleDateString()}
225
+ </div>
226
+ )}
227
+ {billing?.upgrade_reasons.length ? (
228
+ <div className="mt-4 rounded border border-warning/40 bg-warning/10 px-3 py-2 text-body text-warning">
229
+ {billing.upgrade_reasons[0].state === 'reached' ? 'Limit reached' : 'Approaching plan limit'}:
230
+ {' '}
231
+ {billing.upgrade_reasons[0].limit_type.replaceAll('_', ' ')}
232
+ </div>
233
+ ) : null}
234
+ </div>
235
+
236
+ {billing?.plan !== 'free' && billing?.stripe_customer_id ? (
237
+ <button
238
+ onClick={handleManageBilling}
239
+ className="rounded bg-surface-raised border border-border px-4 py-2 text-body text-text-primary hover:bg-border transition-colors"
240
+ >
241
+ Manage billing &rarr;
242
+ </button>
243
+ ) : (
244
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
245
+ <PlanCard
246
+ name="Individual"
247
+ price={upgradesEnabled ? '$10' : 'Waitlist'}
248
+ period={upgradesEnabled ? '/mo' : ''}
249
+ features={['15 agents', 'Priority rules', 'More protected resources']}
250
+ cta={upgradesEnabled ? 'Upgrade' : 'Join waitlist'}
251
+ onSelect={() => handleUpgrade('individual')}
252
+ />
253
+ <PlanCard
254
+ name="Team"
255
+ price={upgradesEnabled ? '$25' : 'Waitlist'}
256
+ period={upgradesEnabled ? '/mo' : ''}
257
+ features={['Unlimited agents', 'Single workspace user for now', 'Advanced agent guardrails']}
258
+ cta={upgradesEnabled ? 'Upgrade' : 'Join waitlist'}
259
+ onSelect={() => handleUpgrade('team')}
260
+ />
261
+ </div>
262
+ )}
263
+ </div>
264
+ )}
265
+
266
+ {/* API tab */}
267
+ {tab === 'api' && (
268
+ <div className="space-y-6">
269
+ <div>
270
+ <h3 className="text-heading font-medium text-text-primary mb-3">Quick start</h3>
271
+ <CodeBlock
272
+ label="Check availability"
273
+ code={`curl -X GET "${appUrl}/v1/availability?agent_id=YOUR_AGENT_ID&from=NEXT_BUSINESS_DAY_START&to=NEXT_BUSINESS_DAY_END&duration_minutes=30" \\
274
+ -H "Authorization: Bearer YOUR_API_KEY"`}
275
+ onCopy={() => showCopied('Quick start')}
276
+ />
277
+ </div>
278
+
279
+ <div>
280
+ <h3 className="text-heading font-medium text-text-primary mb-3">MCP config</h3>
281
+ <CodeBlock
282
+ label="Claude Desktop config"
283
+ code={`{
284
+ "mcpServers": {
285
+ "availsync": {
286
+ "command": "npx",
287
+ "args": ["-y", "@availsync/mcp@alpha"],
288
+ "env": {
289
+ "AVAILSYNC_API_URL": "${appUrl}",
290
+ "AVAILSYNC_AGENT_ID": "YOUR_AGENT_ID",
291
+ "AVAILSYNC_API_KEY": "YOUR_API_KEY"
292
+ }
293
+ }
294
+ }
295
+ }`}
296
+ onCopy={() => showCopied('MCP config')}
297
+ />
298
+ </div>
299
+ </div>
300
+ )}
301
+ {waitlistPlan && (
302
+ <WaitlistDialog
303
+ open
304
+ plan={waitlistPlan}
305
+ source="settings"
306
+ defaultEmail={session?.email || billing?.billing_email || ''}
307
+ onClose={() => setWaitlistPlan(null)}
308
+ />
309
+ )}
310
+ </div>
311
+ );
312
+ }
313
+
314
+ function UsageRow({ label, used, limit }: { label: string; used: number; limit: number | null }) {
315
+ const pct = limit ? Math.min(100, Math.round((used / limit) * 100)) : 0;
316
+ return (
317
+ <div className="rounded border border-border bg-surface-raised p-3">
318
+ <div className="flex items-center justify-between gap-3 text-body">
319
+ <span className="text-text-secondary">{label}</span>
320
+ <span className="text-text-primary">{used.toLocaleString()} / {limit === null ? 'Unlimited' : limit.toLocaleString()}</span>
321
+ </div>
322
+ {limit !== null && (
323
+ <div className="mt-2 h-1.5 rounded bg-border">
324
+ <div
325
+ className={`h-1.5 rounded ${pct >= 100 ? 'bg-error' : pct >= 80 ? 'bg-warning' : 'bg-accent'}`}
326
+ style={{ width: `${pct}%` }}
327
+ />
328
+ </div>
329
+ )}
330
+ </div>
331
+ );
332
+ }
333
+
334
+ function PlanCard({
335
+ name,
336
+ price,
337
+ period,
338
+ features,
339
+ cta,
340
+ onSelect,
341
+ }: {
342
+ name: string;
343
+ price: string;
344
+ period: string;
345
+ features: string[];
346
+ cta: string;
347
+ onSelect: () => void;
348
+ }) {
349
+ return (
350
+ <div className="rounded border border-border bg-surface p-5">
351
+ <h3 className="text-heading font-medium text-text-primary">{name}</h3>
352
+ <div className="mt-2 mb-4">
353
+ <span className="text-title font-semibold text-text-primary">{price}</span>
354
+ <span className="text-body text-text-tertiary">{period}</span>
355
+ </div>
356
+ <ul className="space-y-1.5 mb-4">
357
+ {features.map((f) => (
358
+ <li key={f} className="text-body text-text-secondary">{f}</li>
359
+ ))}
360
+ </ul>
361
+ <button
362
+ onClick={onSelect}
363
+ className="w-full rounded bg-accent text-white py-2 text-body font-medium hover:bg-accent-hover transition-colors active:scale-[0.98]"
364
+ >
365
+ {cta}
366
+ </button>
367
+ </div>
368
+ );
369
+ }
370
+
371
+ function CodeBlock({ label, code, onCopy }: { label: string; code: string; onCopy: () => void }) {
372
+ return (
373
+ <div className="rounded border border-border bg-surface overflow-hidden">
374
+ <div className="flex items-center justify-between px-4 py-2 border-b border-border">
375
+ <span className="text-label uppercase text-text-tertiary">{label}</span>
376
+ <button
377
+ onClick={() => {
378
+ navigator.clipboard.writeText(code);
379
+ onCopy();
380
+ }}
381
+ className="text-text-tertiary hover:text-text-secondary transition-colors"
382
+ >
383
+ <Copy className="h-3.5 w-3.5" />
384
+ </button>
385
+ </div>
386
+ <pre className="px-4 py-3 text-[12px] font-mono text-text-secondary overflow-x-auto whitespace-pre">
387
+ {code}
388
+ </pre>
389
+ </div>
390
+ );
391
+ }
392
+
393
+ export default function SettingsPage() {
394
+ return (
395
+ <Suspense>
396
+ <SettingsContent />
397
+ </Suspense>
398
+ );
399
+ }