diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
index 51d7dd419ed..cb06d2c3907 100644
--- a/.claude/CLAUDE.md
+++ b/.claude/CLAUDE.md
@@ -31,6 +31,8 @@ pnpm typecheck # typecheck all packages
**Styling** — Tailwind only, semantic tokens (`bg-muted`, `text-foreground-light`), no hardcoded colors.
+**Language** — Use U.S. English everywhere.
+
## Studio
Pages router. Co-locate sub-components with parent. Avoid barrel re-export files.
diff --git a/.claude/skills/studio-ui-patterns/SKILL.md b/.claude/skills/studio-ui-patterns/SKILL.md
index 85acab8a146..2a67de2bee4 100644
--- a/.claude/skills/studio-ui-patterns/SKILL.md
+++ b/.claude/skills/studio-ui-patterns/SKILL.md
@@ -34,7 +34,7 @@ Docs: `apps/design-system/content/docs/ui-patterns/forms.mdx`
- Use `react-hook-form` + `zod`
- Use `FormItemLayout` instead of manually composing `FormItem`/`FormLabel`/`FormMessage`/`FormDescription`
-- Wrap inputs with `FormControl_Shadcn_`; use `_Shadcn_` imports from `ui` for primitives
+- Wrap inputs with `FormControl`; use `_Shadcn_` imports from `ui` for primitives
Layout selection:
diff --git a/.github/instructions/studio-telemetry.instructions.md b/.github/instructions/studio-telemetry.instructions.md
index 3892a6fde6b..0a9897dce61 100644
--- a/.github/instructions/studio-telemetry.instructions.md
+++ b/.github/instructions/studio-telemetry.instructions.md
@@ -1,5 +1,5 @@
---
-applyTo: "apps/studio/**,packages/common/telemetry*"
+applyTo: 'apps/studio/**,packages/common/telemetry*'
---
# Studio Telemetry Review Rules
@@ -11,8 +11,8 @@ All comments are **advisory** — suggest, do not request changes.
Use judgment — not every PR needs telemetry. But **always flag** when:
1. **Changes to `packages/common/telemetry-constants.ts`** — validate event naming, property conventions, and JSDoc accuracy.
-2. **PostHog feature flags without measurement.** If a PR uses `usePHFlag` or PostHog-backed hooks like `useDataApiGrantTogglesEnabled` to gate behavior, the flag state should be captured in a telemetry event so the rollout can be measured. Flag if the flag value isn't included in a relevant `track()` call. (Note: `useFlag` from `common` reads ConfigCat flags, not PostHog — different system, different guidance.)
-3. **Feature-flagged rollouts without outcome tracking.** If a flag gates new behavior, there should be telemetry on both the flag state *and* how users respond to the new behavior (e.g., toggle clicks, opt-in actions).
+2. **PostHog feature flags without measurement.** If a PR uses `usePHFlag` or PostHog-backed hooks like `useDataApiRevokeOnCreateDefaultEnabled` to gate behavior, the flag state should be captured in a telemetry event so the rollout can be measured. Flag if the flag value isn't included in a relevant `track()` call. (Note: `useFlag` from `common` reads ConfigCat flags, not PostHog — different system, different guidance.)
+3. **Feature-flagged rollouts without outcome tracking.** If a flag gates new behavior, there should be telemetry on both the flag state _and_ how users respond to the new behavior (e.g., toggle clicks, opt-in actions).
4. **Growth-oriented components adding user interactions without tracking** — onboarding flows, setup wizards, upgrade CTAs, A/B experiment variants.
When tracking is missing, comment: _"This adds a user interaction (or feature flag) that may benefit from tracking."_ Then propose an event name and `useTrack()` call.
@@ -52,6 +52,7 @@ Flag: unapproved verbs (`saved`, `viewed`, `pressed`), wrong order (`click_produ
```typescript
import { useTrack } from 'lib/telemetry/track'
+
const track = useTrack()
track('product_card_clicked', { productType: 'database', planTier: 'pro' })
```
diff --git a/.github/workflows/self-host-tests-smoke.yml b/.github/workflows/self-host-tests-smoke.yml
index 9f3782ed5f4..1727558d181 100644
--- a/.github/workflows/self-host-tests-smoke.yml
+++ b/.github/workflows/self-host-tests-smoke.yml
@@ -31,4 +31,4 @@ jobs:
cd docker
cp .env.example .env
yq -i '.services.supavisor.environment.RLIMIT_NOFILE=1024' docker-compose.yml
- docker compose up --wait --wait-timeout 180
+ docker compose up --quiet-pull --wait --wait-timeout 180
diff --git a/.github/workflows/studio-e2e-test.yml b/.github/workflows/studio-e2e-test.yml
index cf3ecc38199..be170f07d38 100644
--- a/.github/workflows/studio-e2e-test.yml
+++ b/.github/workflows/studio-e2e-test.yml
@@ -83,18 +83,30 @@ jobs:
if: steps.filter.outputs.studio == 'true'
run: rm -rf supabase && pnpm exec supabase init && mkdir supabase/functions
+ - name: Pre-start diagnostics
+ run: |
+ docker ps -a
+ sudo ss -tlnp | grep 5432 || echo "5432 free"
+
- name: Start supabase
if: steps.filter.outputs.studio == 'true'
run: SKIP_ASSET_UPLOAD=1 pnpm run e2e:setup:cli
+ - name: Failure diagnostics
+ if: failure()
+ run: |
+ docker ps -a
+ sudo ss -tlnp | grep 5432
+ docker logs $(docker ps -aq) 2>&1 || true
+
- name: Build studio
if: steps.filter.outputs.studio == 'true'
run: SKIP_ASSET_UPLOAD=1 NODE_ENV=test NODE_OPTIONS="--max-old-space-size=4096" pnpm run build:studio
- - name: 🚀 Run Playwright tests against Vercel Preview
+ - name: 🚀 Run Playwright tests against local studio build
if: steps.filter.outputs.studio == 'true'
id: playwright
- run: pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
+ run: PWTEST_SHARD_WEIGHTS=62:38 pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload blob report to GitHub Actions Artifacts
if: always() && steps.filter.outputs.studio == 'true'
diff --git a/.prettierignore b/.prettierignore
index 5f74f6bc0d8..e1ba10c8806 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -8,6 +8,9 @@ apps/**/out
**/supabase/migrations/*.sql
apps/www/schema.sql
apps/www/public/images/*
+# Generated by apps/www/scripts/generateStaticContent.mjs (GitHub discussion bodies)
+apps/www/public/changelog.md
+apps/www/public/changelog/*.md
apps/www/.generated/*
apps/docs/**/generated/*
apps/docs/examples/*
diff --git a/DEVELOPERS.md b/DEVELOPERS.md
index d228ea7b169..6bf8f3c41db 100644
--- a/DEVELOPERS.md
+++ b/DEVELOPERS.md
@@ -192,7 +192,7 @@ We support "federating" docs, meaning doc content can come directly from externa
Federated docs work using Next.js's build pipeline. We use `getStaticProps()` to fetch remote documentation (ie. markdown) at build time which is processed and passed to the respective page within the docs.
-See the [Vecs Python source code](https://github.com/supabase/supabase/tree/master/apps/docs/app/guides/ai/python/%5Bslug%5D to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs.
+See the [Vecs Python source code](https://github.com/supabase/supabase/tree/master/apps/docs/app/guides/ai/python/%5Bslug%5D) to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs.
Some things to consider:
diff --git a/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx b/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx
index 361c35a9a45..deab28e4ee2 100644
--- a/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx
+++ b/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx
@@ -71,7 +71,7 @@ export default function ChartComposedMetrics() {
}
+ loadingState={}
>
@@ -89,7 +89,7 @@ export default function ChartComposedMetrics() {
}
+ loadingState={}
>
diff --git a/apps/design-system/__registry__/index.tsx b/apps/design-system/__registry__/index.tsx
index 61ccda9e6b0..5b69704eecc 100644
--- a/apps/design-system/__registry__/index.tsx
+++ b/apps/design-system/__registry__/index.tsx
@@ -2568,6 +2568,17 @@ export const Index: Record = {
subcategory: "undefined",
chunks: []
},
+ "multi-select-in-dialog": {
+ name: "multi-select-in-dialog",
+ type: "components:example",
+ registryDependencies: undefined,
+ component: React.lazy(() => import("@/registry/default/example/multi-select-in-dialog")),
+ source: "",
+ files: ["registry/default/example/multi-select-in-dialog.tsx"],
+ category: "undefined",
+ subcategory: "undefined",
+ chunks: []
+ },
"tree-view-demo": {
name: "tree-view-demo",
type: "components:example",
diff --git a/apps/design-system/app/Providers.tsx b/apps/design-system/app/Providers.tsx
index a7fe031c76b..46dce708544 100644
--- a/apps/design-system/app/Providers.tsx
+++ b/apps/design-system/app/Providers.tsx
@@ -1,20 +1,19 @@
'use client'
+import { ThemeProvider } from 'common'
import { Provider as JotaiProvider } from 'jotai'
-import { ThemeProvider as NextThemesProvider } from 'next-themes'
-import { ThemeProviderProps } from 'next-themes/dist/types'
import { TooltipProvider } from 'ui'
import { MobileSidebarProvider } from '@/context/mobile-sidebar-context'
-export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+export function Providers({ children }: { children: React.ReactNode }) {
return (
-
+
{children}
-
+
)
}
diff --git a/apps/design-system/app/globals.css b/apps/design-system/app/globals.css
deleted file mode 100644
index f7f07cd6431..00000000000
--- a/apps/design-system/app/globals.css
+++ /dev/null
@@ -1,29 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-/* :root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
-} */
-
-body {
- /* color: rgb(var(--foreground-rgb));
- background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
- rgb(var(--background-start-rgb)); */
-}
-/*
-@layer utilities {
- .text-balance {
- text-wrap: balance;
- }
-} */
diff --git a/apps/design-system/app/layout.tsx b/apps/design-system/app/layout.tsx
index a7d6c82e2dd..69176828eb9 100644
--- a/apps/design-system/app/layout.tsx
+++ b/apps/design-system/app/layout.tsx
@@ -1,10 +1,10 @@
+import 'react-data-grid/lib/styles.css'
import '@/styles/globals.css'
-import '../../studio/styles/typography.css'
import type { Metadata, Viewport } from 'next'
import { customFont, sourceCodePro } from './fonts'
-import { ThemeProvider } from './Providers'
+import { Providers } from './Providers'
import { Toaster } from './toaster'
const className = `${customFont.variable} ${sourceCodePro.variable}`
@@ -131,16 +131,12 @@ export default async function Layout({ children }: RootLayoutProps) {
/>
-
+
-
+