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.
- package/.adal/skills/stripe-best-practices/SKILL.md +42 -0
- package/.adal/skills/stripe-best-practices/references/billing.md +36 -0
- package/.adal/skills/stripe-best-practices/references/connect.md +48 -0
- package/.adal/skills/stripe-best-practices/references/payments.md +79 -0
- package/.adal/skills/stripe-best-practices/references/security.md +109 -0
- package/.adal/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.adal/skills/stripe-projects/SKILL.md +139 -0
- package/.adal/skills/upgrade-stripe/SKILL.md +185 -0
- package/.agents/skills/stripe-best-practices/SKILL.md +42 -0
- package/.agents/skills/stripe-best-practices/references/billing.md +36 -0
- package/.agents/skills/stripe-best-practices/references/connect.md +48 -0
- package/.agents/skills/stripe-best-practices/references/payments.md +79 -0
- package/.agents/skills/stripe-best-practices/references/security.md +109 -0
- package/.agents/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.agents/skills/stripe-projects/SKILL.md +139 -0
- package/.agents/skills/upgrade-stripe/SKILL.md +185 -0
- package/.augment/skills/stripe-best-practices/SKILL.md +42 -0
- package/.augment/skills/stripe-best-practices/references/billing.md +36 -0
- package/.augment/skills/stripe-best-practices/references/connect.md +48 -0
- package/.augment/skills/stripe-best-practices/references/payments.md +79 -0
- package/.augment/skills/stripe-best-practices/references/security.md +109 -0
- package/.augment/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.augment/skills/stripe-projects/SKILL.md +139 -0
- package/.augment/skills/upgrade-stripe/SKILL.md +185 -0
- package/.bob/skills/stripe-best-practices/SKILL.md +42 -0
- package/.bob/skills/stripe-best-practices/references/billing.md +36 -0
- package/.bob/skills/stripe-best-practices/references/connect.md +48 -0
- package/.bob/skills/stripe-best-practices/references/payments.md +79 -0
- package/.bob/skills/stripe-best-practices/references/security.md +109 -0
- package/.bob/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.bob/skills/stripe-projects/SKILL.md +139 -0
- package/.bob/skills/upgrade-stripe/SKILL.md +185 -0
- package/.claude/settings.local.json +7 -0
- package/.claude/skills/stripe-best-practices/SKILL.md +42 -0
- package/.claude/skills/stripe-best-practices/references/billing.md +36 -0
- package/.claude/skills/stripe-best-practices/references/connect.md +48 -0
- package/.claude/skills/stripe-best-practices/references/payments.md +79 -0
- package/.claude/skills/stripe-best-practices/references/security.md +109 -0
- package/.claude/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.claude/skills/stripe-projects/SKILL.md +139 -0
- package/.claude/skills/upgrade-stripe/SKILL.md +185 -0
- package/.codebuddy/skills/stripe-best-practices/SKILL.md +42 -0
- package/.codebuddy/skills/stripe-best-practices/references/billing.md +36 -0
- package/.codebuddy/skills/stripe-best-practices/references/connect.md +48 -0
- package/.codebuddy/skills/stripe-best-practices/references/payments.md +79 -0
- package/.codebuddy/skills/stripe-best-practices/references/security.md +109 -0
- package/.codebuddy/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.codebuddy/skills/stripe-projects/SKILL.md +139 -0
- package/.codebuddy/skills/upgrade-stripe/SKILL.md +185 -0
- package/.commandcode/skills/stripe-best-practices/SKILL.md +42 -0
- package/.commandcode/skills/stripe-best-practices/references/billing.md +36 -0
- package/.commandcode/skills/stripe-best-practices/references/connect.md +48 -0
- package/.commandcode/skills/stripe-best-practices/references/payments.md +79 -0
- package/.commandcode/skills/stripe-best-practices/references/security.md +109 -0
- package/.commandcode/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.commandcode/skills/stripe-projects/SKILL.md +139 -0
- package/.commandcode/skills/upgrade-stripe/SKILL.md +185 -0
- package/.continue/skills/stripe-best-practices/SKILL.md +42 -0
- package/.continue/skills/stripe-best-practices/references/billing.md +36 -0
- package/.continue/skills/stripe-best-practices/references/connect.md +48 -0
- package/.continue/skills/stripe-best-practices/references/payments.md +79 -0
- package/.continue/skills/stripe-best-practices/references/security.md +109 -0
- package/.continue/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.continue/skills/stripe-projects/SKILL.md +139 -0
- package/.continue/skills/upgrade-stripe/SKILL.md +185 -0
- package/.cortex/skills/stripe-best-practices/SKILL.md +42 -0
- package/.cortex/skills/stripe-best-practices/references/billing.md +36 -0
- package/.cortex/skills/stripe-best-practices/references/connect.md +48 -0
- package/.cortex/skills/stripe-best-practices/references/payments.md +79 -0
- package/.cortex/skills/stripe-best-practices/references/security.md +109 -0
- package/.cortex/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.cortex/skills/stripe-projects/SKILL.md +139 -0
- package/.cortex/skills/upgrade-stripe/SKILL.md +185 -0
- package/.crush/skills/stripe-best-practices/SKILL.md +42 -0
- package/.crush/skills/stripe-best-practices/references/billing.md +36 -0
- package/.crush/skills/stripe-best-practices/references/connect.md +48 -0
- package/.crush/skills/stripe-best-practices/references/payments.md +79 -0
- package/.crush/skills/stripe-best-practices/references/security.md +109 -0
- package/.crush/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.crush/skills/stripe-projects/SKILL.md +139 -0
- package/.crush/skills/upgrade-stripe/SKILL.md +185 -0
- package/.env.example +20 -0
- package/.factory/skills/stripe-best-practices/SKILL.md +42 -0
- package/.factory/skills/stripe-best-practices/references/billing.md +36 -0
- package/.factory/skills/stripe-best-practices/references/connect.md +48 -0
- package/.factory/skills/stripe-best-practices/references/payments.md +79 -0
- package/.factory/skills/stripe-best-practices/references/security.md +109 -0
- package/.factory/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.factory/skills/stripe-projects/SKILL.md +139 -0
- package/.factory/skills/upgrade-stripe/SKILL.md +185 -0
- package/.goose/skills/stripe-best-practices/SKILL.md +42 -0
- package/.goose/skills/stripe-best-practices/references/billing.md +36 -0
- package/.goose/skills/stripe-best-practices/references/connect.md +48 -0
- package/.goose/skills/stripe-best-practices/references/payments.md +79 -0
- package/.goose/skills/stripe-best-practices/references/security.md +109 -0
- package/.goose/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.goose/skills/stripe-projects/SKILL.md +139 -0
- package/.goose/skills/upgrade-stripe/SKILL.md +185 -0
- package/.iflow/skills/stripe-best-practices/SKILL.md +42 -0
- package/.iflow/skills/stripe-best-practices/references/billing.md +36 -0
- package/.iflow/skills/stripe-best-practices/references/connect.md +48 -0
- package/.iflow/skills/stripe-best-practices/references/payments.md +79 -0
- package/.iflow/skills/stripe-best-practices/references/security.md +109 -0
- package/.iflow/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.iflow/skills/stripe-projects/SKILL.md +139 -0
- package/.iflow/skills/upgrade-stripe/SKILL.md +185 -0
- package/.junie/skills/stripe-best-practices/SKILL.md +42 -0
- package/.junie/skills/stripe-best-practices/references/billing.md +36 -0
- package/.junie/skills/stripe-best-practices/references/connect.md +48 -0
- package/.junie/skills/stripe-best-practices/references/payments.md +79 -0
- package/.junie/skills/stripe-best-practices/references/security.md +109 -0
- package/.junie/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.junie/skills/stripe-projects/SKILL.md +139 -0
- package/.junie/skills/upgrade-stripe/SKILL.md +185 -0
- package/.kilocode/skills/stripe-best-practices/SKILL.md +42 -0
- package/.kilocode/skills/stripe-best-practices/references/billing.md +36 -0
- package/.kilocode/skills/stripe-best-practices/references/connect.md +48 -0
- package/.kilocode/skills/stripe-best-practices/references/payments.md +79 -0
- package/.kilocode/skills/stripe-best-practices/references/security.md +109 -0
- package/.kilocode/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.kilocode/skills/stripe-projects/SKILL.md +139 -0
- package/.kilocode/skills/upgrade-stripe/SKILL.md +185 -0
- package/.kiro/skills/stripe-best-practices/SKILL.md +42 -0
- package/.kiro/skills/stripe-best-practices/references/billing.md +36 -0
- package/.kiro/skills/stripe-best-practices/references/connect.md +48 -0
- package/.kiro/skills/stripe-best-practices/references/payments.md +79 -0
- package/.kiro/skills/stripe-best-practices/references/security.md +109 -0
- package/.kiro/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.kiro/skills/stripe-projects/SKILL.md +139 -0
- package/.kiro/skills/upgrade-stripe/SKILL.md +185 -0
- package/.kode/skills/stripe-best-practices/SKILL.md +42 -0
- package/.kode/skills/stripe-best-practices/references/billing.md +36 -0
- package/.kode/skills/stripe-best-practices/references/connect.md +48 -0
- package/.kode/skills/stripe-best-practices/references/payments.md +79 -0
- package/.kode/skills/stripe-best-practices/references/security.md +109 -0
- package/.kode/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.kode/skills/stripe-projects/SKILL.md +139 -0
- package/.kode/skills/upgrade-stripe/SKILL.md +185 -0
- package/.mcpjam/skills/stripe-best-practices/SKILL.md +42 -0
- package/.mcpjam/skills/stripe-best-practices/references/billing.md +36 -0
- package/.mcpjam/skills/stripe-best-practices/references/connect.md +48 -0
- package/.mcpjam/skills/stripe-best-practices/references/payments.md +79 -0
- package/.mcpjam/skills/stripe-best-practices/references/security.md +109 -0
- package/.mcpjam/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.mcpjam/skills/stripe-projects/SKILL.md +139 -0
- package/.mcpjam/skills/upgrade-stripe/SKILL.md +185 -0
- package/.mux/skills/stripe-best-practices/SKILL.md +42 -0
- package/.mux/skills/stripe-best-practices/references/billing.md +36 -0
- package/.mux/skills/stripe-best-practices/references/connect.md +48 -0
- package/.mux/skills/stripe-best-practices/references/payments.md +79 -0
- package/.mux/skills/stripe-best-practices/references/security.md +109 -0
- package/.mux/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.mux/skills/stripe-projects/SKILL.md +139 -0
- package/.mux/skills/upgrade-stripe/SKILL.md +185 -0
- package/.neovate/skills/stripe-best-practices/SKILL.md +42 -0
- package/.neovate/skills/stripe-best-practices/references/billing.md +36 -0
- package/.neovate/skills/stripe-best-practices/references/connect.md +48 -0
- package/.neovate/skills/stripe-best-practices/references/payments.md +79 -0
- package/.neovate/skills/stripe-best-practices/references/security.md +109 -0
- package/.neovate/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.neovate/skills/stripe-projects/SKILL.md +139 -0
- package/.neovate/skills/upgrade-stripe/SKILL.md +185 -0
- package/.nixpacksignore +14 -0
- package/.openhands/skills/stripe-best-practices/SKILL.md +42 -0
- package/.openhands/skills/stripe-best-practices/references/billing.md +36 -0
- package/.openhands/skills/stripe-best-practices/references/connect.md +48 -0
- package/.openhands/skills/stripe-best-practices/references/payments.md +79 -0
- package/.openhands/skills/stripe-best-practices/references/security.md +109 -0
- package/.openhands/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.openhands/skills/stripe-projects/SKILL.md +139 -0
- package/.openhands/skills/upgrade-stripe/SKILL.md +185 -0
- package/.pi/skills/stripe-best-practices/SKILL.md +42 -0
- package/.pi/skills/stripe-best-practices/references/billing.md +36 -0
- package/.pi/skills/stripe-best-practices/references/connect.md +48 -0
- package/.pi/skills/stripe-best-practices/references/payments.md +79 -0
- package/.pi/skills/stripe-best-practices/references/security.md +109 -0
- package/.pi/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.pi/skills/stripe-projects/SKILL.md +139 -0
- package/.pi/skills/upgrade-stripe/SKILL.md +185 -0
- package/.pochi/skills/stripe-best-practices/SKILL.md +42 -0
- package/.pochi/skills/stripe-best-practices/references/billing.md +36 -0
- package/.pochi/skills/stripe-best-practices/references/connect.md +48 -0
- package/.pochi/skills/stripe-best-practices/references/payments.md +79 -0
- package/.pochi/skills/stripe-best-practices/references/security.md +109 -0
- package/.pochi/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.pochi/skills/stripe-projects/SKILL.md +139 -0
- package/.pochi/skills/upgrade-stripe/SKILL.md +185 -0
- package/.qoder/skills/stripe-best-practices/SKILL.md +42 -0
- package/.qoder/skills/stripe-best-practices/references/billing.md +36 -0
- package/.qoder/skills/stripe-best-practices/references/connect.md +48 -0
- package/.qoder/skills/stripe-best-practices/references/payments.md +79 -0
- package/.qoder/skills/stripe-best-practices/references/security.md +109 -0
- package/.qoder/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.qoder/skills/stripe-projects/SKILL.md +139 -0
- package/.qoder/skills/upgrade-stripe/SKILL.md +185 -0
- package/.qwen/skills/stripe-best-practices/SKILL.md +42 -0
- package/.qwen/skills/stripe-best-practices/references/billing.md +36 -0
- package/.qwen/skills/stripe-best-practices/references/connect.md +48 -0
- package/.qwen/skills/stripe-best-practices/references/payments.md +79 -0
- package/.qwen/skills/stripe-best-practices/references/security.md +109 -0
- package/.qwen/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.qwen/skills/stripe-projects/SKILL.md +139 -0
- package/.qwen/skills/upgrade-stripe/SKILL.md +185 -0
- package/.roo/skills/stripe-best-practices/SKILL.md +42 -0
- package/.roo/skills/stripe-best-practices/references/billing.md +36 -0
- package/.roo/skills/stripe-best-practices/references/connect.md +48 -0
- package/.roo/skills/stripe-best-practices/references/payments.md +79 -0
- package/.roo/skills/stripe-best-practices/references/security.md +109 -0
- package/.roo/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.roo/skills/stripe-projects/SKILL.md +139 -0
- package/.roo/skills/upgrade-stripe/SKILL.md +185 -0
- package/.trae/skills/stripe-best-practices/SKILL.md +42 -0
- package/.trae/skills/stripe-best-practices/references/billing.md +36 -0
- package/.trae/skills/stripe-best-practices/references/connect.md +48 -0
- package/.trae/skills/stripe-best-practices/references/payments.md +79 -0
- package/.trae/skills/stripe-best-practices/references/security.md +109 -0
- package/.trae/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.trae/skills/stripe-projects/SKILL.md +139 -0
- package/.trae/skills/upgrade-stripe/SKILL.md +185 -0
- package/.vibe/skills/stripe-best-practices/SKILL.md +42 -0
- package/.vibe/skills/stripe-best-practices/references/billing.md +36 -0
- package/.vibe/skills/stripe-best-practices/references/connect.md +48 -0
- package/.vibe/skills/stripe-best-practices/references/payments.md +79 -0
- package/.vibe/skills/stripe-best-practices/references/security.md +109 -0
- package/.vibe/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.vibe/skills/stripe-projects/SKILL.md +139 -0
- package/.vibe/skills/upgrade-stripe/SKILL.md +185 -0
- package/.windsurf/skills/stripe-best-practices/SKILL.md +42 -0
- package/.windsurf/skills/stripe-best-practices/references/billing.md +36 -0
- package/.windsurf/skills/stripe-best-practices/references/connect.md +48 -0
- package/.windsurf/skills/stripe-best-practices/references/payments.md +79 -0
- package/.windsurf/skills/stripe-best-practices/references/security.md +109 -0
- package/.windsurf/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.windsurf/skills/stripe-projects/SKILL.md +139 -0
- package/.windsurf/skills/upgrade-stripe/SKILL.md +185 -0
- package/.zencoder/skills/stripe-best-practices/SKILL.md +42 -0
- package/.zencoder/skills/stripe-best-practices/references/billing.md +36 -0
- package/.zencoder/skills/stripe-best-practices/references/connect.md +48 -0
- package/.zencoder/skills/stripe-best-practices/references/payments.md +79 -0
- package/.zencoder/skills/stripe-best-practices/references/security.md +109 -0
- package/.zencoder/skills/stripe-best-practices/references/treasury.md +16 -0
- package/.zencoder/skills/stripe-projects/SKILL.md +139 -0
- package/.zencoder/skills/upgrade-stripe/SKILL.md +185 -0
- package/AUDIT.md +95 -0
- package/BLOCKERS.md +0 -0
- package/COOLIFY.md +51 -0
- package/MCP_SETUP.md +23 -0
- package/PRODUCTION_CHECKLIST.md +246 -0
- package/README.md +47 -0
- package/ROADMAP.md +91 -0
- package/docs/superpowers/plans/2026-05-11-availsync-frontend-sales-flow.md +2445 -0
- package/frontend/.env.example +2 -0
- package/frontend/app/admin/layout.tsx +13 -0
- package/frontend/app/admin/page.tsx +747 -0
- package/frontend/app/app/activity/page.tsx +257 -0
- package/frontend/app/app/agents/[agentId]/page.tsx +21 -0
- package/frontend/app/app/agents/page.tsx +1155 -0
- package/frontend/app/app/audit/page.tsx +225 -0
- package/frontend/app/app/availability/page.tsx +840 -0
- package/frontend/app/app/holds/page.tsx +262 -0
- package/frontend/app/app/layout.tsx +19 -0
- package/frontend/app/app/onboarding/page.tsx +10 -0
- package/frontend/app/app/onboarding/verify/page.tsx +309 -0
- package/frontend/app/app/page.tsx +508 -0
- package/frontend/app/app/settings/page.tsx +399 -0
- package/frontend/app/app/work/page.tsx +426 -0
- package/frontend/app/changelog/page.tsx +93 -0
- package/frontend/app/checkout/page.tsx +25 -0
- package/frontend/app/docs/api/page.tsx +157 -0
- package/frontend/app/docs/page.tsx +296 -0
- package/frontend/app/docs/pilot/page.tsx +127 -0
- package/frontend/app/docs/quickstart/page.tsx +318 -0
- package/frontend/app/docs/reliability/page.tsx +78 -0
- package/frontend/app/docs/sdk/node/page.tsx +166 -0
- package/frontend/app/globals.css +57 -0
- package/frontend/app/icon.png +0 -0
- package/frontend/app/layout.tsx +87 -0
- package/frontend/app/login/page.tsx +14 -0
- package/frontend/app/page.tsx +47 -0
- package/frontend/app/pricing/page.tsx +66 -0
- package/frontend/app/privacy/page.tsx +52 -0
- package/frontend/app/robots.ts +26 -0
- package/frontend/app/security/page.tsx +74 -0
- package/frontend/app/signup/page.tsx +14 -0
- package/frontend/app/sitemap.ts +14 -0
- package/frontend/app/terms/page.tsx +51 -0
- package/frontend/components/brand/AvailsyncLogo.tsx +56 -0
- package/frontend/components/checkout/CheckoutClient.tsx +100 -0
- package/frontend/components/dashboard/AgentForm.tsx +59 -0
- package/frontend/components/dashboard/AppShell.tsx +291 -0
- package/frontend/components/dashboard/AvailabilityChecker.tsx +117 -0
- package/frontend/components/dashboard/AvailabilityWindowForm.tsx +40 -0
- package/frontend/components/dashboard/HoldForm.tsx +133 -0
- package/frontend/components/dashboard/MetricCard.tsx +10 -0
- package/frontend/components/login/LoginForm.tsx +95 -0
- package/frontend/components/marketing/AgentCoordinationStory.tsx +1530 -0
- package/frontend/components/marketing/Faq.tsx +41 -0
- package/frontend/components/marketing/Hero.tsx +73 -0
- package/frontend/components/marketing/HowItWorks.tsx +28 -0
- package/frontend/components/marketing/ObserveModeTeaser.tsx +41 -0
- package/frontend/components/marketing/PricingTeaser.tsx +23 -0
- package/frontend/components/marketing/ProblemSolution.tsx +36 -0
- package/frontend/components/marketing/SiteFooter.tsx +59 -0
- package/frontend/components/marketing/SiteHeader.tsx +45 -0
- package/frontend/components/marketing/UseCases.tsx +27 -0
- package/frontend/components/onboarding/OnboardingClient.tsx +278 -0
- package/frontend/components/pricing/PricingCards.tsx +65 -0
- package/frontend/components/privacy/CookieConsent.tsx +230 -0
- package/frontend/components/privacy/CookieSettingsButton.tsx +15 -0
- package/frontend/components/seo/JsonLd.tsx +10 -0
- package/frontend/components/signup/SignupForm.tsx +55 -0
- package/frontend/components/ui/Badge.tsx +23 -0
- package/frontend/components/ui/Button.tsx +37 -0
- package/frontend/components/ui/Card.tsx +11 -0
- package/frontend/components/ui/ConfirmDialog.tsx +77 -0
- package/frontend/components/ui/EmptyState.tsx +24 -0
- package/frontend/components/ui/Input.tsx +14 -0
- package/frontend/components/ui/KeyDisplay.tsx +49 -0
- package/frontend/components/ui/Select.tsx +14 -0
- package/frontend/components/ui/Skeleton.tsx +24 -0
- package/frontend/components/ui/Tabs.tsx +19 -0
- package/frontend/components/ui/Textarea.tsx +14 -0
- package/frontend/components/ui/Toast.tsx +78 -0
- package/frontend/components/waitlist/WaitlistDialog.tsx +128 -0
- package/frontend/lib/api.ts +1282 -0
- package/frontend/lib/billing.ts +6 -0
- package/frontend/lib/cookieConsent.ts +113 -0
- package/frontend/lib/format.ts +16 -0
- package/frontend/lib/plans.ts +62 -0
- package/frontend/lib/schemas.ts +108 -0
- package/frontend/lib/seo.ts +376 -0
- package/frontend/lib/setupGuides.ts +630 -0
- package/frontend/lib/storage.ts +30 -0
- package/frontend/next-env.d.ts +6 -0
- package/frontend/next.config.mjs +13 -0
- package/frontend/package-lock.json +14409 -0
- package/frontend/package.json +41 -0
- package/frontend/playwright.config.ts +20 -0
- package/frontend/postcss.config.mjs +8 -0
- package/frontend/public/.gitkeep +0 -0
- package/frontend/public/brand/availsync-logo-board.png +0 -0
- package/frontend/public/brand/availsync-logo-dark.png +0 -0
- package/frontend/public/brand/availsync-mark-dark.png +0 -0
- package/frontend/public/brand/availsync-wordmark-dark.png +0 -0
- package/frontend/public/marketing/hero-agent-coordination.png +0 -0
- package/frontend/tailwind.config.ts +53 -0
- package/frontend/tests/smoke.spec.ts +89 -0
- package/frontend/tsconfig.json +23 -0
- package/jest.config.js +7 -0
- package/nixpacks.toml +11 -0
- package/package.json +53 -0
- package/packages/mcp/LICENSE +21 -0
- package/packages/mcp/README.md +60 -0
- package/packages/mcp/jest.config.cjs +8 -0
- package/packages/mcp/package.json +54 -0
- package/packages/mcp/src/helpers.ts +38 -0
- package/packages/mcp/src/index.test.ts +60 -0
- package/packages/mcp/src/index.ts +387 -0
- package/packages/mcp/tsconfig.json +20 -0
- package/packages/mcp/tsconfig.test.json +12 -0
- package/packages/node/LICENSE +21 -0
- package/packages/node/README.md +120 -0
- package/packages/node/jest.config.cjs +8 -0
- package/packages/node/package.json +46 -0
- package/packages/node/src/index.test.ts +360 -0
- package/packages/node/src/index.ts +402 -0
- package/packages/node/tsconfig.json +20 -0
- package/packages/node/tsconfig.test.json +12 -0
- package/plan.md +923 -0
- package/skills/stripe-best-practices/SKILL.md +42 -0
- package/skills/stripe-best-practices/references/billing.md +36 -0
- package/skills/stripe-best-practices/references/connect.md +48 -0
- package/skills/stripe-best-practices/references/payments.md +79 -0
- package/skills/stripe-best-practices/references/security.md +109 -0
- package/skills/stripe-best-practices/references/treasury.md +16 -0
- package/skills/stripe-projects/SKILL.md +139 -0
- package/skills/upgrade-stripe/SKILL.md +185 -0
- package/skills-lock.json +20 -0
- package/src/core/availability.ts +178 -0
- package/src/core/conflict.ts +209 -0
- package/src/core/work.ts +490 -0
- package/src/db/client.ts +17 -0
- package/src/db/migrations/001_init.sql +88 -0
- package/src/db/migrations/002_stripe.sql +2 -0
- package/src/db/migrations/003_workspace_auth.sql +19 -0
- package/src/db/migrations/004_agent_mcp_status.sql +2 -0
- package/src/db/migrations/005_hold_event_actor.sql +4 -0
- package/src/db/migrations/006_agent_activity.sql +35 -0
- package/src/db/migrations/007_work_coordination.sql +60 -0
- package/src/db/migrations/008_work_claim_leases.sql +20 -0
- package/src/db/migrations/009_billing_subscription_state.sql +23 -0
- package/src/db/migrations/010_agent_api_key_prefix.sql +10 -0
- package/src/db/migrations/011_org_verified_and_work_event_retention.sql +11 -0
- package/src/db/migrations/012_agent_enforcement_mode.sql +12 -0
- package/src/db/migrations/013_support_tickets.sql +21 -0
- package/src/db/migrations/014_paid_plan_waitlist.sql +23 -0
- package/src/db/migrations/015_agent_last_seen.sql +2 -0
- package/src/db/migrations.ts +164 -0
- package/src/db/run-migrations.ts +13 -0
- package/src/index.ts +183 -0
- package/src/lib/activity.ts +137 -0
- package/src/lib/apiKeys.ts +32 -0
- package/src/lib/appInfo.ts +26 -0
- package/src/lib/billingConfig.ts +3 -0
- package/src/lib/env.ts +75 -0
- package/src/lib/logger.ts +8 -0
- package/src/lib/plans.ts +204 -0
- package/src/mcp/server.js +5 -0
- package/src/mcp/server.ts +350 -0
- package/src/middleware/auth.ts +342 -0
- package/src/middleware/requestId.ts +16 -0
- package/src/routes/account.ts +168 -0
- package/src/routes/activity.ts +126 -0
- package/src/routes/admin.ts +514 -0
- package/src/routes/audit.ts +68 -0
- package/src/routes/auth.ts +203 -0
- package/src/routes/availability.ts +325 -0
- package/src/routes/billing.ts +406 -0
- package/src/routes/conflicts.ts +131 -0
- package/src/routes/holds.ts +437 -0
- package/src/routes/mcp.ts +57 -0
- package/src/routes/metrics.ts +39 -0
- package/src/routes/onboarding.ts +273 -0
- package/src/routes/orgs.ts +981 -0
- package/src/routes/preferences.ts +132 -0
- package/src/routes/session.ts +16 -0
- package/src/routes/support.ts +77 -0
- package/src/routes/value.ts +186 -0
- package/src/routes/waitlist.ts +63 -0
- package/src/routes/work.ts +1578 -0
- package/src/server.ts +36 -0
- package/src/types/index.ts +109 -0
- package/tests/integration/activity.route.test.ts +103 -0
- package/tests/integration/admin.route.test.ts +143 -0
- package/tests/integration/agent-keys.route.test.ts +237 -0
- package/tests/integration/availability.route.test.ts +125 -0
- package/tests/integration/billing.route.test.ts +393 -0
- package/tests/integration/conflicts.route.test.ts +131 -0
- package/tests/integration/flows.test.ts +154 -0
- package/tests/integration/helpers.ts +134 -0
- package/tests/integration/holds.route.test.ts +185 -0
- package/tests/integration/metrics.route.test.ts +100 -0
- package/tests/integration/onboarding.verify.route.test.ts +163 -0
- package/tests/integration/preferences.route.test.ts +53 -0
- package/tests/integration/session.route.test.ts +97 -0
- package/tests/integration/system.route.test.ts +92 -0
- package/tests/integration/value.route.test.ts +235 -0
- package/tests/integration/work.route.test.ts +745 -0
- package/tests/setup.ts +4 -0
- package/tests/smoke.sh +62 -0
- package/tests/unit/auth.test.ts +114 -0
- package/tests/unit/availability.test.ts +149 -0
- package/tests/unit/conflict.test.ts +118 -0
- package/tests/unit/env.test.ts +69 -0
- package/tests/unit/migrations.test.ts +135 -0
- package/tests/unit/request-id.test.ts +37 -0
- package/tmp-mobile-agents.png +0 -0
- package/tmp-next-mobile.err.log +10 -0
- package/tmp-next-mobile.log +5 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "availsync-frontend",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": "22.x"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "next dev -p 3001",
|
|
10
|
+
"build": "next build",
|
|
11
|
+
"start": "node scripts/start-next.mjs",
|
|
12
|
+
"lint": "next lint",
|
|
13
|
+
"test:e2e": "playwright test"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@lobehub/icons": "^5.8.0",
|
|
17
|
+
"@tanstack/react-query": "^5.90.0",
|
|
18
|
+
"clsx": "^2.1.1",
|
|
19
|
+
"framer-motion": "^11.18.2",
|
|
20
|
+
"geist": "^1.7.0",
|
|
21
|
+
"lucide-react": "^0.468.0",
|
|
22
|
+
"next": "^15.0.0",
|
|
23
|
+
"react": "^19.0.0",
|
|
24
|
+
"react-dom": "^19.0.0",
|
|
25
|
+
"react-hook-form": "^7.53.0",
|
|
26
|
+
"tailwind-merge": "^2.5.4",
|
|
27
|
+
"zod": "^4.4.3"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@playwright/test": "^1.49.0",
|
|
31
|
+
"@types/node": "^22.0.0",
|
|
32
|
+
"@types/react": "^19.0.0",
|
|
33
|
+
"@types/react-dom": "^19.0.0",
|
|
34
|
+
"autoprefixer": "^10.4.20",
|
|
35
|
+
"eslint": "^9.0.0",
|
|
36
|
+
"eslint-config-next": "^15.0.0",
|
|
37
|
+
"postcss": "^8.4.49",
|
|
38
|
+
"tailwindcss": "^3.4.17",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './tests',
|
|
5
|
+
timeout: 30_000,
|
|
6
|
+
webServer: {
|
|
7
|
+
command: 'npm run dev',
|
|
8
|
+
url: 'http://localhost:3001',
|
|
9
|
+
reuseExistingServer: true,
|
|
10
|
+
timeout: 120_000,
|
|
11
|
+
},
|
|
12
|
+
use: {
|
|
13
|
+
baseURL: 'http://localhost:3001',
|
|
14
|
+
trace: 'on-first-retry',
|
|
15
|
+
},
|
|
16
|
+
projects: [
|
|
17
|
+
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
18
|
+
{ name: 'mobile', use: { ...devices['Pixel 5'] } },
|
|
19
|
+
],
|
|
20
|
+
});
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Config } from 'tailwindcss';
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}', './lib/**/*.{ts,tsx}'],
|
|
5
|
+
theme: {
|
|
6
|
+
extend: {
|
|
7
|
+
colors: {
|
|
8
|
+
// Linear-style dark palette
|
|
9
|
+
bg: '#0F0F0F',
|
|
10
|
+
surface: '#161616',
|
|
11
|
+
'surface-raised': '#1C1C1C',
|
|
12
|
+
border: '#2A2A2A',
|
|
13
|
+
'border-focus': '#3D3D3D',
|
|
14
|
+
'text-primary': '#F2F2F2',
|
|
15
|
+
'text-secondary': '#A0A0A0',
|
|
16
|
+
'text-tertiary': '#5C5C5C',
|
|
17
|
+
accent: '#5E6AD2',
|
|
18
|
+
'accent-hover': '#6B75DB',
|
|
19
|
+
success: '#4CAF50',
|
|
20
|
+
warning: '#E8B84B',
|
|
21
|
+
error: '#E55353',
|
|
22
|
+
// Keep old colors for marketing pages
|
|
23
|
+
ink: '#101418',
|
|
24
|
+
paper: '#f7f5ef',
|
|
25
|
+
line: '#d8d2c4',
|
|
26
|
+
moss: '#556b4e',
|
|
27
|
+
rust: '#b75c2b',
|
|
28
|
+
blue: '#315f8a',
|
|
29
|
+
},
|
|
30
|
+
fontFamily: {
|
|
31
|
+
sans: ['var(--font-geist-sans)', 'system-ui', 'sans-serif'],
|
|
32
|
+
mono: ['var(--font-geist-mono)', 'Menlo', 'monospace'],
|
|
33
|
+
},
|
|
34
|
+
fontSize: {
|
|
35
|
+
'label': ['11px', { lineHeight: '16px', letterSpacing: '0.04em' }],
|
|
36
|
+
'body': ['13px', { lineHeight: '20px' }],
|
|
37
|
+
'heading': ['15px', { lineHeight: '22px', letterSpacing: '0' }],
|
|
38
|
+
'title': ['20px', { lineHeight: '28px', letterSpacing: '0' }],
|
|
39
|
+
},
|
|
40
|
+
boxShadow: {
|
|
41
|
+
panel: '0 16px 48px rgba(16, 20, 24, 0.10)',
|
|
42
|
+
},
|
|
43
|
+
spacing: {
|
|
44
|
+
'4.5': '18px',
|
|
45
|
+
'7.5': '30px',
|
|
46
|
+
'9': '36px',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
plugins: [],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default config;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test('buyer can understand product and start onboarding', async ({ page }) => {
|
|
4
|
+
await page.goto('/');
|
|
5
|
+
await expect(
|
|
6
|
+
page.getByRole('heading', { name: /one scheduling source of truth/i }),
|
|
7
|
+
).toBeVisible();
|
|
8
|
+
await page.getByRole('link', { name: /start free/i }).first().click();
|
|
9
|
+
await expect(
|
|
10
|
+
page.getByRole('heading', { name: /create your availsync workspace/i }),
|
|
11
|
+
).toBeVisible();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('pricing shows all plans', async ({ page }) => {
|
|
15
|
+
await page.goto('/pricing');
|
|
16
|
+
await expect(page.getByText('Free', { exact: true })).toBeVisible();
|
|
17
|
+
await expect(page.getByText('Individual', { exact: true })).toBeVisible();
|
|
18
|
+
await expect(page.getByText('Team', { exact: true })).toBeVisible();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('docs quickstart includes API commands', async ({ page }) => {
|
|
22
|
+
await page.goto('/docs/quickstart');
|
|
23
|
+
await expect(page.getByRole('heading', { name: 'Create org' })).toBeVisible();
|
|
24
|
+
await expect(page.getByRole('heading', { name: 'Check availability' })).toBeVisible();
|
|
25
|
+
await expect(page.getByRole('heading', { name: 'Book hold' })).toBeVisible();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('buyer can create workspace, check availability, and manage a hold', async ({ page }) => {
|
|
29
|
+
const localInputValue = (date: Date) => {
|
|
30
|
+
const offsetDate = new Date(date.getTime() - date.getTimezoneOffset() * 60_000);
|
|
31
|
+
return offsetDate.toISOString().slice(0, 16);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const windowStart = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
|
35
|
+
windowStart.setHours(9, 0, 0, 0);
|
|
36
|
+
const availabilityEnd = new Date(windowStart);
|
|
37
|
+
availabilityEnd.setHours(11, 0, 0, 0);
|
|
38
|
+
const holdEnd = new Date(windowStart);
|
|
39
|
+
holdEnd.setMinutes(holdEnd.getMinutes() + 30);
|
|
40
|
+
|
|
41
|
+
await page.goto('/signup');
|
|
42
|
+
await page.getByLabel('Organization name').fill(`AvailSync E2E ${Date.now()}`);
|
|
43
|
+
await page.getByRole('button', { name: 'Create organization' }).click();
|
|
44
|
+
|
|
45
|
+
await expect(page.getByRole('heading', { name: /create your first ai agent/i })).toBeVisible();
|
|
46
|
+
await page.getByRole('button', { name: 'Create agent and window' }).click();
|
|
47
|
+
await expect(page.getByText('Copy this API key now')).toBeVisible();
|
|
48
|
+
|
|
49
|
+
const session = await page.evaluate(() => {
|
|
50
|
+
const session = window.localStorage.getItem('availsync_session');
|
|
51
|
+
return session ? JSON.parse(session) : null;
|
|
52
|
+
});
|
|
53
|
+
expect(session?.orgId).toBeTruthy();
|
|
54
|
+
expect(session?.apiKey).toBeTruthy();
|
|
55
|
+
const orgId = session.orgId;
|
|
56
|
+
|
|
57
|
+
await page.evaluate(() => window.localStorage.removeItem('availsync_session'));
|
|
58
|
+
await page.goto('/login');
|
|
59
|
+
await page.getByLabel('Agent API key').fill(session.apiKey);
|
|
60
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
61
|
+
await expect(page.getByText('Connected')).toBeVisible();
|
|
62
|
+
|
|
63
|
+
await page.goto('/app');
|
|
64
|
+
await page.getByRole('link', { name: 'Upgrade', exact: true }).click();
|
|
65
|
+
await expect(page.getByRole('heading', { name: /simple pricing/i })).toBeVisible();
|
|
66
|
+
await page.goto('/app');
|
|
67
|
+
await expect(page.getByText('Connected')).toBeVisible();
|
|
68
|
+
await page.getByRole('link', { name: 'Upgrade plan' }).click();
|
|
69
|
+
await expect(page.getByRole('heading', { name: /checkout for individual/i })).toBeVisible();
|
|
70
|
+
await expect(page.getByLabel('Organization ID')).toHaveValue(orgId);
|
|
71
|
+
|
|
72
|
+
await page.goto('/app');
|
|
73
|
+
await page.getByRole('link', { name: 'Check availability' }).click();
|
|
74
|
+
await expect(page.getByRole('heading', { name: 'Availability' })).toBeVisible();
|
|
75
|
+
await page.getByLabel('From', { exact: true }).fill(localInputValue(windowStart));
|
|
76
|
+
await page.getByLabel('To', { exact: true }).fill(localInputValue(availabilityEnd));
|
|
77
|
+
await page.getByLabel('Duration minutes', { exact: true }).fill('30');
|
|
78
|
+
await page.getByRole('button', { name: 'Check availability' }).click();
|
|
79
|
+
await expect(page.getByText(/Confidence/).first()).toBeVisible();
|
|
80
|
+
|
|
81
|
+
await page.getByRole('link', { name: 'Holds' }).click();
|
|
82
|
+
await expect(page.getByRole('heading', { name: 'Holds' })).toBeVisible();
|
|
83
|
+
await page.getByLabel('Start', { exact: true }).fill(localInputValue(windowStart));
|
|
84
|
+
await page.getByLabel('End', { exact: true }).fill(localInputValue(holdEnd));
|
|
85
|
+
await page.getByRole('button', { name: 'Create hold' }).click();
|
|
86
|
+
await expect(page.getByRole('button', { name: 'Release' }).first()).toBeVisible();
|
|
87
|
+
await page.getByRole('button', { name: 'Release' }).first().click();
|
|
88
|
+
await expect(page.getByRole('button', { name: 'Release' })).toHaveCount(0);
|
|
89
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "ES2022"],
|
|
5
|
+
"allowJs": false,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
package/jest.config.js
ADDED
package/nixpacks.toml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[variables]
|
|
2
|
+
NIXPACKS_NODE_VERSION = "22"
|
|
3
|
+
|
|
4
|
+
[phases.install]
|
|
5
|
+
cmds = ["npm ci --include=dev", "npm ci --prefix frontend --include=dev"]
|
|
6
|
+
|
|
7
|
+
[phases.build]
|
|
8
|
+
cmds = ["npm run build", "npm prune --omit=dev", "npm prune --prefix frontend --omit=dev"]
|
|
9
|
+
|
|
10
|
+
[start]
|
|
11
|
+
cmd = "npm run start"
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "availsync",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": "22.x"
|
|
6
|
+
},
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc && npm run build --prefix frontend",
|
|
9
|
+
"build:api": "tsc",
|
|
10
|
+
"build:frontend": "npm run build --prefix frontend",
|
|
11
|
+
"build:sdk": "npm run build --prefix packages/node",
|
|
12
|
+
"build:mcp": "npm run build --prefix packages/mcp",
|
|
13
|
+
"start": "node dist/server.js",
|
|
14
|
+
"dev": "ts-node-dev --respawn src/index.ts",
|
|
15
|
+
"test": "jest --runInBand",
|
|
16
|
+
"test:sdk": "npm run test --prefix packages/node",
|
|
17
|
+
"test:mcp": "npm run test --prefix packages/mcp",
|
|
18
|
+
"typecheck:sdk": "npm run typecheck --prefix packages/node",
|
|
19
|
+
"migrate": "ts-node src/db/run-migrations.ts",
|
|
20
|
+
"lint": "eslint src --ext .ts",
|
|
21
|
+
"mcp": "ts-node src/mcp/server.ts"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
25
|
+
"bcrypt": "^6.0.0",
|
|
26
|
+
"cors": "^2.8.6",
|
|
27
|
+
"date-fns": "^4.1.0",
|
|
28
|
+
"express": "^4.22.1",
|
|
29
|
+
"express-rate-limit": "^8.5.1",
|
|
30
|
+
"helmet": "^8.1.0",
|
|
31
|
+
"pg": "^8.20.0",
|
|
32
|
+
"stripe": "^22.1.1",
|
|
33
|
+
"uuid": "^14.0.0",
|
|
34
|
+
"zod": "^4.4.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/bcrypt": "^6.0.0",
|
|
38
|
+
"@types/cors": "^2.8.19",
|
|
39
|
+
"@types/express": "^4.17.25",
|
|
40
|
+
"@types/jest": "^30.0.0",
|
|
41
|
+
"@types/pg": "^8.20.0",
|
|
42
|
+
"@types/supertest": "^7.2.0",
|
|
43
|
+
"@types/uuid": "^10.0.0",
|
|
44
|
+
"eslint": "^10.3.0",
|
|
45
|
+
"jest": "^30.4.2",
|
|
46
|
+
"prettier": "^3.8.3",
|
|
47
|
+
"supertest": "^7.2.2",
|
|
48
|
+
"ts-jest": "^29.4.9",
|
|
49
|
+
"ts-node": "^10.9.2",
|
|
50
|
+
"ts-node-dev": "^2.0.0",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Availsync
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @availsync/mcp
|
|
2
|
+
|
|
3
|
+
MCP server for Availsync. Use it with Claude Desktop, Cursor, or another stdio MCP client so an agent can check availability, preview conflicts, claim a repo/project, extend a live claim, and release it when finished.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Use the explicit alpha tag during the pilot:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y @availsync/mcp@alpha --help
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Claude or Cursor config
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"availsync": {
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["-y", "@availsync/mcp@alpha"],
|
|
21
|
+
"env": {
|
|
22
|
+
"AVAILSYNC_API_URL": "https://availsync.dev",
|
|
23
|
+
"AVAILSYNC_AGENT_ID": "AGENT_ID",
|
|
24
|
+
"AVAILSYNC_API_KEY": "API_KEY"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Environment
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
AVAILSYNC_API_URL=https://availsync.dev
|
|
35
|
+
AVAILSYNC_AGENT_ID=AGENT_ID
|
|
36
|
+
AVAILSYNC_API_KEY=API_KEY
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`AVAILSYNC_API_KEY` is a runtime secret. Keep it in your MCP/client secret store or environment, not in prompts, repos, or browser-visible code.
|
|
40
|
+
|
|
41
|
+
`AVAILSYNC_AGENT_ID` is used as the default agent for tools. You may still pass `agent_id` in a tool call to override it. If neither is present, the MCP tool returns a clear configuration error without exposing secrets.
|
|
42
|
+
|
|
43
|
+
## Tools
|
|
44
|
+
|
|
45
|
+
- `check_work_slot`
|
|
46
|
+
- `claim_work_slot` uses `/v1/work/run/start` and returns `proceed` or `skip_run`.
|
|
47
|
+
- `extend_work_slot` uses `/v1/work/run/extend`.
|
|
48
|
+
- `release_work_slot` uses `/v1/work/run/finish`.
|
|
49
|
+
- `check_availability`
|
|
50
|
+
- `preview_conflict`
|
|
51
|
+
- `book_slot`
|
|
52
|
+
- `release_slot`
|
|
53
|
+
|
|
54
|
+
Recommended pilot and production-like flow for coding agents:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
heartbeat -> check_work_slot -> claim_work_slot -> extend_work_slot while working -> release_work_slot
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If Availsync is unavailable in enforce mode, stop the agent run instead of editing files unguarded. In observe mode, `claim_work_slot` can proceed without creating a lease and include shadow metadata about what would have been blocked.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@availsync/mcp",
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
|
+
"description": "MCP server for Availsync coding-agent and scheduling guardrails.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"homepage": "https://availsync.dev/docs/quickstart",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"availsync",
|
|
27
|
+
"mcp",
|
|
28
|
+
"claude",
|
|
29
|
+
"cursor",
|
|
30
|
+
"ai-agents",
|
|
31
|
+
"coding-agents",
|
|
32
|
+
"guardrails",
|
|
33
|
+
"repo-locks"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"tag": "alpha"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"prepack": "npm run build",
|
|
45
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"start": "node dist/index.js",
|
|
47
|
+
"test": "jest --config jest.config.cjs --runInBand",
|
|
48
|
+
"test:help": "npm run build && node dist/index.js --help"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
|
+
"zod": "^4.4.3"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function configuredAgentId(): string | null {
|
|
2
|
+
return process.env.AVAILSYNC_AGENT_ID?.trim() || null;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function requireAgentId(inputAgentId?: string): string {
|
|
6
|
+
const agentId = inputAgentId ?? configuredAgentId();
|
|
7
|
+
if (!agentId) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
'agent_id is required. Pass agent_id in the tool call or set AVAILSYNC_AGENT_ID in the MCP server environment.',
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return agentId;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function idempotencyHeaders(idempotencyKey?: string): Record<string, string> {
|
|
16
|
+
return idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function parseResponseBody(text: string, response: Response): unknown {
|
|
20
|
+
if (!text) return {};
|
|
21
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
22
|
+
if (!contentType.includes('application/json')) {
|
|
23
|
+
return {
|
|
24
|
+
error: 'non_json_response',
|
|
25
|
+
status: response.status,
|
|
26
|
+
body_preview: text.slice(0, 300),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(text) as unknown;
|
|
31
|
+
} catch {
|
|
32
|
+
return {
|
|
33
|
+
error: 'invalid_json_response',
|
|
34
|
+
status: response.status,
|
|
35
|
+
body_preview: text.slice(0, 300),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { idempotencyHeaders, parseResponseBody, requireAgentId } from './helpers';
|
|
2
|
+
|
|
3
|
+
describe('MCP configuration helpers', () => {
|
|
4
|
+
const previousAgentId = process.env.AVAILSYNC_AGENT_ID;
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
if (previousAgentId == null) {
|
|
8
|
+
delete process.env.AVAILSYNC_AGENT_ID;
|
|
9
|
+
} else {
|
|
10
|
+
process.env.AVAILSYNC_AGENT_ID = previousAgentId;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('defaults agent id from AVAILSYNC_AGENT_ID', () => {
|
|
15
|
+
process.env.AVAILSYNC_AGENT_ID = '11111111-1111-4111-8111-111111111111';
|
|
16
|
+
|
|
17
|
+
expect(requireAgentId()).toBe('11111111-1111-4111-8111-111111111111');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('tool input agent id overrides env default', () => {
|
|
21
|
+
process.env.AVAILSYNC_AGENT_ID = '11111111-1111-4111-8111-111111111111';
|
|
22
|
+
|
|
23
|
+
expect(requireAgentId('22222222-2222-4222-8222-222222222222')).toBe('22222222-2222-4222-8222-222222222222');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('missing agent id produces a clear setup error', () => {
|
|
27
|
+
delete process.env.AVAILSYNC_AGENT_ID;
|
|
28
|
+
|
|
29
|
+
expect(() => requireAgentId()).toThrow('agent_id is required');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('idempotency header is omitted unless explicitly supplied', () => {
|
|
33
|
+
expect(idempotencyHeaders()).toEqual({});
|
|
34
|
+
expect(idempotencyHeaders('run-123')).toEqual({ 'Idempotency-Key': 'run-123' });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('MCP upstream response parsing', () => {
|
|
39
|
+
test('returns non_json_response with safe preview', () => {
|
|
40
|
+
const response = new Response('<html>bad gateway with secretless body</html>', {
|
|
41
|
+
status: 502,
|
|
42
|
+
headers: { 'content-type': 'text/html' },
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(parseResponseBody('<html>bad gateway with secretless body</html>', response)).toEqual({
|
|
46
|
+
error: 'non_json_response',
|
|
47
|
+
status: 502,
|
|
48
|
+
body_preview: '<html>bad gateway with secretless body</html>',
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('parses JSON responses', () => {
|
|
53
|
+
const response = new Response('{"ok":true}', {
|
|
54
|
+
status: 200,
|
|
55
|
+
headers: { 'content-type': 'application/json' },
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
expect(parseResponseBody('{"ok":true}', response)).toEqual({ ok: true });
|
|
59
|
+
});
|
|
60
|
+
});
|