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,630 @@
1
+ export type SetupSnippet = {
2
+ id: string;
3
+ title: string;
4
+ description: string;
5
+ code: string;
6
+ copyLabel: string;
7
+ };
8
+
9
+ export type SetupGuideInput = {
10
+ appUrl?: string;
11
+ agentId?: string;
12
+ resourceType?: 'project' | 'repo';
13
+ resourceKey?: string;
14
+ durationMinutes?: number;
15
+ };
16
+
17
+ export const resourceScopeNote =
18
+ 'Use repo-level resources for maximum safety. Use project-level resources only for independent work streams; Availsync does not yet infer dependencies between different resources.';
19
+
20
+ function values(input: SetupGuideInput) {
21
+ return {
22
+ appUrl: input.appUrl || 'https://availsync.dev',
23
+ agentId: input.agentId || 'AGENT_ID',
24
+ resourceType: input.resourceType || 'repo',
25
+ resourceKey: input.resourceKey || 'owner/repo',
26
+ durationMinutes: input.durationMinutes || 45,
27
+ };
28
+ }
29
+
30
+ export function mcpEnvSnippet(input: SetupGuideInput = {}): SetupSnippet {
31
+ const { appUrl, agentId } = values(input);
32
+ return {
33
+ id: 'mcp-env',
34
+ title: 'MCP environment',
35
+ description: 'Store these values in your MCP or server environment. The API key is a runtime secret.',
36
+ copyLabel: 'Copy MCP env',
37
+ code: `AVAILSYNC_API_URL=${appUrl}
38
+ AVAILSYNC_AGENT_ID=${agentId}
39
+ AVAILSYNC_API_KEY=API_KEY`,
40
+ };
41
+ }
42
+
43
+ export function claudeCursorSnippet(input: SetupGuideInput = {}): SetupSnippet {
44
+ const { appUrl, agentId } = values(input);
45
+ return {
46
+ id: 'claude-cursor-mcp',
47
+ title: 'Claude or Cursor MCP config',
48
+ description: 'Use the public stdio MCP package with environment variables. Replace API_KEY in your local secret store.',
49
+ copyLabel: 'Copy MCP config',
50
+ code: `{
51
+ "mcpServers": {
52
+ "availsync": {
53
+ "command": "npx",
54
+ "args": ["-y", "@availsync/mcp@alpha"],
55
+ "env": {
56
+ "AVAILSYNC_API_URL": "${appUrl}",
57
+ "AVAILSYNC_AGENT_ID": "${agentId}",
58
+ "AVAILSYNC_API_KEY": "API_KEY"
59
+ }
60
+ }
61
+ }
62
+ }`,
63
+ };
64
+ }
65
+
66
+ export function codexMcpSetupSnippet(input: SetupGuideInput = {}): SetupSnippet {
67
+ const { appUrl, agentId } = values(input);
68
+ return {
69
+ id: 'codex-mcp-fields',
70
+ title: 'Codex app MCP server fields',
71
+ description: 'In Codex, open Settings -> MCP servers -> Add server, then fill the fields below. Keep API_KEY as a secret value from create or rotate key.',
72
+ copyLabel: 'Copy Codex MCP fields',
73
+ code: `Name
74
+ Availsync
75
+
76
+ Command
77
+ npx
78
+
79
+ Arguments
80
+ -y @availsync/mcp@alpha
81
+
82
+ Transport
83
+ stdio
84
+
85
+ Working directory
86
+ Leave empty
87
+
88
+ Environment variables
89
+ AVAILSYNC_API_URL=${appUrl}
90
+ AVAILSYNC_AGENT_ID=${agentId}
91
+ AVAILSYNC_API_KEY=API_KEY`,
92
+ };
93
+ }
94
+
95
+ export function codexMultiAgentMcpSnippet(input: SetupGuideInput = {}): SetupSnippet {
96
+ const { appUrl } = values(input);
97
+ return {
98
+ id: 'codex-multi-agent-mcp',
99
+ title: 'Multiple Codex sessions or roles',
100
+ description: 'Use one MCP server entry per Availsync agent when you want role-specific priorities, for example builder and reviewer. Each role needs its own agent id and one-time API key.',
101
+ copyLabel: 'Copy multi-agent Codex TOML',
102
+ code: `[mcp_servers.availsync_builder]
103
+ command = "cmd"
104
+ args = ["/c", "npx", "-y", "@availsync/mcp@alpha"]
105
+ enabled = true
106
+
107
+ [mcp_servers.availsync_builder.env]
108
+ AVAILSYNC_API_URL = "${appUrl}"
109
+ AVAILSYNC_AGENT_ID = "BUILDER_AGENT_ID"
110
+ AVAILSYNC_API_KEY = "BUILDER_API_KEY"
111
+
112
+ [mcp_servers.availsync_reviewer]
113
+ command = "cmd"
114
+ args = ["/c", "npx", "-y", "@availsync/mcp@alpha"]
115
+ enabled = true
116
+
117
+ [mcp_servers.availsync_reviewer.env]
118
+ AVAILSYNC_API_URL = "${appUrl}"
119
+ AVAILSYNC_AGENT_ID = "REVIEWER_AGENT_ID"
120
+ AVAILSYNC_API_KEY = "REVIEWER_API_KEY"`,
121
+ };
122
+ }
123
+
124
+ export function workGuardrailSnippets(input: SetupGuideInput = {}): SetupSnippet[] {
125
+ const { appUrl, agentId, resourceType, resourceKey, durationMinutes } = values(input);
126
+ return [
127
+ {
128
+ id: 'work-check',
129
+ title: 'Check work slot',
130
+ description: `Call this before a coding agent starts. Default to repo-level scope unless the work stream is independent. ${resourceScopeNote}`,
131
+ copyLabel: 'Copy check curl',
132
+ code: `curl -X POST "${appUrl}/v1/work/check" \\
133
+ -H "Authorization: Bearer API_KEY" \\
134
+ -H "Content-Type: application/json" \\
135
+ -d '{"agent_id":"${agentId}","resource_type":"${resourceType}","resource_key":"${resourceKey}","duration_minutes":${durationMinutes},"reason":"pre-flight coding run"}'`,
136
+ },
137
+ {
138
+ id: 'work-claim',
139
+ title: 'Claim before work',
140
+ description: 'Claim the repo with an idempotency key so retries do not create duplicate active claims.',
141
+ copyLabel: 'Copy claim curl',
142
+ code: `curl -X POST "${appUrl}/v1/work/claim" \\
143
+ -H "Authorization: Bearer API_KEY" \\
144
+ -H "Idempotency-Key: coding-run-${resourceKey.replace(/[^a-zA-Z0-9]/g, '-')}-$(date +%Y%m%d%H)" \\
145
+ -H "Content-Type: application/json" \\
146
+ -d '{"agent_id":"${agentId}","resource_type":"${resourceType}","resource_key":"${resourceKey}","duration_minutes":${durationMinutes},"reason":"coding agent run"}'`,
147
+ },
148
+ {
149
+ id: 'work-extend',
150
+ title: 'Extend while running',
151
+ description: 'Call this before expires_at if the agent is still working.',
152
+ copyLabel: 'Copy extend curl',
153
+ code: `curl -X POST "${appUrl}/v1/work/claims/CLAIM_ID/extend" \\
154
+ -H "Authorization: Bearer API_KEY" \\
155
+ -H "Content-Type: application/json" \\
156
+ -d '{"duration_minutes":45}'`,
157
+ },
158
+ {
159
+ id: 'work-release',
160
+ title: 'Release when done',
161
+ description: 'Always release the claim when the agent finishes or exits cleanly.',
162
+ copyLabel: 'Copy release curl',
163
+ code: `curl -X DELETE "${appUrl}/v1/work/claims/CLAIM_ID" \\
164
+ -H "Authorization: Bearer API_KEY"`,
165
+ },
166
+ ];
167
+ }
168
+
169
+ export function automationGuardrailSnippets(input: SetupGuideInput = {}): SetupSnippet[] {
170
+ const { appUrl, agentId, resourceType, resourceKey, durationMinutes } = values(input);
171
+ const safeKey = resourceKey.replace(/[^a-zA-Z0-9]/g, '-');
172
+ return [
173
+ {
174
+ id: 'automation-shell',
175
+ title: 'Shell guardrail wrapper',
176
+ description: `Use run/start before work and always call run/finish from a trap when a claim was created. ${resourceScopeNote}`,
177
+ copyLabel: 'Copy shell wrapper',
178
+ code: `#!/usr/bin/env bash
179
+ set -euo pipefail
180
+
181
+ API_URL="${appUrl}"
182
+ AGENT_ID="${agentId}"
183
+ RESOURCE_TYPE="${resourceType}"
184
+ RESOURCE_KEY="${resourceKey}"
185
+ IDEMPOTENCY_KEY="automation-${safeKey}-$(date +%Y%m%d%H)"
186
+ CLAIM_ID=""
187
+
188
+ finish_claim() {
189
+ if [ -n "$CLAIM_ID" ]; then
190
+ curl -fsS -X POST "$API_URL/v1/work/run/finish" \\
191
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
192
+ -H "Content-Type: application/json" \\
193
+ -d "{\\"claim_id\\":\\"$CLAIM_ID\\",\\"outcome\\":\\"finished\\"}" >/dev/null || true
194
+ fi
195
+ }
196
+ trap finish_claim EXIT
197
+
198
+ START_RESPONSE=$(curl -fsS -X POST "$API_URL/v1/work/run/start" \\
199
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
200
+ -H "Idempotency-Key: $IDEMPOTENCY_KEY" \\
201
+ -H "Content-Type: application/json" \\
202
+ -d "{\\"agent_id\\":\\"$AGENT_ID\\",\\"resource_type\\":\\"$RESOURCE_TYPE\\",\\"resource_key\\":\\"$RESOURCE_KEY\\",\\"duration_minutes\\":${durationMinutes},\\"reason\\":\\"scheduled coding automation\\"}")
203
+
204
+ ACTION=$(node -e "const r=JSON.parse(process.argv[1]); console.log(r.action)" "$START_RESPONSE")
205
+ if [ "$ACTION" = "skip_run" ]; then
206
+ node -e "const r=JSON.parse(process.argv[1]); console.log(r.reason)" "$START_RESPONSE"
207
+ exit 0
208
+ fi
209
+
210
+ CLAIM_ID=$(node -e "const r=JSON.parse(process.argv[1]); console.log(r.claim.id)" "$START_RESPONSE")
211
+
212
+ # Run the coding agent command here.
213
+ # codex exec "...your task..."
214
+ `,
215
+ },
216
+ {
217
+ id: 'automation-github-actions',
218
+ title: 'GitHub Actions step',
219
+ description: 'Put Availsync secrets in repository or organization secrets and skip cleanly when another agent owns the repo.',
220
+ copyLabel: 'Copy Actions step',
221
+ code: `- name: Start Availsync guarded run
222
+ id: availsync
223
+ env:
224
+ AVAILSYNC_API_KEY: \${{ secrets.AVAILSYNC_API_KEY }}
225
+ run: |
226
+ RESPONSE=$(curl -fsS -X POST "${appUrl}/v1/work/run/start" \\
227
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
228
+ -H "Idempotency-Key: github-\${{ github.run_id }}" \\
229
+ -H "Content-Type: application/json" \\
230
+ -d '{"agent_id":"${agentId}","resource_type":"${resourceType}","resource_key":"${resourceKey}","duration_minutes":${durationMinutes},"reason":"GitHub Actions coding automation"}')
231
+ echo "action=$(node -e 'const r=JSON.parse(process.argv[1]); console.log(r.action)' "$RESPONSE")" >> "$GITHUB_OUTPUT"
232
+ echo "claim_id=$(node -e 'const r=JSON.parse(process.argv[1]); console.log(r.claim?.id || "")' "$RESPONSE")" >> "$GITHUB_OUTPUT"
233
+
234
+ - name: Finish Availsync guarded run
235
+ if: always() && steps.availsync.outputs.claim_id != ''
236
+ env:
237
+ AVAILSYNC_API_KEY: \${{ secrets.AVAILSYNC_API_KEY }}
238
+ run: |
239
+ curl -fsS -X POST "${appUrl}/v1/work/run/finish" \\
240
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
241
+ -H "Content-Type: application/json" \\
242
+ -d '{"claim_id":"\${{ steps.availsync.outputs.claim_id }}","outcome":"finished"}'`,
243
+ },
244
+ {
245
+ id: 'automation-codex-prompt',
246
+ title: 'Codex automation prompt',
247
+ description: 'Use this in a scheduled Codex run so the agent respects the shared repo claim before editing.',
248
+ copyLabel: 'Copy Codex prompt',
249
+ code: `Before changing files, start an Availsync guarded run.
250
+
251
+ Use:
252
+ - API URL: ${appUrl}
253
+ - Agent ID: ${agentId}
254
+ - Resource: ${resourceType}:${resourceKey}
255
+
256
+ Resource scope:
257
+ - Safe default: repo:owner/repo means one active agent can work in the repo.
258
+ - Advanced: project:homepage allows parallel work only when it does not depend on other active project work.
259
+
260
+ Call POST /v1/work/run/start with an Idempotency-Key for this run.
261
+ If action is "skip_run", stop and report the reason.
262
+ If action is "proceed", keep the claim id, extend with /v1/work/run/extend if work continues near expiry, and always call /v1/work/run/finish before ending.`,
263
+ },
264
+ {
265
+ id: 'automation-server-worker',
266
+ title: 'Server worker flow',
267
+ description: 'Use this shape in cron, queue workers, deploy bots, or hosted scheduled jobs.',
268
+ copyLabel: 'Copy worker flow',
269
+ code: `POST ${appUrl}/v1/work/run/start
270
+ Authorization: Bearer API_KEY
271
+ Idempotency-Key: worker-${safeKey}-RUN_ID
272
+
273
+ {
274
+ "agent_id": "${agentId}",
275
+ "resource_type": "${resourceType}",
276
+ "resource_key": "${resourceKey}",
277
+ "duration_minutes": ${durationMinutes},
278
+ "reason": "server-side automation"
279
+ }
280
+
281
+ If action === "skip_run": exit 0 with reason.
282
+ If action === "proceed": run work, call /v1/work/run/extend while active, then /v1/work/run/finish in finally.`,
283
+ },
284
+ ];
285
+ }
286
+
287
+ export function nodeSdkSnippets(input: SetupGuideInput = {}): SetupSnippet[] {
288
+ const { agentId, resourceKey, durationMinutes } = values(input);
289
+ const safeKey = resourceKey.replace(/[^a-zA-Z0-9]/g, '-');
290
+ return [
291
+ {
292
+ id: 'node-sdk-basic',
293
+ title: 'Basic guarded run',
294
+ description: 'Use the SDK helper when your app should run work only after Availsync claims the repo.',
295
+ copyLabel: 'Copy SDK example',
296
+ code: `import { createAvailsyncClient } from '@availsync/node';
297
+
298
+ const availsync = createAvailsyncClient({
299
+ apiKey: process.env.AVAILSYNC_API_KEY!,
300
+ agentId: process.env.AVAILSYNC_AGENT_ID!,
301
+ baseUrl: process.env.AVAILSYNC_API_URL,
302
+ });
303
+
304
+ const result = await availsync.work.withClaim(
305
+ 'repo:${resourceKey}',
306
+ { reason: 'coding-agent run', durationMinutes: ${durationMinutes} },
307
+ async ({ claim, shadow }) => {
308
+ if (shadow.wouldHaveBlocked) {
309
+ console.warn('Observe-only: Availsync would have skipped this run.');
310
+ }
311
+ const extendTimer = claim
312
+ ? setInterval(() => claim.extend({ durationMinutes: ${durationMinutes} }).catch(console.error), (${durationMinutes} - 5) * 60_000)
313
+ : null;
314
+ try {
315
+ await doWork();
316
+ } finally {
317
+ if (extendTimer) clearInterval(extendTimer);
318
+ }
319
+ },
320
+ );
321
+
322
+ if (result.action === 'skip_run') {
323
+ console.log(result.reason);
324
+ }`,
325
+ },
326
+ {
327
+ id: 'node-sdk-codex',
328
+ title: 'Scheduled Codex run',
329
+ description: 'Wrap a scheduled Codex task so it exits cleanly when another agent owns the repo.',
330
+ copyLabel: 'Copy Codex SDK example',
331
+ code: `import { createAvailsyncClient } from '@availsync/node';
332
+ import { spawn } from 'node:child_process';
333
+ import { once } from 'node:events';
334
+
335
+ const availsync = createAvailsyncClient({
336
+ apiKey: process.env.AVAILSYNC_API_KEY!,
337
+ agentId: '${agentId}',
338
+ baseUrl: process.env.AVAILSYNC_API_URL,
339
+ });
340
+
341
+ const result = await availsync.work.withClaim(
342
+ 'repo:${resourceKey}',
343
+ {
344
+ reason: 'scheduled Codex automation',
345
+ durationMinutes: ${durationMinutes},
346
+ idempotencyKey: \`codex-${safeKey}-\${new Date().toISOString().slice(0, 13)}\`,
347
+ },
348
+ async ({ shadow }) => {
349
+ if (shadow.wouldHaveBlocked) {
350
+ console.warn('Observe-only: Availsync would have skipped this Codex run.');
351
+ }
352
+ const child = spawn('codex', ['exec', 'run the scheduled maintenance task'], { stdio: 'inherit' });
353
+ const [code] = await once(child, 'exit');
354
+ if (code !== 0) throw new Error(\`codex exited with \${code}\`);
355
+ },
356
+ );
357
+
358
+ if (result.action === 'skip_run') process.exit(0);`,
359
+ },
360
+ {
361
+ id: 'node-sdk-github-actions',
362
+ title: 'GitHub Actions step',
363
+ description: 'Install the SDK in your automation project and use GitHub run id as the idempotency key.',
364
+ copyLabel: 'Copy Actions SDK step',
365
+ code: `- name: Run guarded agent task
366
+ env:
367
+ AVAILSYNC_API_KEY: \${{ secrets.AVAILSYNC_API_KEY }}
368
+ AVAILSYNC_AGENT_ID: ${agentId}
369
+ AVAILSYNC_API_URL: ${values(input).appUrl}
370
+ run: |
371
+ npm install @availsync/node@alpha
372
+ node ./scripts/guarded-agent-run.mjs
373
+
374
+ # scripts/guarded-agent-run.mjs
375
+ import { createAvailsyncClient } from '@availsync/node';
376
+
377
+ const availsync = createAvailsyncClient({
378
+ apiKey: process.env.AVAILSYNC_API_KEY,
379
+ agentId: process.env.AVAILSYNC_AGENT_ID,
380
+ baseUrl: process.env.AVAILSYNC_API_URL,
381
+ });
382
+
383
+ const result = await availsync.work.withClaim(
384
+ 'repo:${resourceKey}',
385
+ {
386
+ reason: 'GitHub Actions coding automation',
387
+ idempotencyKey: \`github-\${process.env.GITHUB_RUN_ID}\`,
388
+ },
389
+ async ({ claim, shadow }) => {
390
+ if (shadow.wouldHaveBlocked) {
391
+ console.warn('Observe-only: Availsync would have skipped this run.');
392
+ }
393
+ const extendTimer = claim
394
+ ? setInterval(() => claim.extend({ durationMinutes: ${durationMinutes} }).catch(console.error), (${durationMinutes} - 5) * 60_000)
395
+ : null;
396
+ try {
397
+ // Run the coding agent command here.
398
+ } finally {
399
+ if (extendTimer) clearInterval(extendTimer);
400
+ }
401
+ },
402
+ );
403
+
404
+ if (result.action === 'skip_run') process.exit(0);`,
405
+ },
406
+ {
407
+ id: 'node-sdk-manual-extend',
408
+ title: 'Manual long-running flow',
409
+ description: 'Use start, extend, and finish directly when you need more control than withClaim.',
410
+ copyLabel: 'Copy manual SDK flow',
411
+ code: `const started = await availsync.work.start({
412
+ resource: 'repo:${resourceKey}',
413
+ reason: 'long-running agent run',
414
+ durationMinutes: ${durationMinutes},
415
+ idempotencyKey: \`agent-${safeKey}-\${Date.now()}\`,
416
+ });
417
+
418
+ if (started.action === 'skip_run') {
419
+ console.log(started.reason);
420
+ process.exit(0);
421
+ }
422
+
423
+ if (started.shadow_mode && started.would_have_blocked) {
424
+ console.warn('Observe-only: Availsync would have skipped this run.');
425
+ }
426
+
427
+ try {
428
+ if (started.claim) {
429
+ // Extend before expiry while the long-running task is still active.
430
+ await availsync.work.extend(started.claim.id, { durationMinutes: 45 });
431
+ }
432
+ await doWork();
433
+ } finally {
434
+ if (started.claim) {
435
+ await availsync.work.finish(started.claim.id, { outcome: 'finished' });
436
+ }
437
+ }`,
438
+ },
439
+ ];
440
+ }
441
+
442
+ export function openClawSkillSnippet(input: SetupGuideInput = {}): SetupSnippet {
443
+ const { appUrl, agentId, resourceType, resourceKey, durationMinutes } = values(input);
444
+ return {
445
+ id: 'openclaw-skill-md',
446
+ title: 'OpenClaw SKILL.md',
447
+ description: 'Install this as an OpenClaw skill so the agent claims the repo before it edits files.',
448
+ copyLabel: 'Copy SKILL.md',
449
+ code: `---
450
+ name: availsync-guardrail
451
+ description: Use before coding, repo edits, scheduled automations, deploy work, migrations, or other agent work that must not overlap with another agent. Coordinates through Availsync work run endpoints and prevents the agent from touching the same selected resource while another claim is active.
452
+ ---
453
+
454
+ # Availsync Guardrail
455
+
456
+ Use Availsync before changing files, running deploys, editing a repo, or starting long-running project work.
457
+
458
+ ## Required environment
459
+
460
+ - AVAILSYNC_API_URL: ${appUrl}
461
+ - AVAILSYNC_AGENT_ID: ${agentId}
462
+ - AVAILSYNC_API_KEY: runtime secret, never write it into files or chat
463
+ - AVAILSYNC_RESOURCE_TYPE: ${resourceType}
464
+ - AVAILSYNC_RESOURCE_KEY: ${resourceKey}
465
+
466
+ ## Resource scope
467
+
468
+ Use AVAILSYNC_RESOURCE_TYPE=repo and AVAILSYNC_RESOURCE_KEY=owner/repo for maximum safety. That allows only one active agent in the repo.
469
+
470
+ Use project-level resources only for independent work streams. Availsync does not yet infer that project:homepage depends on project:product-catalog.
471
+
472
+ ## Workflow
473
+
474
+ 1. Before making changes, call POST /v1/work/run/start.
475
+ 2. Send Authorization: Bearer $AVAILSYNC_API_KEY and an Idempotency-Key for the current run.
476
+ 3. Include client_name: "openclaw" in the JSON body.
477
+ 4. If response action is "skip_run", stop immediately and report the reason. Do not edit files.
478
+ 5. If response action is "proceed", keep the claim id and do the requested work.
479
+ 6. If work continues near expires_at, call POST /v1/work/run/extend with the claim id.
480
+ 7. Always call POST /v1/work/run/finish before ending, including after errors or no-op runs.
481
+
482
+ ## Start request
483
+
484
+ curl -fsS -X POST "$AVAILSYNC_API_URL/v1/work/run/start" \\
485
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
486
+ -H "Idempotency-Key: openclaw-$(date +%Y%m%d%H%M%S)" \\
487
+ -H "Content-Type: application/json" \\
488
+ -d '{"agent_id":"'$AVAILSYNC_AGENT_ID'","resource_type":"'$AVAILSYNC_RESOURCE_TYPE'","resource_key":"'$AVAILSYNC_RESOURCE_KEY'","duration_minutes":${durationMinutes},"reason":"OpenClaw guarded run","client_name":"openclaw"}'
489
+
490
+ ## Finish request
491
+
492
+ curl -fsS -X POST "$AVAILSYNC_API_URL/v1/work/run/finish" \\
493
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
494
+ -H "Content-Type: application/json" \\
495
+ -d '{"claim_id":"CLAIM_ID","outcome":"finished","client_name":"openclaw"}'
496
+
497
+ ## Failure policy
498
+
499
+ If Availsync is unreachable, authentication fails, or the start response cannot be parsed, stop without editing files. Never continue unguarded.`,
500
+ };
501
+ }
502
+
503
+ export function openClawSetupSnippet(input: SetupGuideInput = {}): SetupSnippet {
504
+ const { appUrl, agentId, resourceType, resourceKey } = values(input);
505
+ return {
506
+ id: 'openclaw-setup',
507
+ title: 'OpenClaw setup',
508
+ description: 'Create the skill folder, paste SKILL.md, and keep secrets in environment variables.',
509
+ copyLabel: 'Copy OpenClaw setup',
510
+ code: `mkdir -p ~/.openclaw/skills/availsync-guardrail
511
+ $EDITOR ~/.openclaw/skills/availsync-guardrail/SKILL.md
512
+
513
+ export AVAILSYNC_API_URL="${appUrl}"
514
+ export AVAILSYNC_AGENT_ID="${agentId}"
515
+ export AVAILSYNC_API_KEY="API_KEY"
516
+ export AVAILSYNC_RESOURCE_TYPE="${resourceType}"
517
+ export AVAILSYNC_RESOURCE_KEY="${resourceKey}"
518
+
519
+ # Resource scope:
520
+ # - repo + owner/repo is the safest default: one active agent per repo.
521
+ # - project + homepage allows parallel work only when streams are independent.
522
+ # - Availsync does not yet infer dependencies between different resources.
523
+
524
+ # Test after installing:
525
+ # 1. Ask OpenClaw to use Availsync before editing this repo.
526
+ # 2. Confirm Activity shows client "openclaw".
527
+ # 3. Confirm blocked runs stop with skip_run instead of editing files.`,
528
+ };
529
+ }
530
+
531
+ export function schedulingSnippets(input: SetupGuideInput = {}): SetupSnippet[] {
532
+ const { appUrl, agentId } = values(input);
533
+ return [
534
+ {
535
+ id: 'availability-check',
536
+ title: 'Check availability',
537
+ description: 'Ask Availsync for open slots before touching a calendar or downstream booking tool.',
538
+ copyLabel: 'Copy availability curl',
539
+ code: `curl "${appUrl}/v1/availability?agent_id=${agentId}&from=NEXT_BUSINESS_DAY_START&to=NEXT_BUSINESS_DAY_END&duration_minutes=30" \\
540
+ -H "Authorization: Bearer API_KEY"`,
541
+ },
542
+ {
543
+ id: 'conflict-preview',
544
+ title: 'Preview conflict',
545
+ description: 'Preview the decision and explanation before creating a hold.',
546
+ copyLabel: 'Copy preview curl',
547
+ code: `curl -X POST "${appUrl}/v1/conflicts/check" \\
548
+ -H "Authorization: Bearer API_KEY" \\
549
+ -H "Content-Type: application/json" \\
550
+ -d '{"agent_id":"${agentId}","start_at":"NEXT_BUSINESS_DAY_START","end_at":"NEXT_BUSINESS_DAY_SLOT_END","reason":"demo booking"}'`,
551
+ },
552
+ {
553
+ id: 'hold-create',
554
+ title: 'Create hold',
555
+ description: 'Create a hold only after availability and conflict preview pass.',
556
+ copyLabel: 'Copy hold curl',
557
+ code: `curl -X POST "${appUrl}/v1/holds" \\
558
+ -H "Authorization: Bearer API_KEY" \\
559
+ -H "Content-Type: application/json" \\
560
+ -d '{"agent_id":"${agentId}","start_at":"NEXT_BUSINESS_DAY_START","end_at":"NEXT_BUSINESS_DAY_SLOT_END","reason":"demo booking"}'`,
561
+ },
562
+ ];
563
+ }
564
+
565
+ export function codexPromptSnippet(input: SetupGuideInput = {}): SetupSnippet {
566
+ const { agentId, resourceKey } = values(input);
567
+ return {
568
+ id: 'codex-prompt',
569
+ title: 'Codex automation prompt',
570
+ description: 'Paste this into a scheduled coding-agent run so it respects Availsync before editing.',
571
+ copyLabel: 'Copy prompt',
572
+ code: `Before changing files, use Availsync.
573
+
574
+ Agent id: ${agentId}
575
+ Protected repo: ${resourceKey}
576
+
577
+ Resource scope:
578
+ - Safe default: claim repo:${resourceKey} so only one active agent can work in the repo.
579
+ - Advanced: use project-level resources only when work streams are independent.
580
+
581
+ 1. Call check_work_slot for ${resourceKey}.
582
+ 2. If the response is would_lose or blocked, stop and report the blocking claim.
583
+ 3. If available or would_win, call claim_work_slot with an idempotency key for this run.
584
+ 4. While working, extend_work_slot before expires_at if more time is needed.
585
+ 5. Release the claim when finished, even if no code changes were made.`,
586
+ };
587
+ }
588
+
589
+ export function serverCronSnippet(input: SetupGuideInput = {}): SetupSnippet {
590
+ const { appUrl, agentId, resourceType, resourceKey, durationMinutes } = values(input);
591
+ return {
592
+ id: 'server-cron',
593
+ title: 'Server or cron pre-flight',
594
+ description: 'Use run/start in scheduled jobs so blocked runs skip cleanly instead of failing the job.',
595
+ copyLabel: 'Copy script',
596
+ code: `#!/usr/bin/env bash
597
+ set -euo pipefail
598
+
599
+ API_URL="${appUrl}"
600
+ AGENT_ID="${agentId}"
601
+ RESOURCE_TYPE="${resourceType}"
602
+ RESOURCE_KEY="${resourceKey}"
603
+
604
+ curl -fsS -X POST "$API_URL/v1/work/run/start" \\
605
+ -H "Authorization: Bearer $AVAILSYNC_API_KEY" \\
606
+ -H "Idempotency-Key: cron-${resourceKey.replace(/[^a-zA-Z0-9]/g, '-')}-$(date +%Y%m%d%H)" \\
607
+ -H "Content-Type: application/json" \\
608
+ -d "{\\"agent_id\\":\\"$AGENT_ID\\",\\"resource_type\\":\\"$RESOURCE_TYPE\\",\\"resource_key\\":\\"$RESOURCE_KEY\\",\\"duration_minutes\\":${durationMinutes}}"`,
609
+ };
610
+ }
611
+
612
+ export function quickstartUseCases() {
613
+ return [
614
+ {
615
+ title: 'Stop two coding agents from working on the same repo',
616
+ body:
617
+ 'Each agent checks and claims owner/repo before it starts. If another claim is active, the next run skips with a clear reason instead of touching the same files.',
618
+ },
619
+ {
620
+ title: 'Coordinate server automations before they run',
621
+ body:
622
+ 'Deploys, migrations, review passes, cron jobs, and cleanup scripts can use the same repo claims as coding agents.',
623
+ },
624
+ {
625
+ title: 'Also coordinate scheduling tools before they book',
626
+ body:
627
+ 'Scheduling agents can check availability, preview conflicts, create holds, and release them through the same priority and audit layer.',
628
+ },
629
+ ];
630
+ }
@@ -0,0 +1,30 @@
1
+ export type StoredSession = {
2
+ orgId: string;
3
+ userId: string;
4
+ email: string;
5
+ };
6
+
7
+ const KEY = 'availsync_session';
8
+
9
+ export function saveSession(session: StoredSession): void {
10
+ if (typeof window === 'undefined') return;
11
+ window.localStorage.setItem(KEY, JSON.stringify(session));
12
+ }
13
+
14
+ export function loadSession(): StoredSession | null {
15
+ if (typeof window === 'undefined') return null;
16
+ const raw = window.localStorage.getItem(KEY);
17
+ if (!raw) return null;
18
+ try {
19
+ const parsed = JSON.parse(raw) as Partial<StoredSession>;
20
+ if (!parsed.orgId || !parsed.userId || !parsed.email) return null;
21
+ return parsed as StoredSession;
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+
27
+ export function clearSession(): void {
28
+ if (typeof window === 'undefined') return;
29
+ window.localStorage.removeItem(KEY);
30
+ }
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ /// <reference path="./.next/types/routes.d.ts" />
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -0,0 +1,13 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+
4
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
+
6
+ /** @type {import('next').NextConfig} */
7
+ const nextConfig = {
8
+ output: 'standalone',
9
+ outputFileTracingRoot: __dirname,
10
+ devIndicators: false,
11
+ };
12
+
13
+ export default nextConfig;