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,508 @@
1
+ 'use client';
2
+
3
+ import { Fragment, useEffect, useState } from 'react';
4
+ import { saveSession } from '@/lib/storage';
5
+ import {
6
+ getAuditLog,
7
+ getBillingStatus,
8
+ getMetricsOverview,
9
+ getValueHealth,
10
+ listAgents,
11
+ restoreSession,
12
+ type ValueHealth,
13
+ } from '@/lib/api';
14
+ import { SkeletonMetric } from '@/components/ui/Skeleton';
15
+ import { Badge } from '@/components/ui/Badge';
16
+ import { useRouter } from 'next/navigation';
17
+ import { Clipboard } from 'lucide-react';
18
+ import type { Agent } from '@/lib/schemas';
19
+ import { mcpEnvSnippet, nodeSdkSnippets, workGuardrailSnippets, schedulingSnippets } from '@/lib/setupGuides';
20
+
21
+ function formatRelative(dateStr: string) {
22
+ const diff = Date.now() - new Date(dateStr).getTime();
23
+ const mins = Math.floor(diff / 60000);
24
+ if (mins < 1) return 'just now';
25
+ if (mins < 60) return `${mins}m ago`;
26
+ const hours = Math.floor(mins / 60);
27
+ if (hours < 24) return `${hours}h ago`;
28
+ const days = Math.floor(hours / 24);
29
+ return `${days}d ago`;
30
+ }
31
+
32
+ const eventBadge: Record<string, { variant: 'success' | 'warning' | 'error' | 'neutral' | 'accent'; label: string }> = {
33
+ created: { variant: 'success', label: 'Created' },
34
+ superseded: { variant: 'warning', label: 'Superseded' },
35
+ released: { variant: 'neutral', label: 'Released' },
36
+ conflict_won: { variant: 'accent', label: 'Won' },
37
+ conflict_lost: { variant: 'error', label: 'Lost' },
38
+ };
39
+
40
+ const nextActionCopy: Record<ValueHealth['next_best_action'], { title: string; body: string; href: string; label: string }> = {
41
+ run_verification: {
42
+ title: 'Verify the workspace',
43
+ body: 'Run the dashboard verification to see Availsync resolve a real agent conflict.',
44
+ href: '/app/onboarding/verify',
45
+ label: 'Run verification',
46
+ },
47
+ connect_first_agent: {
48
+ title: 'Install the SDK and send a real run',
49
+ body: 'Verification is complete, but no production SDK/MCP/API traffic has reached Availsync yet. Put one agent in Observe and run a guarded repo task.',
50
+ href: '/app/agents',
51
+ label: 'Open agent setup',
52
+ },
53
+ check_inactive_agents: {
54
+ title: 'Check inactive agents',
55
+ body: 'One or more agents have not called Availsync recently. Check their SDK, REST, MCP, or automation env setup.',
56
+ href: '/app/agents',
57
+ label: 'Review agents',
58
+ },
59
+ review_errors: {
60
+ title: 'Review recent errors',
61
+ body: 'Recent runtime errors were reported by agents. Open Activity to inspect failed calls.',
62
+ href: '/app/activity?status=error',
63
+ label: 'Open Activity',
64
+ },
65
+ none: {
66
+ title: 'Agents are active',
67
+ body: 'Availsync has seen real runtime traffic and no immediate setup issue needs attention.',
68
+ href: '/app/activity',
69
+ label: 'Open Activity',
70
+ },
71
+ };
72
+
73
+ export default function OverviewPage() {
74
+ const router = useRouter();
75
+ const [loading, setLoading] = useState(true);
76
+ const [metrics, setMetrics] = useState<{
77
+ active_agents: number;
78
+ mcp_online: number;
79
+ confirmed_holds: number;
80
+ conflicts_resolved: number;
81
+ conflicts_blocked: number;
82
+ released_holds: number;
83
+ api_calls_today: number;
84
+ connected_agents: number;
85
+ recent_errors: number;
86
+ token_usage_reported: number;
87
+ active_work_claims: number;
88
+ protected_resources: number;
89
+ blocked_agent_runs: number;
90
+ released_work_slots: number;
91
+ latest_event_at: string | null;
92
+ } | null>(null);
93
+ const [billing, setBilling] = useState<Awaited<ReturnType<typeof getBillingStatus>> | null>(null);
94
+ const [valueHealth, setValueHealth] = useState<ValueHealth | null>(null);
95
+ const [agents, setAgents] = useState<Agent[]>([]);
96
+ const [events, setEvents] = useState<Array<{
97
+ id: string;
98
+ event_type: string;
99
+ agent_name: string;
100
+ created_at: string;
101
+ hold_id: string;
102
+ rule_applied: string | null;
103
+ metadata: Record<string, unknown> | null;
104
+ actor_type: string | null;
105
+ actor_label: string | null;
106
+ }>>([]);
107
+ const [expandedEvent, setExpandedEvent] = useState<string | null>(null);
108
+ const [selectedSetupAgentId, setSelectedSetupAgentId] = useState('');
109
+ const [verifiedAt, setVerifiedAt] = useState<string | null>(null);
110
+ const selectedSetupAgent = agents.find((agent) => agent.id === selectedSetupAgentId) ?? agents[0];
111
+
112
+ useEffect(() => {
113
+ restoreSession().then(async (sessionData) => {
114
+ saveSession({
115
+ orgId: sessionData.org.id,
116
+ userId: sessionData.user.id,
117
+ email: sessionData.user.email,
118
+ });
119
+ const [metricsData, auditData, agentRows, billingData, valueHealthData] = await Promise.all([
120
+ getMetricsOverview(),
121
+ getAuditLog({ limit: 10 }).catch(() => ({ events: [] })),
122
+ listAgents(sessionData.org.id).catch(() => []),
123
+ getBillingStatus().catch(() => null),
124
+ getValueHealth().catch(() => null),
125
+ ]);
126
+ setMetrics(metricsData);
127
+ setEvents(auditData.events);
128
+ setAgents(agentRows);
129
+ setSelectedSetupAgentId((current) => current || agentRows[0]?.id || '');
130
+ setBilling(billingData);
131
+ setValueHealth(valueHealthData);
132
+ setVerifiedAt(sessionData.org.verified_at ?? null);
133
+ setLoading(false);
134
+ }).catch(() => router.push('/login'));
135
+ }, [router]);
136
+
137
+ return (
138
+ <div className="w-full max-w-none p-4 sm:p-6">
139
+ <h1 className="text-title font-semibold text-text-primary mb-6">Overview</h1>
140
+
141
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3 mb-8">
142
+ {loading ? (
143
+ <>
144
+ <SkeletonMetric />
145
+ <SkeletonMetric />
146
+ <SkeletonMetric />
147
+ <SkeletonMetric />
148
+ <SkeletonMetric />
149
+ </>
150
+ ) : (
151
+ <>
152
+ <MetricBlock
153
+ label="Active agents"
154
+ value={String(metrics?.active_agents ?? 0)}
155
+ sub={`${metrics?.connected_agents ?? 0} connected`}
156
+ />
157
+ <MetricBlock label="API calls today" value={String(metrics?.api_calls_today ?? 0)} />
158
+ <MetricBlock
159
+ label="Active work claims"
160
+ value={String(metrics?.active_work_claims ?? 0)}
161
+ sub={`${metrics?.protected_resources ?? 0} resources`}
162
+ />
163
+ <MetricBlock
164
+ label="Blocked agent runs"
165
+ value={String(metrics?.blocked_agent_runs ?? 0)}
166
+ sub={`${metrics?.released_work_slots ?? 0} released`}
167
+ />
168
+ <MetricBlock
169
+ label="Plan usage"
170
+ value={billing?.plan || 'free'}
171
+ sub={`${billing?.usage.api_calls_month ?? 0}/${billing?.limits.api_calls_month ?? 1000} API calls`}
172
+ />
173
+ </>
174
+ )}
175
+ </div>
176
+
177
+ {!loading && valueHealth && (
178
+ <div className="mb-8 grid grid-cols-1 gap-3 lg:grid-cols-[1.4fr_1fr]">
179
+ <ValuePanel valueHealth={valueHealth} />
180
+ <AgentHealthPanel valueHealth={valueHealth} agents={agents} />
181
+ </div>
182
+ )}
183
+
184
+ <SetupGuide
185
+ agents={agents}
186
+ selectedAgent={selectedSetupAgent}
187
+ selectedAgentId={selectedSetupAgentId}
188
+ onSelectAgent={setSelectedSetupAgentId}
189
+ verifiedAt={verifiedAt}
190
+ />
191
+
192
+ <div>
193
+ <h2 className="text-heading font-medium text-text-primary mb-3">Recent activity</h2>
194
+ {events.length === 0 && !loading ? (
195
+ <div className="rounded border border-border bg-surface p-4">
196
+ <p className="text-body text-text-secondary">
197
+ No audit events yet. Run an MCP heartbeat or call check_work_slot from an agent, then open Activity to validate runtime traffic.
198
+ </p>
199
+ <div className="mt-3 flex flex-wrap gap-2">
200
+ <a href={selectedSetupAgent ? `/app/agents?connect=${selectedSetupAgent.id}` : '/app/agents'} className="rounded bg-accent px-3 py-1.5 text-body font-medium text-white hover:bg-accent-hover">
201
+ Open agent setup
202
+ </a>
203
+ <a href="/docs/sdk/node" className="rounded border border-border px-3 py-1.5 text-body text-text-secondary hover:text-text-primary">
204
+ Read SDK docs
205
+ </a>
206
+ <a href="/app/activity" className="rounded border border-border px-3 py-1.5 text-body text-text-secondary hover:text-text-primary">
207
+ Open Activity
208
+ </a>
209
+ </div>
210
+ </div>
211
+ ) : (
212
+ <div className="overflow-x-auto rounded border border-border dark-scroll">
213
+ <table className="w-full min-w-[760px]">
214
+ <thead>
215
+ <tr className="border-b border-border bg-surface text-label uppercase text-text-tertiary">
216
+ <th className="text-left px-4 py-2 font-medium">Time</th>
217
+ <th className="text-left px-4 py-2 font-medium">Agent</th>
218
+ <th className="text-left px-4 py-2 font-medium">Event</th>
219
+ <th className="text-left px-4 py-2 font-medium">Actor</th>
220
+ </tr>
221
+ </thead>
222
+ <tbody>
223
+ {events.map((event) => {
224
+ const badge = eventBadge[event.event_type] || { variant: 'neutral' as const, label: event.event_type };
225
+ const isExpanded = expandedEvent === event.id;
226
+ return (
227
+ <Fragment key={event.id}>
228
+ <tr
229
+ className="border-b border-border h-9 hover:bg-surface-raised cursor-pointer transition-colors duration-150"
230
+ onClick={() => setExpandedEvent(isExpanded ? null : event.id)}
231
+ >
232
+ <td className="px-4 font-mono text-body text-text-tertiary">
233
+ {formatRelative(event.created_at)}
234
+ </td>
235
+ <td className="px-4 text-body text-text-secondary">
236
+ {event.agent_name || 'Unknown'}
237
+ </td>
238
+ <td className="px-4">
239
+ <Badge variant={badge.variant}>{badge.label}</Badge>
240
+ </td>
241
+ <td className="px-4 text-body text-text-secondary">
242
+ {event.actor_label || event.actor_type || '-'}
243
+ </td>
244
+ </tr>
245
+ {isExpanded && (
246
+ <tr className="border-b border-border">
247
+ <td colSpan={4} className="px-4 py-3 bg-surface">
248
+ <pre className="font-mono text-[11px] text-text-secondary whitespace-pre-wrap">
249
+ {JSON.stringify({ hold_id: event.hold_id, metadata: event.metadata }, null, 2)}
250
+ </pre>
251
+ </td>
252
+ </tr>
253
+ )}
254
+ </Fragment>
255
+ );
256
+ })}
257
+ </tbody>
258
+ </table>
259
+ </div>
260
+ )}
261
+ </div>
262
+ </div>
263
+ );
264
+ }
265
+
266
+ function SetupGuide({
267
+ agents,
268
+ selectedAgent,
269
+ selectedAgentId,
270
+ onSelectAgent,
271
+ verifiedAt,
272
+ }: {
273
+ agents: Agent[];
274
+ selectedAgent?: Agent;
275
+ selectedAgentId: string;
276
+ onSelectAgent: (agentId: string) => void;
277
+ verifiedAt: string | null;
278
+ }) {
279
+ const agentId = selectedAgent?.id || 'YOUR_AGENT_ID';
280
+ const appUrl = typeof window === 'undefined' ? 'https://availsync.dev' : window.location.origin;
281
+ const snippets = [
282
+ {
283
+ ...nodeSdkSnippets({ appUrl, agentId })[0],
284
+ title: '1. Install Node SDK',
285
+ description: 'Use npm install @availsync/node@alpha, then wrap your repo task with withClaim.',
286
+ },
287
+ {
288
+ ...mcpEnvSnippet({ appUrl, agentId }),
289
+ title: '2. Add runtime env',
290
+ description: 'Store the API key only in your agent, CI, MCP, or server environment.',
291
+ },
292
+ {
293
+ ...workGuardrailSnippets({ appUrl, agentId })[0],
294
+ title: '3. Check repo work',
295
+ },
296
+ {
297
+ ...workGuardrailSnippets({ appUrl, agentId })[1],
298
+ title: '4. Claim before coding',
299
+ },
300
+ {
301
+ ...workGuardrailSnippets({ appUrl, agentId })[2],
302
+ title: '5. Extend while working',
303
+ },
304
+ {
305
+ ...workGuardrailSnippets({ appUrl, agentId })[3],
306
+ title: '6. Release when finished',
307
+ },
308
+ {
309
+ ...schedulingSnippets({ appUrl, agentId })[0],
310
+ title: '7. Optional scheduling check',
311
+ },
312
+ ];
313
+
314
+ return (
315
+ <div className="mb-8">
316
+ <div className="mb-3 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
317
+ <div>
318
+ <h2 className="text-heading font-medium text-text-primary">Setup guide</h2>
319
+ <p className="mt-1 text-body text-text-tertiary">
320
+ Start with dashboard verification, install the Node SDK, run one agent in Observe, then confirm real traffic in Activity.
321
+ </p>
322
+ <div className="mt-2 flex items-center gap-2">
323
+ <Badge variant={verifiedAt ? 'success' : 'neutral'}>
324
+ {verifiedAt ? 'Integration verified' : 'Verification pending'}
325
+ </Badge>
326
+ {!verifiedAt && (
327
+ <a href="/app/onboarding/verify" className="text-body text-accent hover:text-accent-hover">
328
+ Run verification
329
+ </a>
330
+ )}
331
+ </div>
332
+ </div>
333
+ <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
334
+ <select
335
+ value={selectedAgentId}
336
+ onChange={(event) => onSelectAgent(event.target.value)}
337
+ className="rounded border border-border bg-surface px-3 py-1.5 text-body text-text-primary outline-none focus:border-border-focus"
338
+ disabled={agents.length === 0}
339
+ >
340
+ {agents.length === 0 ? (
341
+ <option value="">No agents yet</option>
342
+ ) : (
343
+ agents.map((agent) => (
344
+ <option key={agent.id} value={agent.id}>
345
+ {agent.name}
346
+ </option>
347
+ ))
348
+ )}
349
+ </select>
350
+ <div className="flex gap-3">
351
+ <a href={selectedAgent ? `/app/agents?connect=${selectedAgent.id}` : '/app/agents'} className="text-body text-accent hover:text-accent-hover">
352
+ Connect agent
353
+ </a>
354
+ <a href="/docs/quickstart" className="text-body text-accent hover:text-accent-hover">
355
+ Full quickstart
356
+ </a>
357
+ <a href="/docs/pilot" className="text-body text-accent hover:text-accent-hover">
358
+ Pilot guide
359
+ </a>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
364
+ <GuideCard
365
+ title="Agent ID"
366
+ body="Use this ID when your coding agent checks, claims, extends, or releases guarded work through Availsync."
367
+ code={agentId}
368
+ />
369
+ {snippets.map((snippet) => (
370
+ <GuideCard key={snippet.id} title={snippet.title} body={snippet.description} code={snippet.code} />
371
+ ))}
372
+ </div>
373
+ </div>
374
+ );
375
+ }
376
+
377
+ function ValuePanel({ valueHealth }: { valueHealth: ValueHealth }) {
378
+ const action = nextActionCopy[valueHealth.next_best_action];
379
+
380
+ return (
381
+ <section className="rounded border border-border bg-surface p-4">
382
+ <div className="mb-4 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
383
+ <div>
384
+ <h2 className="text-heading font-medium text-text-primary">Value this week</h2>
385
+ <p className="mt-1 text-body text-text-tertiary">
386
+ Real agent traffic only. Setup tests and onboarding verification are excluded.
387
+ </p>
388
+ </div>
389
+ <Badge variant={valueHealth.summary.conflicts_prevented_7d > 0 ? 'success' : 'neutral'}>
390
+ {valueHealth.summary.conflicts_prevented_7d} prevented
391
+ </Badge>
392
+ </div>
393
+ <div className="grid grid-cols-2 gap-3 lg:grid-cols-5">
394
+ <MiniMetric label="Conflicts prevented" value={valueHealth.summary.conflicts_prevented_7d} />
395
+ <MiniMetric label="Blocked work runs" value={valueHealth.summary.blocked_work_runs_7d} />
396
+ <MiniMetric label="Would have blocked" value={valueHealth.summary.would_have_blocked_runs_7d} />
397
+ <MiniMetric label="Real API calls" value={valueHealth.summary.api_calls_7d} />
398
+ <MiniMetric
399
+ label="Latest real activity"
400
+ value={valueHealth.summary.latest_real_activity_at ? formatRelative(valueHealth.summary.latest_real_activity_at) : 'none'}
401
+ text
402
+ />
403
+ </div>
404
+ <div className="mt-4 rounded border border-border bg-bg p-3">
405
+ <div className="text-body font-medium text-text-primary">{action.title}</div>
406
+ <p className="mt-1 text-body text-text-secondary">{action.body}</p>
407
+ <a href={action.href} className="mt-2 inline-flex rounded bg-accent px-3 py-1.5 text-body font-medium text-white hover:bg-accent-hover">
408
+ {action.label}
409
+ </a>
410
+ </div>
411
+ </section>
412
+ );
413
+ }
414
+
415
+ function AgentHealthPanel({ valueHealth, agents }: { valueHealth: ValueHealth; agents: Agent[] }) {
416
+ const needsAttention = valueHealth.agent_health.filter((agent) => agent.status !== 'healthy');
417
+ const rows = needsAttention.length > 0 ? needsAttention : valueHealth.agent_health.slice(0, 3);
418
+
419
+ return (
420
+ <section className="rounded border border-border bg-surface p-4">
421
+ <h2 className="text-heading font-medium text-text-primary">Agent health</h2>
422
+ <p className="mt-1 text-body text-text-tertiary">Quiet agents usually mean stale SDK/REST/MCP env, stopped automation, or disabled credentials.</p>
423
+ <div className="mt-4 space-y-2">
424
+ {rows.length === 0 ? (
425
+ <p className="text-body text-text-tertiary">No agents yet.</p>
426
+ ) : (
427
+ rows.map((agent) => {
428
+ const knownAgent = agents.find((row) => row.id === agent.agent_id);
429
+ return (
430
+ <a
431
+ key={agent.agent_id}
432
+ href={`/app/agents?connect=${agent.agent_id}`}
433
+ className="flex items-center justify-between gap-3 rounded border border-border bg-bg px-3 py-2 hover:bg-surface-raised"
434
+ >
435
+ <div className="min-w-0">
436
+ <div className="truncate text-body font-medium text-text-primary">{agent.name}</div>
437
+ <div className="text-label text-text-tertiary">
438
+ {agent.last_activity_at
439
+ ? `Last real activity ${formatRelative(agent.last_activity_at)}`
440
+ : agent.last_seen_at
441
+ ? `Last seen ${formatRelative(agent.last_seen_at)}`
442
+ : knownAgent?.mcp_last_seen_at
443
+ ? `MCP ${formatRelative(knownAgent.mcp_last_seen_at)}`
444
+ : 'No SDK, REST, or MCP traffic yet'}
445
+ </div>
446
+ </div>
447
+ <HealthBadge status={agent.status} />
448
+ </a>
449
+ );
450
+ })
451
+ )}
452
+ </div>
453
+ </section>
454
+ );
455
+ }
456
+
457
+ function MiniMetric({ label, value, text }: { label: string; value: number | string; text?: boolean }) {
458
+ return (
459
+ <div className="rounded border border-border bg-bg p-3">
460
+ <div className="text-label uppercase text-text-tertiary">{label}</div>
461
+ <div className={`${text ? 'text-body' : 'font-mono text-[24px]'} mt-1 font-semibold text-text-primary`}>
462
+ {value}
463
+ </div>
464
+ </div>
465
+ );
466
+ }
467
+
468
+ function HealthBadge({ status }: { status: ValueHealth['agent_health'][number]['status'] }) {
469
+ const map: Record<ValueHealth['agent_health'][number]['status'], { label: string; variant: 'success' | 'warning' | 'neutral' | 'error' }> = {
470
+ healthy: { label: 'Healthy', variant: 'success' },
471
+ quiet: { label: 'Quiet', variant: 'warning' },
472
+ never_connected: { label: 'Never connected', variant: 'neutral' },
473
+ error: { label: 'Error', variant: 'error' },
474
+ };
475
+ const entry = map[status];
476
+ return <Badge variant={entry.variant}>{entry.label}</Badge>;
477
+ }
478
+
479
+ function GuideCard({ title, body, code }: { title: string; body: string; code: string }) {
480
+ return (
481
+ <div className="rounded border border-border bg-surface p-4">
482
+ <h3 className="text-body font-medium text-text-primary">{title}</h3>
483
+ <p className="mt-1 mb-3 text-body text-text-secondary">{body}</p>
484
+ <div className="group relative rounded border border-border bg-bg">
485
+ <button
486
+ onClick={() => navigator.clipboard.writeText(code)}
487
+ className="absolute right-2 top-2 rounded border border-border bg-surface p-1.5 text-text-tertiary opacity-0 transition-opacity hover:text-text-secondary group-hover:opacity-100 focus:opacity-100"
488
+ title="Copy"
489
+ >
490
+ <Clipboard className="h-3.5 w-3.5" />
491
+ </button>
492
+ <pre className="max-h-56 overflow-auto p-3 pr-10 text-[11px] font-mono text-text-secondary whitespace-pre-wrap break-all">
493
+ {code}
494
+ </pre>
495
+ </div>
496
+ </div>
497
+ );
498
+ }
499
+
500
+ function MetricBlock({ label, value, sub }: { label: string; value: string; sub?: string }) {
501
+ return (
502
+ <div className="rounded border border-border bg-surface p-4">
503
+ <div className="text-label uppercase text-text-tertiary mb-2">{label}</div>
504
+ <div className="font-mono text-[30px] font-semibold leading-tight text-text-primary capitalize">{value}</div>
505
+ {sub && <div className="text-body text-text-tertiary mt-0.5">{sub}</div>}
506
+ </div>
507
+ );
508
+ }