vibecarbon 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 (495) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +188 -0
  3. package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
  4. package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
  5. package/carbon/.claude/settings.json +29 -0
  6. package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
  7. package/carbon/.dockerignore +57 -0
  8. package/carbon/.env.example +219 -0
  9. package/carbon/.github/copilot-instructions.md +3 -0
  10. package/carbon/.github/workflows/deploy.yml +346 -0
  11. package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
  12. package/carbon/.windsurfrules +74 -0
  13. package/carbon/AGENTS.md +422 -0
  14. package/carbon/CLAUDE.md +3 -0
  15. package/carbon/DEVELOPMENT.md +187 -0
  16. package/carbon/Dockerfile +98 -0
  17. package/carbon/LICENSE +21 -0
  18. package/carbon/PRODUCTION.md +364 -0
  19. package/carbon/README.md +193 -0
  20. package/carbon/TESTING.md +138 -0
  21. package/carbon/backup/Dockerfile +75 -0
  22. package/carbon/backup/backup.sh +95 -0
  23. package/carbon/backup/compose-backup.sh +140 -0
  24. package/carbon/biome.json +83 -0
  25. package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
  26. package/carbon/cloud-init/k3s/master-init.sh +215 -0
  27. package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
  28. package/carbon/cloud-init/k3s/worker-init.sh +147 -0
  29. package/carbon/components.json +24 -0
  30. package/carbon/content/blog/authentication-guide.mdx +34 -0
  31. package/carbon/content/blog/getting-started.mdx +41 -0
  32. package/carbon/content/changelog/v0-1-0.mdx +40 -0
  33. package/carbon/content/docs/analytics.mdx +90 -0
  34. package/carbon/content/docs/authentication.mdx +231 -0
  35. package/carbon/content/docs/background-jobs.mdx +116 -0
  36. package/carbon/content/docs/cli.mdx +630 -0
  37. package/carbon/content/docs/database.mdx +236 -0
  38. package/carbon/content/docs/deployment.mdx +227 -0
  39. package/carbon/content/docs/development.mdx +238 -0
  40. package/carbon/content/docs/environments.mdx +84 -0
  41. package/carbon/content/docs/getting-started.mdx +112 -0
  42. package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
  43. package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
  44. package/carbon/content/docs/optional-services.mdx +160 -0
  45. package/carbon/db/Dockerfile +23 -0
  46. package/carbon/docker-compose.dev-init.yml +5 -0
  47. package/carbon/docker-compose.metabase.override.yml +14 -0
  48. package/carbon/docker-compose.metabase.prod.yml +28 -0
  49. package/carbon/docker-compose.metabase.yml +84 -0
  50. package/carbon/docker-compose.n8n.override.yml +14 -0
  51. package/carbon/docker-compose.n8n.prod.yml +31 -0
  52. package/carbon/docker-compose.n8n.yml +97 -0
  53. package/carbon/docker-compose.observability.override.yml +18 -0
  54. package/carbon/docker-compose.observability.prod.yml +28 -0
  55. package/carbon/docker-compose.observability.yml +125 -0
  56. package/carbon/docker-compose.override.yml +28 -0
  57. package/carbon/docker-compose.prod.yml +294 -0
  58. package/carbon/docker-compose.yml +508 -0
  59. package/carbon/docker-entrypoint.sh +12 -0
  60. package/carbon/ha/activate-standby.sh +52 -0
  61. package/carbon/ha/primary-init.sql +36 -0
  62. package/carbon/ha/standby-init.sh +74 -0
  63. package/carbon/k8s/LICENSE +99 -0
  64. package/carbon/k8s/README.md +272 -0
  65. package/carbon/k8s/base/app/deployment.yaml +130 -0
  66. package/carbon/k8s/base/app/hpa.yaml +44 -0
  67. package/carbon/k8s/base/app/kustomization.yaml +10 -0
  68. package/carbon/k8s/base/app/network-policy.yaml +124 -0
  69. package/carbon/k8s/base/app/pdb.yaml +14 -0
  70. package/carbon/k8s/base/app/rbac.yaml +36 -0
  71. package/carbon/k8s/base/app/service.yaml +16 -0
  72. package/carbon/k8s/base/backup/cronjob.yaml +120 -0
  73. package/carbon/k8s/base/backup/kustomization.yaml +7 -0
  74. package/carbon/k8s/base/backup/network-policy.yaml +31 -0
  75. package/carbon/k8s/base/backup/rbac.yaml +7 -0
  76. package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
  77. package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
  78. package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
  79. package/carbon/k8s/base/config/configmap.yaml +48 -0
  80. package/carbon/k8s/base/config/kustomization.yaml +8 -0
  81. package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
  82. package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
  83. package/carbon/k8s/base/kustomization.yaml +43 -0
  84. package/carbon/k8s/base/namespace.yaml +7 -0
  85. package/carbon/k8s/base/network-policies.yaml +95 -0
  86. package/carbon/k8s/base/registry/kustomization.yaml +5 -0
  87. package/carbon/k8s/base/registry/local-registry.yaml +193 -0
  88. package/carbon/k8s/base/traefik/certificate.yaml +21 -0
  89. package/carbon/k8s/base/traefik/configmap.yaml +13 -0
  90. package/carbon/k8s/base/traefik/deployment.yaml +165 -0
  91. package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
  92. package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
  93. package/carbon/k8s/base/traefik/middleware.yaml +109 -0
  94. package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
  95. package/carbon/k8s/base/traefik/service.yaml +38 -0
  96. package/carbon/k8s/flux/README.md +49 -0
  97. package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
  98. package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
  99. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
  100. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
  101. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
  102. package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
  103. package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
  104. package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
  105. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
  106. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
  107. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
  108. package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
  109. package/carbon/k8s/infra/kustomization.yaml +21 -0
  110. package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
  111. package/carbon/k8s/overlays/local/configmap.yaml +23 -0
  112. package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
  113. package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
  114. package/carbon/k8s/overlays/local/namespace.yaml +8 -0
  115. package/carbon/k8s/overlays/local/secrets.yaml +32 -0
  116. package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
  117. package/carbon/k8s/test-local.sh +318 -0
  118. package/carbon/k8s/values/supabase.values.yaml +133 -0
  119. package/carbon/package.json +154 -0
  120. package/carbon/runtime.Dockerfile +17 -0
  121. package/carbon/scripts/_dev-jwt.mjs +45 -0
  122. package/carbon/scripts/check-rls.ts +53 -0
  123. package/carbon/scripts/dev-init.js +191 -0
  124. package/carbon/scripts/dev.js +191 -0
  125. package/carbon/scripts/docker-down.js +63 -0
  126. package/carbon/scripts/docker-logs.js +59 -0
  127. package/carbon/scripts/docker-up.js +222 -0
  128. package/carbon/scripts/generate-dev-configs.sh +131 -0
  129. package/carbon/scripts/generate-rss.ts +116 -0
  130. package/carbon/scripts/generate-sitemap.ts +102 -0
  131. package/carbon/scripts/k8s-apply.js +71 -0
  132. package/carbon/scripts/k8s-delete.js +75 -0
  133. package/carbon/scripts/lib/manifest.js +176 -0
  134. package/carbon/scripts/secret-scan.mjs +278 -0
  135. package/carbon/scripts/validate-dev-configs.sh +101 -0
  136. package/carbon/src/client/App.tsx +202 -0
  137. package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
  138. package/carbon/src/client/assets/hyperformant-light.svg +29 -0
  139. package/carbon/src/client/assets/logos/aider.svg +1 -0
  140. package/carbon/src/client/assets/logos/antigravity.svg +1 -0
  141. package/carbon/src/client/assets/logos/bolt.svg +1 -0
  142. package/carbon/src/client/assets/logos/claude-code.svg +1 -0
  143. package/carbon/src/client/assets/logos/copilot.svg +1 -0
  144. package/carbon/src/client/assets/logos/cursor.svg +1 -0
  145. package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
  146. package/carbon/src/client/assets/logos/lovable.svg +1 -0
  147. package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
  148. package/carbon/src/client/assets/logos/v0.svg +1 -0
  149. package/carbon/src/client/assets/logos/windsurf.svg +1 -0
  150. package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
  151. package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
  152. package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
  153. package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
  154. package/carbon/src/client/components/AppSidebar.tsx +760 -0
  155. package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
  156. package/carbon/src/client/components/CTAFooter.tsx +59 -0
  157. package/carbon/src/client/components/ComparisonSection.tsx +132 -0
  158. package/carbon/src/client/components/ContentPanel.tsx +66 -0
  159. package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
  160. package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
  161. package/carbon/src/client/components/FAQSection.tsx +76 -0
  162. package/carbon/src/client/components/FileUpload.tsx +210 -0
  163. package/carbon/src/client/components/HeaderActions.tsx +17 -0
  164. package/carbon/src/client/components/Hero.tsx +608 -0
  165. package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
  166. package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
  167. package/carbon/src/client/components/Logo.tsx +87 -0
  168. package/carbon/src/client/components/LogoStrip.tsx +76 -0
  169. package/carbon/src/client/components/MetricsStrip.tsx +48 -0
  170. package/carbon/src/client/components/Nav.tsx +195 -0
  171. package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
  172. package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
  173. package/carbon/src/client/components/PageHeader.tsx +24 -0
  174. package/carbon/src/client/components/PlanGate.tsx +36 -0
  175. package/carbon/src/client/components/PricingSection.tsx +371 -0
  176. package/carbon/src/client/components/SEO.tsx +34 -0
  177. package/carbon/src/client/components/SmoothScroll.tsx +45 -0
  178. package/carbon/src/client/components/TechStackSection.tsx +165 -0
  179. package/carbon/src/client/components/WorkflowSection.tsx +604 -0
  180. package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
  181. package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
  182. package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
  183. package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
  184. package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
  185. package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
  186. package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
  187. package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
  188. package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
  189. package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
  190. package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
  191. package/carbon/src/client/components/effects/index.ts +2 -0
  192. package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
  193. package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
  194. package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
  195. package/carbon/src/client/components/scroll/index.ts +2 -0
  196. package/carbon/src/client/components/ui/accordion.tsx +71 -0
  197. package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
  198. package/carbon/src/client/components/ui/alert.tsx +73 -0
  199. package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
  200. package/carbon/src/client/components/ui/avatar.tsx +91 -0
  201. package/carbon/src/client/components/ui/badge.tsx +50 -0
  202. package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
  203. package/carbon/src/client/components/ui/button-group.tsx +78 -0
  204. package/carbon/src/client/components/ui/button.tsx +120 -0
  205. package/carbon/src/client/components/ui/calendar.tsx +182 -0
  206. package/carbon/src/client/components/ui/card.tsx +85 -0
  207. package/carbon/src/client/components/ui/carousel.tsx +227 -0
  208. package/carbon/src/client/components/ui/chart.tsx +357 -0
  209. package/carbon/src/client/components/ui/checkbox.tsx +27 -0
  210. package/carbon/src/client/components/ui/collapsible.tsx +15 -0
  211. package/carbon/src/client/components/ui/command.tsx +178 -0
  212. package/carbon/src/client/components/ui/context-menu.tsx +233 -0
  213. package/carbon/src/client/components/ui/dialog.tsx +132 -0
  214. package/carbon/src/client/components/ui/drawer.tsx +118 -0
  215. package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
  216. package/carbon/src/client/components/ui/empty.tsx +94 -0
  217. package/carbon/src/client/components/ui/field.tsx +226 -0
  218. package/carbon/src/client/components/ui/hover-card.tsx +44 -0
  219. package/carbon/src/client/components/ui/input-group.tsx +146 -0
  220. package/carbon/src/client/components/ui/input-otp.tsx +83 -0
  221. package/carbon/src/client/components/ui/input.tsx +20 -0
  222. package/carbon/src/client/components/ui/item.tsx +188 -0
  223. package/carbon/src/client/components/ui/kbd.tsx +26 -0
  224. package/carbon/src/client/components/ui/label.tsx +21 -0
  225. package/carbon/src/client/components/ui/menubar.tsx +250 -0
  226. package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
  227. package/carbon/src/client/components/ui/pagination.tsx +102 -0
  228. package/carbon/src/client/components/ui/popover.tsx +75 -0
  229. package/carbon/src/client/components/ui/progress.tsx +66 -0
  230. package/carbon/src/client/components/ui/radio-group.tsx +36 -0
  231. package/carbon/src/client/components/ui/resizable.tsx +46 -0
  232. package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
  233. package/carbon/src/client/components/ui/select.tsx +186 -0
  234. package/carbon/src/client/components/ui/separator.tsx +21 -0
  235. package/carbon/src/client/components/ui/sheet.tsx +124 -0
  236. package/carbon/src/client/components/ui/sidebar.tsx +702 -0
  237. package/carbon/src/client/components/ui/skeleton.tsx +13 -0
  238. package/carbon/src/client/components/ui/slider.tsx +57 -0
  239. package/carbon/src/client/components/ui/sonner.tsx +45 -0
  240. package/carbon/src/client/components/ui/spinner.tsx +15 -0
  241. package/carbon/src/client/components/ui/switch.tsx +30 -0
  242. package/carbon/src/client/components/ui/table.tsx +89 -0
  243. package/carbon/src/client/components/ui/tabs.tsx +73 -0
  244. package/carbon/src/client/components/ui/textarea.tsx +18 -0
  245. package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
  246. package/carbon/src/client/components/ui/toggle.tsx +44 -0
  247. package/carbon/src/client/components/ui/tooltip.tsx +56 -0
  248. package/carbon/src/client/hooks/api/index.ts +14 -0
  249. package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
  250. package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
  251. package/carbon/src/client/hooks/use-mobile.ts +21 -0
  252. package/carbon/src/client/hooks/useMousePosition.ts +91 -0
  253. package/carbon/src/client/hooks/useNotifications.tsx +124 -0
  254. package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
  255. package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
  256. package/carbon/src/client/hooks/usePackageManager.ts +69 -0
  257. package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
  258. package/carbon/src/client/hooks/useRunningServices.ts +114 -0
  259. package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
  260. package/carbon/src/client/index.css +467 -0
  261. package/carbon/src/client/index.html +56 -0
  262. package/carbon/src/client/lib/admin-services.ts +151 -0
  263. package/carbon/src/client/lib/api.ts +32 -0
  264. package/carbon/src/client/lib/blog.ts +35 -0
  265. package/carbon/src/client/lib/changelog.ts +33 -0
  266. package/carbon/src/client/lib/docs-search.ts +101 -0
  267. package/carbon/src/client/lib/docs.ts +37 -0
  268. package/carbon/src/client/lib/i18n.ts +32 -0
  269. package/carbon/src/client/lib/supabase.ts +72 -0
  270. package/carbon/src/client/lib/tailwind-colors.ts +357 -0
  271. package/carbon/src/client/lib/theme.ts +117 -0
  272. package/carbon/src/client/lib/utils.ts +22 -0
  273. package/carbon/src/client/locales/de.json +529 -0
  274. package/carbon/src/client/locales/en.json +461 -0
  275. package/carbon/src/client/locales/es.json +529 -0
  276. package/carbon/src/client/locales/fr.json +529 -0
  277. package/carbon/src/client/locales/pt.json +529 -0
  278. package/carbon/src/client/main.tsx +56 -0
  279. package/carbon/src/client/mdx.d.ts +13 -0
  280. package/carbon/src/client/pages/ApiDocs.tsx +76 -0
  281. package/carbon/src/client/pages/AuthCallback.tsx +34 -0
  282. package/carbon/src/client/pages/Blog.tsx +167 -0
  283. package/carbon/src/client/pages/Changelog.tsx +171 -0
  284. package/carbon/src/client/pages/Charts.tsx +388 -0
  285. package/carbon/src/client/pages/Checkout.tsx +227 -0
  286. package/carbon/src/client/pages/Contact.tsx +174 -0
  287. package/carbon/src/client/pages/Dashboard.tsx +368 -0
  288. package/carbon/src/client/pages/Docs.tsx +372 -0
  289. package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
  290. package/carbon/src/client/pages/Home.tsx +187 -0
  291. package/carbon/src/client/pages/Legal.tsx +100 -0
  292. package/carbon/src/client/pages/Login.tsx +408 -0
  293. package/carbon/src/client/pages/MFAVerify.tsx +156 -0
  294. package/carbon/src/client/pages/NotFound.tsx +21 -0
  295. package/carbon/src/client/pages/Onboarding.tsx +246 -0
  296. package/carbon/src/client/pages/ResetPassword.tsx +200 -0
  297. package/carbon/src/client/pages/UIComponents.tsx +390 -0
  298. package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
  299. package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
  300. package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
  301. package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
  302. package/carbon/src/client/pages/admin/Logs.tsx +18 -0
  303. package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
  304. package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
  305. package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
  306. package/carbon/src/client/pages/admin/Settings.tsx +314 -0
  307. package/carbon/src/client/pages/admin/Theme.tsx +465 -0
  308. package/carbon/src/client/pages/admin/Users.tsx +365 -0
  309. package/carbon/src/client/pages/api-docs.css +156 -0
  310. package/carbon/src/client/pages/organizations/Details.tsx +200 -0
  311. package/carbon/src/client/pages/organizations/Members.tsx +402 -0
  312. package/carbon/src/client/pages/settings/Billing.tsx +473 -0
  313. package/carbon/src/client/pages/settings/Profile.tsx +160 -0
  314. package/carbon/src/client/pages/settings/Security.tsx +341 -0
  315. package/carbon/src/client/public/favicon.svg +19 -0
  316. package/carbon/src/client/public/robots.txt +8 -0
  317. package/carbon/src/server/billing/index.ts +104 -0
  318. package/carbon/src/server/billing/provider.ts +81 -0
  319. package/carbon/src/server/billing/providers/paddle.ts +314 -0
  320. package/carbon/src/server/billing/providers/polar.ts +325 -0
  321. package/carbon/src/server/billing/providers/stripe.ts +233 -0
  322. package/carbon/src/server/emails/templates.ts +116 -0
  323. package/carbon/src/server/index.ts +554 -0
  324. package/carbon/src/server/lib/auth.ts +6 -0
  325. package/carbon/src/server/lib/email.ts +64 -0
  326. package/carbon/src/server/lib/env.ts +112 -0
  327. package/carbon/src/server/lib/errors.ts +21 -0
  328. package/carbon/src/server/lib/logger.ts +17 -0
  329. package/carbon/src/server/lib/rate-limiter.ts +288 -0
  330. package/carbon/src/server/lib/request.ts +34 -0
  331. package/carbon/src/server/lib/stripe.ts +42 -0
  332. package/carbon/src/server/lib/supabase.ts +65 -0
  333. package/carbon/src/server/middleware/requirePlan.ts +80 -0
  334. package/carbon/src/server/routes/_internal/services-status.ts +958 -0
  335. package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
  336. package/carbon/src/server/routes/health.ts +48 -0
  337. package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
  338. package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
  339. package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
  340. package/carbon/src/server/routes/v1/auth.ts +390 -0
  341. package/carbon/src/server/routes/v1/billing.ts +718 -0
  342. package/carbon/src/server/routes/v1/contact.ts +93 -0
  343. package/carbon/src/server/routes/v1/index.ts +1333 -0
  344. package/carbon/src/server/routes/v1/newsletter.ts +181 -0
  345. package/carbon/src/server/routes/v1/performance.ts +157 -0
  346. package/carbon/src/server/routes/v1/stats.ts +170 -0
  347. package/carbon/src/server/routes/v1/theme.ts +106 -0
  348. package/carbon/src/server/routes/webhooks/billing.ts +376 -0
  349. package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
  350. package/carbon/src/server/types.ts +11 -0
  351. package/carbon/src/shared/pricing.ts +155 -0
  352. package/carbon/src/shared/types.ts +338 -0
  353. package/carbon/supabase/migrations/00001_init.sql +717 -0
  354. package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
  355. package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
  356. package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
  357. package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
  358. package/carbon/supabase/seed.sql +16 -0
  359. package/carbon/tests/_helpers/app.ts +45 -0
  360. package/carbon/tests/_helpers/env.ts +37 -0
  361. package/carbon/tests/_helpers/factories.ts +69 -0
  362. package/carbon/tests/_helpers/jwt.ts +23 -0
  363. package/carbon/tests/_helpers/setup-integration.ts +20 -0
  364. package/carbon/tests/_helpers/setup-rtl.ts +12 -0
  365. package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
  366. package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
  367. package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
  368. package/carbon/tests/integration/server/routes/health.test.ts +61 -0
  369. package/carbon/tests/structural/i18n-parity.test.ts +42 -0
  370. package/carbon/tests/unit/client/utils.test.ts +49 -0
  371. package/carbon/tests/unit/shared/pricing.test.ts +93 -0
  372. package/carbon/tsconfig.json +27 -0
  373. package/carbon/tsconfig.server.json +27 -0
  374. package/carbon/tsconfig.test.json +9 -0
  375. package/carbon/vite.config.ts +110 -0
  376. package/carbon/vitest.config.ts +74 -0
  377. package/carbon/volumes/db/jwt.sql +57 -0
  378. package/carbon/volumes/db/metabase-init.sh +29 -0
  379. package/carbon/volumes/db/n8n-init.sh +25 -0
  380. package/carbon/volumes/db/realtime.sql +33 -0
  381. package/carbon/volumes/db/roles.sql +93 -0
  382. package/carbon/volumes/db/set-passwords.sh +12 -0
  383. package/carbon/volumes/db/super-admin.dev.sql +113 -0
  384. package/carbon/volumes/db/super-admin.generated.sql +113 -0
  385. package/carbon/volumes/db/super-admin.sql +114 -0
  386. package/carbon/volumes/grafana/dashboards/logs.json +179 -0
  387. package/carbon/volumes/grafana/dashboards/overview.json +523 -0
  388. package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
  389. package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
  390. package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
  391. package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
  392. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
  393. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
  394. package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
  395. package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
  396. package/carbon/volumes/kong/kong.yml +208 -0
  397. package/carbon/volumes/loki/loki-config.yml +58 -0
  398. package/carbon/volumes/n8n/hooks.js +131 -0
  399. package/carbon/volumes/n8n/scripts/setup.sh +66 -0
  400. package/carbon/volumes/prometheus/prometheus.yml +43 -0
  401. package/carbon/volumes/promtail/promtail-config.yml +64 -0
  402. package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
  403. package/carbon/volumes/traefik/middlewares.yml +95 -0
  404. package/carbon/volumes/traefik/vite-dev.yml +20 -0
  405. package/package.json +95 -0
  406. package/src/access.js +354 -0
  407. package/src/activate.js +187 -0
  408. package/src/add.js +718 -0
  409. package/src/backup.js +786 -0
  410. package/src/cli.js +350 -0
  411. package/src/configure.js +967 -0
  412. package/src/console.js +155 -0
  413. package/src/create.js +1499 -0
  414. package/src/deploy.js +311 -0
  415. package/src/destroy.js +2033 -0
  416. package/src/diagnose.js +735 -0
  417. package/src/down.js +80 -0
  418. package/src/failover.js +1032 -0
  419. package/src/lib/backup-s3.js +179 -0
  420. package/src/lib/build.js +33 -0
  421. package/src/lib/checksum.js +28 -0
  422. package/src/lib/ci-setup.js +666 -0
  423. package/src/lib/cli/help.js +129 -0
  424. package/src/lib/cli/parse-flags.js +160 -0
  425. package/src/lib/cli/select-action.js +65 -0
  426. package/src/lib/cli/select-environment.js +108 -0
  427. package/src/lib/cli/tty-guard.js +75 -0
  428. package/src/lib/cloudflare.js +447 -0
  429. package/src/lib/colors.js +52 -0
  430. package/src/lib/command.js +361 -0
  431. package/src/lib/config.js +359 -0
  432. package/src/lib/cost.js +103 -0
  433. package/src/lib/deploy/bundle.js +231 -0
  434. package/src/lib/deploy/compose/acme-verify.js +121 -0
  435. package/src/lib/deploy/compose/build-args.js +78 -0
  436. package/src/lib/deploy/compose/ha.js +1874 -0
  437. package/src/lib/deploy/compose/index.js +1294 -0
  438. package/src/lib/deploy/compose/reconcile.js +74 -0
  439. package/src/lib/deploy/github.js +382 -0
  440. package/src/lib/deploy/image.js +191 -0
  441. package/src/lib/deploy/index.js +119 -0
  442. package/src/lib/deploy/k8s/LICENSE +99 -0
  443. package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
  444. package/src/lib/deploy/k8s/ha/index.js +1000 -0
  445. package/src/lib/deploy/k8s/index.js +62 -0
  446. package/src/lib/deploy/k8s/k3s.js +2515 -0
  447. package/src/lib/deploy/orchestrator.js +1401 -0
  448. package/src/lib/deploy/prompts.js +545 -0
  449. package/src/lib/deploy/remote-build.js +130 -0
  450. package/src/lib/deploy/state.js +120 -0
  451. package/src/lib/deploy/utils.js +328 -0
  452. package/src/lib/deploy-logger.js +93 -0
  453. package/src/lib/dns-propagation.js +48 -0
  454. package/src/lib/environment.js +58 -0
  455. package/src/lib/fetch-retry.js +103 -0
  456. package/src/lib/github-environments.js +335 -0
  457. package/src/lib/hetzner-dns.js +377 -0
  458. package/src/lib/hetzner-guided-setup.js +275 -0
  459. package/src/lib/host-keys.js +37 -0
  460. package/src/lib/iac/cloud-init.js +52 -0
  461. package/src/lib/iac/index.js +325 -0
  462. package/src/lib/iac/programs/hetzner-compose.js +130 -0
  463. package/src/lib/iac/programs/hetzner-k8s.js +320 -0
  464. package/src/lib/kubectl.js +81 -0
  465. package/src/lib/licensing/index.js +259 -0
  466. package/src/lib/licensing/tiers.js +181 -0
  467. package/src/lib/licensing/validator.js +171 -0
  468. package/src/lib/merge-package-json.js +90 -0
  469. package/src/lib/operator-ip.js +381 -0
  470. package/src/lib/package-manager.js +111 -0
  471. package/src/lib/perf.js +71 -0
  472. package/src/lib/project-guard.js +39 -0
  473. package/src/lib/project.js +334 -0
  474. package/src/lib/providers/base.js +276 -0
  475. package/src/lib/providers/hetzner-s3.js +656 -0
  476. package/src/lib/providers/hetzner.js +755 -0
  477. package/src/lib/providers/index.js +164 -0
  478. package/src/lib/s3.js +510 -0
  479. package/src/lib/secret-scan.js +583 -0
  480. package/src/lib/secrets.js +63 -0
  481. package/src/lib/server-types.js +195 -0
  482. package/src/lib/shell.js +91 -0
  483. package/src/lib/ssh.js +241 -0
  484. package/src/lib/tracker.js +242 -0
  485. package/src/lib/upgrade-policy.js +170 -0
  486. package/src/lib/validators.js +105 -0
  487. package/src/lib/version.js +5 -0
  488. package/src/remove.js +292 -0
  489. package/src/reset.js +97 -0
  490. package/src/restore.js +871 -0
  491. package/src/scale.js +1734 -0
  492. package/src/shell.js +222 -0
  493. package/src/status.js +981 -0
  494. package/src/up.js +264 -0
  495. package/src/upgrade.js +721 -0
@@ -0,0 +1,318 @@
1
+ #!/bin/bash
2
+ # Local Kubernetes Testing with k3d
3
+ # Tests the k8s manifests locally before deploying to production
4
+
5
+ set -e
6
+
7
+ # Colors
8
+ RED='\033[0;31m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ NC='\033[0m'
13
+
14
+ CLUSTER_NAME="vibecarbon-local"
15
+ NAMESPACE="vibecarbon"
16
+
17
+ # Get script directory
18
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19
+
20
+ print_step() { echo -e "\n${GREEN}▶ $1${NC}"; }
21
+ print_info() { echo -e "${BLUE}ℹ $1${NC}"; }
22
+ print_warning() { echo -e "${YELLOW}⚠ $1${NC}"; }
23
+ print_error() { echo -e "${RED}✗ $1${NC}"; }
24
+ print_success() { echo -e "${GREEN}✓ $1${NC}"; }
25
+
26
+ check_dependencies() {
27
+ print_step "Checking dependencies..."
28
+
29
+ local missing=()
30
+
31
+ command -v docker &> /dev/null || missing+=("docker")
32
+ command -v kubectl &> /dev/null || missing+=("kubectl")
33
+ command -v k3d &> /dev/null || missing+=("k3d")
34
+
35
+ if [ ${#missing[@]} -ne 0 ]; then
36
+ print_error "Missing dependencies: ${missing[*]}"
37
+ echo ""
38
+ echo "Install instructions:"
39
+ echo ""
40
+ if [[ " ${missing[*]} " =~ " kubectl " ]]; then
41
+ echo " kubectl:"
42
+ echo " curl -LO \"https://dl.k8s.io/release/\$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl\""
43
+ echo " sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl"
44
+ echo ""
45
+ fi
46
+ if [[ " ${missing[*]} " =~ " k3d " ]]; then
47
+ echo " k3d:"
48
+ echo " curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash"
49
+ echo ""
50
+ fi
51
+ exit 1
52
+ fi
53
+
54
+ print_success "All dependencies satisfied"
55
+ }
56
+
57
+ create_cluster() {
58
+ print_step "Creating k3d cluster: ${CLUSTER_NAME}"
59
+
60
+ # Check if cluster exists
61
+ if k3d cluster list | grep -q "${CLUSTER_NAME}"; then
62
+ print_warning "Cluster ${CLUSTER_NAME} already exists"
63
+ read -p "Delete and recreate? (y/N) " -n 1 -r
64
+ echo
65
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
66
+ k3d cluster delete ${CLUSTER_NAME}
67
+ else
68
+ print_info "Using existing cluster"
69
+ return
70
+ fi
71
+ fi
72
+
73
+ # Create cluster with port mappings
74
+ # - 8080:80 for HTTP traffic via Traefik
75
+ # - 8443:443 for HTTPS traffic
76
+ # Note: k3d comes with built-in Traefik, but we deploy our own
77
+ k3d cluster create ${CLUSTER_NAME} \
78
+ --port "8080:80@loadbalancer" \
79
+ --port "8443:443@loadbalancer" \
80
+ --agents 1 \
81
+ --k3s-arg "--disable=traefik@server:0" \
82
+ --wait
83
+
84
+ print_success "Cluster created"
85
+ }
86
+
87
+ install_traefik_crds() {
88
+ print_step "Installing Traefik CRDs..."
89
+
90
+ # Install Traefik CRDs from the official Traefik helm chart
91
+ # These are needed for IngressRoute and Middleware resources
92
+ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.2/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml 2>/dev/null || {
93
+ print_warning "Could not fetch Traefik v3 CRDs, trying v2..."
94
+ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.11/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
95
+ }
96
+
97
+ print_success "Traefik CRDs installed"
98
+ }
99
+
100
+ deploy_manifests() {
101
+ print_step "Deploying Kubernetes manifests..."
102
+
103
+ # Install Traefik CRDs first (since we disabled k3d's built-in Traefik)
104
+ install_traefik_crds
105
+
106
+ # Use the local overlay which:
107
+ # - Sets correct namespace (vibecarbon)
108
+ # - Uses local-path storage class instead of hcloud-volumes
109
+ # - Uses nginx placeholder for app image
110
+ # - Includes secrets and configmap
111
+ # - Reduces replicas for local testing
112
+
113
+ print_info "Applying local overlay..."
114
+
115
+ # Apply the local overlay with kustomize
116
+ # Use kustomize build with load restrictor to allow referencing base manifests
117
+ kubectl kustomize "${SCRIPT_DIR}/overlays/local" --load-restrictor=LoadRestrictionsNone | kubectl apply -f -
118
+
119
+ print_success "Manifests deployed"
120
+ }
121
+
122
+ wait_for_pods() {
123
+ print_step "Waiting for pods to be ready..."
124
+
125
+ local timeout=300
126
+ local start_time=$(date +%s)
127
+
128
+ # First, wait for any pods to appear
129
+ print_info "Waiting for pods to be created..."
130
+ local pod_count=0
131
+ while [ $pod_count -eq 0 ]; do
132
+ local current_time=$(date +%s)
133
+ local elapsed=$((current_time - start_time))
134
+
135
+ if [ $elapsed -gt 60 ]; then
136
+ print_warning "No pods created after 60s, checking all namespaces..."
137
+ kubectl get pods -A
138
+ break
139
+ fi
140
+
141
+ pod_count=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | wc -l)
142
+ if [ $pod_count -eq 0 ]; then
143
+ sleep 2
144
+ fi
145
+ done
146
+
147
+ # Now wait for pods to be ready
148
+ while true; do
149
+ local current_time=$(date +%s)
150
+ local elapsed=$((current_time - start_time))
151
+
152
+ if [ $elapsed -gt $timeout ]; then
153
+ print_error "Timeout waiting for pods"
154
+ echo ""
155
+ echo "Pod Status:"
156
+ kubectl get pods -n ${NAMESPACE} -o wide
157
+ echo ""
158
+ echo "Events:"
159
+ kubectl get events -n ${NAMESPACE} --sort-by='.lastTimestamp' | tail -20
160
+ exit 1
161
+ fi
162
+
163
+ local total=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | wc -l)
164
+ local running=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | grep "Running" | wc -l)
165
+ local pending=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | grep -E "Pending|ContainerCreating|Init" | wc -l)
166
+ local failed=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | grep -E "Error|CrashLoopBackOff|ImagePullBackOff|CreateContainerConfigError" | wc -l)
167
+
168
+ if [ "$total" -gt 0 ] && [ "$running" -eq "$total" ]; then
169
+ print_success "All ${total} pods ready"
170
+ break
171
+ fi
172
+
173
+ if [ "$failed" -gt 0 ]; then
174
+ print_warning "${failed} pods have errors (will continue waiting...)"
175
+ fi
176
+
177
+ print_info "Pods: ${running}/${total} running, ${pending} pending (${elapsed}s)"
178
+ sleep 5
179
+ done
180
+ }
181
+
182
+ show_status() {
183
+ print_step "Deployment Status"
184
+
185
+ echo ""
186
+ echo "Pods:"
187
+ kubectl get pods -n ${NAMESPACE} -o wide 2>/dev/null || echo "No pods found"
188
+
189
+ echo ""
190
+ echo "Services:"
191
+ kubectl get svc -n ${NAMESPACE} 2>/dev/null || echo "No services found"
192
+
193
+ echo ""
194
+ echo "PVCs:"
195
+ kubectl get pvc -n ${NAMESPACE} 2>/dev/null || echo "No PVCs found"
196
+ }
197
+
198
+ show_access_info() {
199
+ print_step "Access Information"
200
+
201
+ echo ""
202
+ echo -e "${BLUE}Local URLs (no auth required):${NC}"
203
+ echo " App: http://localhost:8080"
204
+ echo " Studio: http://studio.localhost:8080"
205
+ echo " n8n: http://n8n.localhost:8080 (admin / local-n8n-password)"
206
+ echo " Traefik: http://traefik.localhost:8080"
207
+ echo ""
208
+ echo -e "${BLUE}Admin URLs (requires admin role - production-like):${NC}"
209
+ echo " Studio: http://localhost:8080/admin/studio"
210
+ echo " n8n: http://localhost:8080/admin/n8n"
211
+ echo ""
212
+ echo -e "${BLUE}Supabase API (via Kong):${NC}"
213
+ echo " Auth: http://localhost:8080/auth/v1/"
214
+ echo " REST: http://localhost:8080/rest/v1/"
215
+ echo " Realtime: http://localhost:8080/realtime/v1/"
216
+ echo " Storage: http://localhost:8080/storage/v1/"
217
+ echo ""
218
+ echo -e "${BLUE}App API:${NC}"
219
+ echo " Health: http://localhost:8080/api/health"
220
+ echo " Docs: http://localhost:8080/api/docs"
221
+ echo " v1 API: http://localhost:8080/api/v1/..."
222
+ echo ""
223
+ echo -e "${BLUE}Port Forwarding (direct service access):${NC}"
224
+ echo " kubectl port-forward svc/postgres 5432:5432 -n ${NAMESPACE}"
225
+ echo " kubectl port-forward svc/kong 8000:8000 -n ${NAMESPACE}"
226
+ echo " kubectl port-forward svc/studio 3001:3000 -n ${NAMESPACE}"
227
+ echo ""
228
+ echo -e "${BLUE}View logs:${NC}"
229
+ echo " kubectl logs -f statefulset/postgres -n ${NAMESPACE}"
230
+ echo " kubectl logs -f deployment/kong -n ${NAMESPACE}"
231
+ echo " kubectl logs -f deployment/auth -n ${NAMESPACE}"
232
+ echo " kubectl logs -f deployment/app -n ${NAMESPACE}"
233
+ echo ""
234
+ echo -e "${BLUE}Delete cluster when done:${NC}"
235
+ echo " k3d cluster delete ${CLUSTER_NAME}"
236
+ echo " # or: pnpm k8s:local:down"
237
+ echo ""
238
+ }
239
+
240
+ debug_pods() {
241
+ print_step "Debugging pod issues..."
242
+
243
+ echo ""
244
+ echo "Failed/Pending pods:"
245
+ kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | grep -v "Running" || echo "All pods running"
246
+
247
+ echo ""
248
+ echo "Recent events:"
249
+ kubectl get events -n ${NAMESPACE} --sort-by='.lastTimestamp' 2>/dev/null | tail -15
250
+
251
+ local problem_pod=$(kubectl get pods -n ${NAMESPACE} --no-headers 2>/dev/null | grep -v "Running" | head -1 | awk '{print $1}')
252
+ if [ -n "$problem_pod" ]; then
253
+ echo ""
254
+ echo "Details for problematic pod: $problem_pod"
255
+ kubectl describe pod "$problem_pod" -n ${NAMESPACE} 2>/dev/null | tail -30
256
+ fi
257
+ }
258
+
259
+ cleanup() {
260
+ print_step "Cleaning up local cluster..."
261
+ k3d cluster delete ${CLUSTER_NAME}
262
+
263
+ # Also delete k3d docker volumes to ensure fresh state
264
+ docker volume rm k3d-${CLUSTER_NAME}-images 2>/dev/null || true
265
+
266
+ print_success "Cluster deleted"
267
+ }
268
+
269
+ # Parse arguments
270
+ case "${1:-}" in
271
+ "delete"|"cleanup"|"down")
272
+ cleanup
273
+ exit 0
274
+ ;;
275
+ "status")
276
+ kubectl config use-context k3d-${CLUSTER_NAME} 2>/dev/null || true
277
+ show_status
278
+ exit 0
279
+ ;;
280
+ "logs")
281
+ kubectl config use-context k3d-${CLUSTER_NAME} 2>/dev/null || true
282
+ kubectl logs -f "${2:-deployment/app}" -n ${NAMESPACE}
283
+ exit 0
284
+ ;;
285
+ "debug")
286
+ kubectl config use-context k3d-${CLUSTER_NAME} 2>/dev/null || true
287
+ debug_pods
288
+ exit 0
289
+ ;;
290
+ "help"|"-h"|"--help")
291
+ echo "Usage: $0 [command]"
292
+ echo ""
293
+ echo "Commands:"
294
+ echo " (none) Create cluster and deploy"
295
+ echo " status Show pod/service status"
296
+ echo " logs Follow logs (default: deployment/app)"
297
+ echo " debug Debug failing pods"
298
+ echo " delete Delete the local cluster"
299
+ echo " help Show this help"
300
+ exit 0
301
+ ;;
302
+ esac
303
+
304
+ # Main flow
305
+ echo -e "${BLUE}"
306
+ echo "╔════════════════════════════════════════════════════════════╗"
307
+ echo "║ Vibecarbon Local Kubernetes Testing ║"
308
+ echo "╚════════════════════════════════════════════════════════════╝"
309
+ echo -e "${NC}"
310
+
311
+ check_dependencies
312
+ create_cluster
313
+ deploy_manifests
314
+ wait_for_pods
315
+ show_status
316
+ show_access_info
317
+
318
+ print_success "Local k8s environment ready!"
@@ -0,0 +1,133 @@
1
+ # Supabase Helm chart values (supabase-community/supabase-kubernetes).
2
+ #
3
+ # Chart schema reference:
4
+ # helm show values supabase-community/supabase
5
+ #
6
+ # Top-level keys recognised by this chart: secret, deployment, image,
7
+ # environment, persistence, service, autoscaling, ingress, migration,
8
+ # bigQuery. Component toggles live under `deployment.<comp>.enabled` —
9
+ # top-level keys like `functions:` or `analytics:` are silently ignored.
10
+ #
11
+ # Placeholders like {{DOMAIN}} are substituted at deploy time in
12
+ # installSupabase — do not hand-edit after deploy.
13
+ #
14
+ # We intentionally do NOT set fullnameOverride/nameOverride: the chart's
15
+ # generated resources ignore the top-level override, so attempting to
16
+ # rename creates a mismatch (ConfigMap URLs stop resolving). Deploy code
17
+ # and the production overlay reference the chart-generated names directly
18
+ # (`supabase-supabase-<component>`).
19
+
20
+ # Shared secret wiring — every component reads from the vibecarbon-secrets
21
+ # Secret created by applyVibecarbonSecrets before helm install runs. The
22
+ # chart's `secretRef` + `secretRefKey` map the chart's internal field
23
+ # names to keys in our secret; plain `secretName: vibecarbon-secrets`
24
+ # does NOT work — the chart silently falls back to generating its own
25
+ # supabase-jwt/supabase-dashboard secrets with random values (hit on
26
+ # 2026-04-19 run #3 — Kong rejected our app's SERVICE_ROLE_KEY because
27
+ # it was signed with our JWT_SECRET while the chart-generated
28
+ # supabase-jwt.secret was a different string).
29
+ secret:
30
+ jwt:
31
+ secretRef: vibecarbon-secrets
32
+ secretRefKey:
33
+ anonKey: ANON_KEY
34
+ serviceKey: SERVICE_ROLE_KEY
35
+ secret: JWT_SECRET
36
+ dashboard:
37
+ # Inline values — dashboard.openAiApiKey is chart-required and we don't
38
+ # ship one in vibecarbon-secrets. Using secretRef here would force the
39
+ # chart to read EVERY dashboard field from the secret (including
40
+ # openAiApiKey), and kubelet would fail the studio StatefulSet with
41
+ # "couldn't find key openAiApiKey in Secret vibecarbon/vibecarbon-secrets".
42
+ # Inline values are rendered into the chart's own supabase-dashboard
43
+ # secret at install time — still secure, just not deduped into ours.
44
+ username: "{{ADMIN_EMAIL}}"
45
+ password: "{{ADMIN_PASSWORD}}"
46
+ openAiApiKey: ""
47
+ db:
48
+ secretRef: vibecarbon-secrets
49
+ # When secretRef is set, the chart uses secret keys for every db.* value
50
+ # (inline values are ignored). Maps the chart's lowercase field names to
51
+ # the uppercase keys vibecarbon-secrets ships (DB_NAME defaulted to
52
+ # "postgres" by applyVibecarbonSecrets).
53
+ secretRefKey:
54
+ password: DB_PASSWORD
55
+ database: DB_NAME
56
+
57
+ # Component enable toggles — chart's path is deployment.<comp>.enabled.
58
+ # Top-level `functions:`/`analytics:`/`vector:` are silently ignored
59
+ # (was the bug behind the 2026-04-26 e2e helm-wait timeout).
60
+ deployment:
61
+ functions:
62
+ # Chart's edge-runtime expects a function source at /home/deno/functions.
63
+ # The template doesn't ship a default `main/index.ts`, so the chart's
64
+ # default deployment fetches `https://deno.land/x/jose@v4.14.4/index.ts`
65
+ # at boot — and the network policy + missing function source produce
66
+ # a CrashLoopBackOff that holds up `helm --wait`. Re-enable once a
67
+ # project actually defines a function.
68
+ enabled: false
69
+ analytics:
70
+ # Logflare — disable until we need it. Adds ClickHouse + BigQuery deps.
71
+ enabled: false
72
+ vector:
73
+ # Log-shipper — disable; conflicts with the optional observability stack.
74
+ enabled: false
75
+ db:
76
+ # Pin postgres to the dedicated supabase node (taint applied by Pulumi).
77
+ nodeSelector:
78
+ dedicated: supabase
79
+ tolerations:
80
+ - key: dedicated
81
+ operator: Equal
82
+ value: supabase
83
+ effect: NoSchedule
84
+
85
+ # Per-component environment — chart's path is environment.<comp>.
86
+ environment:
87
+ auth:
88
+ API_EXTERNAL_URL: https://{{DOMAIN}}
89
+ GOTRUE_SITE_URL: https://{{DOMAIN}}
90
+ GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
91
+ # Auto-confirm signups: the chart doesn't ship an SMTP provider, so
92
+ # leaving AUTOCONFIRM=false makes every signup return 500 "Error
93
+ # sending confirmation email" (observed 2026-04-26 batch run #3 —
94
+ # k8s verify-deploy failed at the auth_signup check). Real
95
+ # production deployments override this to false once they wire up
96
+ # SMTP (configure SMTP_* env in the auth section). Default-true is
97
+ # the right call for an out-of-the-box deploy that doesn't have a
98
+ # mail provider.
99
+ GOTRUE_MAILER_AUTOCONFIRM: "true"
100
+ realtime:
101
+ DB_NAME: postgres
102
+ storage:
103
+ STORAGE_BACKEND: s3
104
+ imgproxy:
105
+ IMGPROXY_USE_S3: "true"
106
+ studio:
107
+ SUPABASE_PUBLIC_URL: https://{{DOMAIN}}
108
+ STUDIO_DEFAULT_ORGANIZATION: "{{PROJECT_NAME}}"
109
+ # Kong reads its declarative config from /usr/local/kong/kong.yml — written
110
+ # by the chart's kong-entrypoint.sh after env substitution. The chart's
111
+ # default `KONG_DECLARATIVE_CONFIG` already points at this path, so leave
112
+ # it un-overridden. (Setting it to `/usr/local/kong/declarative/kong.yml`
113
+ # — which doesn't exist — was the cause of the 2026-04-26 e2e kong
114
+ # CrashLoopBackOff.)
115
+
116
+ # We front Kong with our own Traefik IngressRoute (k8s/base/traefik) — the
117
+ # chart's ingress object is off so we don't end up with two ingresses
118
+ # pointing at the same Service.
119
+ ingress:
120
+ enabled: false
121
+
122
+ # Persistence:
123
+ # - db: bump default 5Gi → 10Gi.
124
+ # - functions: disable PVC creation. The chart's persistence.functions PVC
125
+ # is independent of deployment.functions.enabled — without this, studio
126
+ # stays Pending forever waiting for a `supabase-functions` PVC that
127
+ # persistence.yaml gates on `deployment.functions.enabled` (off here).
128
+ persistence:
129
+ db:
130
+ enabled: true
131
+ size: 10Gi
132
+ functions:
133
+ enabled: false
@@ -0,0 +1,154 @@
1
+ {
2
+ "name": "vibecarbon-template",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "packageManager": "pnpm@10.32.1",
7
+ "scripts": {
8
+ "dev:init": "node scripts/dev-init.js",
9
+ "dev:start": "node scripts/docker-up.js && pnpm db:migrate && exec node scripts/dev.js",
10
+ "dev:start:all": "node scripts/docker-up.js --all && pnpm db:migrate && exec node scripts/dev.js",
11
+ "dev:stop": "node scripts/docker-down.js",
12
+ "dev:stop:all": "node scripts/docker-down.js --all",
13
+ "dev:reset": "node scripts/docker-down.js -v --rmi",
14
+ "dev:reset:all": "node scripts/docker-down.js -v --rmi --all",
15
+ "dev": "exec node scripts/dev.js",
16
+ "dev:server": "tsx watch --env-file=.env.local src/server/index.ts",
17
+ "dev:client": "vite",
18
+ "build": "pnpm build:client && pnpm build:server",
19
+ "build:client": "vite build && tsx scripts/generate-sitemap.ts && tsx scripts/generate-rss.ts",
20
+ "build:server": "esbuild src/server/index.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/server/index.js --external:pino --external:pino-pretty --banner:js=\"import{createRequire as __cr}from'module';const require=__cr(import.meta.url);\"",
21
+ "start": "node dist/server/index.js",
22
+ "lint": "biome check .",
23
+ "lint:fix": "biome check --write .",
24
+ "format": "biome format --write .",
25
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.server.json --noEmit",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:unit": "vitest run --project unit",
29
+ "test:component": "vitest run --project component",
30
+ "test:integration": "vitest run --project integration",
31
+ "test:coverage": "vitest run --coverage",
32
+ "test:prepush": "pnpm lint && pnpm test:unit && pnpm test:component && pnpm test:integration",
33
+ "docker:up": "node scripts/docker-up.js",
34
+ "docker:up:all": "node scripts/docker-up.js --all",
35
+ "docker:down": "node scripts/docker-down.js",
36
+ "docker:down:all": "node scripts/docker-down.js --all",
37
+ "docker:logs": "node scripts/docker-logs.js",
38
+ "docker:reset": "node scripts/docker-down.js -v --rmi",
39
+ "docker:reset:all": "node scripts/docker-down.js -v --rmi --all",
40
+ "docker:prod:up": "node scripts/docker-up.js --prod",
41
+ "docker:prod:down": "node scripts/docker-down.js --prod",
42
+ "db:migrate": "docker compose exec db bash -c 'for f in /migrations/*.sql; do psql -U postgres -d postgres -f \"$f\" || exit 1; done' && docker compose exec db psql -U postgres -d postgres -f /tmp/super-admin.sql",
43
+ "db:reset": "node scripts/docker-down.js -v && node scripts/docker-up.js",
44
+ "k8s:apply": "node scripts/k8s-apply.js",
45
+ "k8s:delete": "node scripts/k8s-delete.js",
46
+ "k8s:local:up": "./k8s/test-local.sh",
47
+ "k8s:local:status": "./k8s/test-local.sh status",
48
+ "k8s:local:debug": "./k8s/test-local.sh debug",
49
+ "k8s:local:down": "./k8s/test-local.sh delete",
50
+ "stripe:listen": "stripe listen --forward-to localhost:3000/api/webhooks/stripe"
51
+ },
52
+ "dependencies": {
53
+ "@base-ui/react": "^1.3.0",
54
+ "@fontsource-variable/noto-sans": "^5.2.10",
55
+ "@fontsource/jetbrains-mono": "^5.2.8",
56
+ "@hono/node-server": "^1.19.13",
57
+ "@hono/zod-openapi": "^1.2.3",
58
+ "@hookform/resolvers": "^5.2.2",
59
+ "@mdx-js/react": "^3.1.1",
60
+ "@mdx-js/rollup": "^3.1.1",
61
+ "@scalar/api-reference-react": "^0.9.15",
62
+ "@supabase/ssr": "^0.9.0",
63
+ "@supabase/supabase-js": "^2.100.0",
64
+ "@tanstack/react-query": "^5.95.2",
65
+ "class-variance-authority": "^0.7.1",
66
+ "clsx": "^2.1.1",
67
+ "cmdk": "^1.1.1",
68
+ "date-fns": "^4.1.0",
69
+ "embla-carousel-react": "^8.6.0",
70
+ "framer-motion": "^12.38.0",
71
+ "hono": "^4.12.16",
72
+ "i18next": "^25.10.9",
73
+ "i18next-browser-languagedetector": "^8.2.1",
74
+ "input-otp": "^1.4.2",
75
+ "ioredis": "^5.10.1",
76
+ "lenis": "^1.3.20",
77
+ "lucide-react": "^1.7.0",
78
+ "next-themes": "^0.4.6",
79
+ "nodemailer": "^8.0.5",
80
+ "pino": "^10.3.1",
81
+ "react": "^19.2.4",
82
+ "react-day-picker": "^9.14.0",
83
+ "react-dom": "^19.2.4",
84
+ "react-hook-form": "^7.72.0",
85
+ "react-i18next": "^16.6.6",
86
+ "react-resizable-panels": "^4.7.6",
87
+ "react-router-dom": "^7.13.2",
88
+ "recharts": "^3.8.1",
89
+ "rehype-autolink-headings": "^7.1.0",
90
+ "rehype-slug": "^6.0.0",
91
+ "remark-frontmatter": "^5.0.0",
92
+ "remark-mdx-frontmatter": "^5.2.0",
93
+ "sonner": "^2.0.7",
94
+ "stripe": "^20.4.1",
95
+ "tailwind-merge": "^3.5.0",
96
+ "vaul": "^1.1.2",
97
+ "zod": "^4.3.6"
98
+ },
99
+ "pnpm": {
100
+ "onlyBuiltDependencies": [
101
+ "esbuild",
102
+ "msw"
103
+ ],
104
+ "allowedDeprecatedVersions": {
105
+ "node-domexception": "1.0.0"
106
+ },
107
+ "overrides": {
108
+ "dompurify": "^3.4.0",
109
+ "unhead": ">=2.1.13",
110
+ "defu": ">=6.1.5",
111
+ "path-to-regexp@>=8.0.0": ">=8.4.0",
112
+ "postcss@<8.5.10": ">=8.5.10",
113
+ "ip-address@<10.1.1": ">=10.1.1",
114
+ "fast-uri@<3.1.2": ">=3.1.2",
115
+ "protobufjs@<7.5.6": "^7.5.6",
116
+ "@protobufjs/utf8@<1.1.1": "^1.1.1"
117
+ },
118
+ "peerDependencyRules": {
119
+ "allowedVersions": {
120
+ "typescript": "*"
121
+ }
122
+ }
123
+ },
124
+ "devDependencies": {
125
+ "@biomejs/biome": "^2.4.9",
126
+ "@hono/swagger-ui": "^0.6.1",
127
+ "@scalar/hono-api-reference": "^0.10.5",
128
+ "@tailwindcss/typography": "^0.5.19",
129
+ "@tailwindcss/vite": "^4.2.2",
130
+ "@testing-library/jest-dom": "^6.6.3",
131
+ "@testing-library/react": "^16.3.0",
132
+ "@testing-library/user-event": "^14.6.1",
133
+ "@types/node": "^25.5.0",
134
+ "@types/nodemailer": "^7.0.11",
135
+ "@types/pg": "^8.20.0",
136
+ "@types/react": "^19.2.14",
137
+ "@types/react-dom": "^19.2.3",
138
+ "@vitejs/plugin-react": "^6.0.1",
139
+ "@vitest/coverage-v8": "^4.1.1",
140
+ "concurrently": "^9.2.1",
141
+ "esbuild": "^0.27.4",
142
+ "jsdom": "^26.1.0",
143
+ "pg": "^8.20.0",
144
+ "pino-pretty": "^13.1.3",
145
+ "remark-gfm": "^4.0.1",
146
+ "shadcn": "^4.1.0",
147
+ "tailwindcss": "^4.2.2",
148
+ "tsx": "^4.21.0",
149
+ "tw-animate-css": "^1.4.0",
150
+ "typescript": "^6.0.2",
151
+ "vite": "^8.0.5",
152
+ "vitest": "^4.1.1"
153
+ }
154
+ }
@@ -0,0 +1,17 @@
1
+ # syntax=docker/dockerfile:1
2
+ # Vibecarbon Runtime Base Image
3
+ # This image contains the pre-installed node_modules for the Vibecarbon template.
4
+ # Using this as a base for your app image reduces build times from minutes to seconds.
5
+
6
+ FROM node:22-alpine3.23 AS base
7
+
8
+ RUN npm install -g pnpm@9
9
+ WORKDIR /app
10
+
11
+ # Pre-install dependencies
12
+ COPY package.json pnpm-lock.yaml ./
13
+ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
14
+ pnpm install --frozen-lockfile
15
+
16
+ # This image is meant to be a base, so we stop here.
17
+ # The app build will continue FROM this image.
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ // Sign HS256 JWTs from a shared dev secret. Used by dev-init.js and
3
+ // generate-dev-configs.sh to produce ANON / SERVICE_ROLE keys at runtime
4
+ // so the carbon template doesn't ship literal JWT strings — those would
5
+ // trip every secret-scanner that looked at the repo (GitHub's, ours,
6
+ // gitleaks, ...). The values are still deterministic for a given
7
+ // JWT_SECRET, so dev workflows that depend on stable keys keep working
8
+ // across runs.
9
+ //
10
+ // Usage:
11
+ // node scripts/_dev-jwt.mjs <role>
12
+ //
13
+ // Where <role> is `anon` or `service_role`. JWT_SECRET must be set in
14
+ // the environment. Prints the JWT to stdout (no newline) on success;
15
+ // non-zero exit on bad input.
16
+
17
+ import { createHmac } from 'node:crypto';
18
+
19
+ const role = process.argv[2];
20
+ if (role !== 'anon' && role !== 'service_role') {
21
+ process.stderr.write('usage: _dev-jwt.mjs (anon|service_role)\n');
22
+ process.exit(2);
23
+ }
24
+ const secret = process.env.JWT_SECRET;
25
+ if (!secret) {
26
+ process.stderr.write('JWT_SECRET must be set in the environment\n');
27
+ process.exit(2);
28
+ }
29
+
30
+ const b64url = (buf) =>
31
+ Buffer.from(buf).toString('base64').replace(/=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
32
+
33
+ const header = b64url(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
34
+ const payload = b64url(
35
+ JSON.stringify({
36
+ iss: 'supabase-demo',
37
+ role,
38
+ // 100-year expiry: dev tokens shouldn't churn during a single
39
+ // engineer's career. Production tokens are signed elsewhere with
40
+ // shorter lifetimes; this is local-dev only.
41
+ exp: Math.floor(Date.now() / 1000) + 100 * 365 * 24 * 60 * 60,
42
+ }),
43
+ );
44
+ const sig = b64url(createHmac('sha256', secret).update(`${header}.${payload}`).digest());
45
+ process.stdout.write(`${header}.${payload}.${sig}`);