Merge branch 'master' into jeremiasmenichelli/ifcs-67-instrument-search-v2-funnel-bis

This commit is contained in:
Jeremias Menichelli authored and GitHub committed 2026-10-02 16:02:56 -03:00
commit 67c0a877ad
71 files changed
+1494 -481

No files matched your search

+1
View File
@@ -10,6 +10,7 @@ issue_enrichment:
enabled: true
reviews:
high_level_summary: false
# Skip machine-generated / vendored files (mirrors .prettierignore). Keeps
# reviews focused on hand-written code and preserves rate-limit budget on
# large codegen diffs.
@@ -29,6 +29,8 @@ function useContentListingClickHandler(group: ContentListingGroup) {
const trackClick = useCallback(
(item: ContentListingItem) => {
if (!item.href) return
sendTelemetryEvent({
action: 'docs_content_listing_clicked',
properties: {
@@ -73,8 +75,45 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
)}
<ul className={listClassName}>
{items.map((item) => {
const key = `${group.id}-${item.href ?? item.title}`
const panel = (
<GlassPanel
title={item.title}
icon={resolveContentListingIcon(item.icon)}
hasLightIcon={item.hasLightIcon ?? typeof item.icon === 'string'}
className={item.href ? undefined : 'cursor-default'}
badge={
item.badge && item.badgePosition !== 'below' ? (
<Badge variant="success">{item.badge}</Badge>
) : undefined
}
>
{item.badge && item.badgePosition === 'below' && (
<Badge variant="success" className="mb-3 block w-fit">
{item.badge}
</Badge>
)}
{item.subtitle && (
<span className="mb-2 block text-tertiary-foreground">{item.subtitle}</span>
)}
{item.description}
</GlassPanel>
)
const listContent = (
<>
<strong>{item.title}</strong>: {item.description}
</>
)
if (!item.href) {
return (
<li key={key} className={gridItemClassName}>
{isGrid ? panel : listContent}
</li>
)
}
const external = isExternalContentListingHref(item.href)
const key = `${group.id}-${item.href}`
if (isGrid) {
return (
@@ -87,26 +126,7 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
target={external ? '_blank' : undefined}
rel={external ? 'noopener noreferrer' : undefined}
>
<GlassPanel
title={item.title}
icon={resolveContentListingIcon(item.icon)}
hasLightIcon={item.hasLightIcon ?? typeof item.icon === 'string'}
badge={
item.badge && item.badgePosition !== 'below' ? (
<Badge variant="success">{item.badge}</Badge>
) : undefined
}
>
{item.badge && item.badgePosition === 'below' && (
<Badge variant="success" className="mb-3 block w-fit">
{item.badge}
</Badge>
)}
{item.subtitle && (
<span className="mb-2 block text-tertiary-foreground">{item.subtitle}</span>
)}
{item.description}
</GlassPanel>
{panel}
</Link>
</li>
)
@@ -120,7 +140,7 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
target={external ? '_blank' : undefined}
rel={external ? 'noopener noreferrer' : undefined}
>
<strong>{item.title}</strong>: {item.description}
{listContent}
</Link>
</li>
)
@@ -1,5 +1,6 @@
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
import { healthAdvisors } from '~/data/health-advisors.data'
import { MDXRemoteBase } from '~/features/docs/MdxBase'
import { TabPanel, Tabs } from '~/features/ui/Tabs'
import { GENERATED_DIRECTORY } from '~/lib/docs'
@@ -25,7 +26,7 @@ export async function DatabaseAdvisorsIndex() {
return (
<Tabs listClassNames="flex flex-wrap gap-2 [&>button]:m-0!" queryGroup="lint">
{lints.map((lint) => (
{[...healthAdvisors, ...lints].map((lint) => (
<TabPanel key={lint.path} id={lint.path} label={capitalize(lint.path.replace(/_/g, ' '))}>
<section id={lint.path}>
<MDXRemoteBase source={lint.content} />
@@ -1139,6 +1139,20 @@ export const database: NavMenuConstant = {
},
],
},
{
name: 'Multigres',
url: undefined,
items: [
{
name: 'Overview',
url: '/guides/database/multigres' as `/${string}`,
},
{
name: 'Compatibility',
url: '/guides/database/multigres/compatibility' as `/${string}`,
},
],
},
{
name: 'Access and security',
url: undefined,
@@ -343,6 +343,37 @@ Every client that implements the MCP authorization specification discovers your
Users can review and revoke connected clients through the [OAuth grant management](/docs/guides/auth/oauth-server/oauth-flows#managing-user-grants) endpoints. The [Headless App block](/library/docs/tanstack/headless-app) ships an `/agents` page that does this.
## Use a custom domain
With a [custom domain](/docs/guides/platform/custom-domains) active, clients can reach your MCP server at `https://api.example.com/functions/v1/mcp`. Supabase Auth keeps its issuer on the project domain, `https://<your-project-ref>.supabase.co/auth/v1`. `withOAuthProtectedResource()` builds the Auth URL from the domain the request arrived on, so on the custom domain it advertises `https://api.example.com/auth/v1`. That doesn't match the issuer, and MCP clients that validate the Auth metadata stop at discovery.
If your clients can use the project URL, `https://<your-project-ref>.supabase.co/functions/v1/mcp` needs no changes. To serve MCP on the custom domain too, set the Auth server explicitly:
1. Point `authorizationServer` at an environment variable instead of letting it default to the request's domain:
```ts
[
withOAuthProtectedResource({ authorizationServer: Deno.env.get('MCP_AUTH_ISSUER') }),
withSupabase<Database>({ auth: 'user' }),
],
```
2. Store the issuer as a secret, and redeploy:
```bash
supabase secrets set MCP_AUTH_ISSUER=https://<your-project-ref>.supabase.co/auth/v1
supabase functions deploy mcp
```
Leave `MCP_AUTH_ISSUER` unset locally. An unset value falls back to the default, which is correct on the local stack. The `resource` URL still follows the domain each client uses, so the project URL and the custom domain both keep working.
To confirm the fix, compare `authorization_servers` from the resource metadata with `issuer` from Auth's discovery document. They must match:
```bash
curl https://api.example.com/functions/v1/mcp/oauth-protected-resource
curl https://<your-project-ref>.supabase.co/auth/v1/.well-known/oauth-authorization-server
```
## Run it outside Edge Functions
The same pipeline mounts in any runtime that speaks `Request` in, `Response` out: a Next.js route handler, a SvelteKit endpoint, Cloudflare Workers, or a plain Node, Bun, or Deno server. Off Edge Functions there are no forwarded headers to derive the public URLs from, so pass them explicitly:
@@ -0,0 +1,60 @@
---
id: 'multigres'
title: 'Multigres'
subtitle: 'Horizontally scalable Postgres for high availability'
description: 'Run high availability Postgres across multiple nodes with automatic failover, using Multigres.'
---
<Admonition type="caution">
Multigres is in [Private Alpha](/docs/guides/getting-started/features#feature-status). It's free during the Alpha for organizations on a paid plan, for up to two projects, but pricing may change once it leaves Alpha. It isn't covered by the [uptime SLA](/sla), and Supabase isn't targeting production or mission-critical workloads with it during this stage.
</Admonition>
Multigres gives your project high availability by running Postgres across multiple nodes instead of one, so reads and writes continue if a node fails. It is Supabase's integration of [Multigres](https://multigres.com), an open-source project that brings the same distributed-systems approach Vitess brought to MySQL to Postgres.
<ContentListings id="database-multigres-what-you-get" />
## Eligibility
During the Private Alpha:
- Multigres is available to organizations on a paid plan. It isn't available on the Free plan.
- Availability is being rolled out gradually, so the option to enable it may not yet appear for every eligible organization.
- Up to two projects per eligible organization can use Multigres for free during the Alpha.
## Enabling Multigres
In the Dashboard, Multigres appears as **High availability** during project creation:
1. Open [Create a new project](/dashboard/new/_) in the Dashboard.
2. Under **High availability**, turn on **Enable high availability**.
3. Finish the remaining fields such as database password, region, and compute size, if shown.
4. Click **Create new project**.
If your organization isn't eligible or hasn't been rolled out yet, **High availability** won't appear.
## What's not included in the alpha
Some Supabase features and project operations aren't yet available on Multigres-backed projects:
- **Realtime.** Multigres doesn't yet support the logical replication that Realtime depends on, so Realtime is unavailable.
- **Point-in-Time Recovery.** Only the standard daily backups are available.
- **Cross-region read replicas.** Multigres projects run in a single region during the Alpha.
- **OrioleDB.** A project can use Multigres or [OrioleDB](/docs/guides/database/orioledb), not both.
- **Resizing after creation.** Compute size, disk, and the number of replicas can't be changed after a Multigres project is created.
- **Sharding and custom durability policies.** These are on the longer-term roadmap but aren't part of the Alpha.
<Admonition type="caution">
Enabling Multigres migrates your project's database to run on Multigres. There's currently no managed path to move it back to a standard Postgres project.
</Admonition>
## Compatibility
Multigres aims for full compatibility with standard Postgres, but there are some differences to be aware of. See [Multigres compatibility](/docs/guides/database/multigres/compatibility) for details.
## Resources
[Multigres documentation](https://multigres.com/docs) — architecture, self-hosted deployment, and other technical depth that goes beyond the hosted Supabase integration covered on this page.
@@ -0,0 +1,6 @@
---
title: 'Multigres compatibility'
description: 'Where Multigres-backed Postgres projects differ from standard Postgres.'
---
Multigres targets full compatibility with standard Postgres, verified against the [`pg_regress`](https://www.postgresql.org/docs/current/regress.html) test suite. See the [Multigres documentation](https://multigres.com/docs) for lower-level architecture and compatibility details, and the [Multigres overview](/docs/guides/database/multigres#whats-not-included-in-the-alpha) for what's not yet supported during the Private Alpha.
@@ -34,14 +34,12 @@ See [Set up manual replication](/docs/guides/database/replication/manual-replica
## Supported destinations
| Destination | Status |
| -------------------------------------------------------------------- | ------------- |
| [BigQuery](/docs/guides/database/replication/pipelines/bigquery) | Public alpha |
| [ClickHouse](/docs/guides/database/replication/pipelines/clickhouse) | Private alpha |
| [DuckLake](/docs/guides/database/replication/pipelines/ducklake) | Private alpha |
| [Snowflake](/docs/guides/database/replication/pipelines/snowflake) | Private alpha |
[Request access](/go/supabase-pipelines-new-destinations) to destinations in private alpha.
| Destination | Status |
| -------------------------------------------------------------------- | ------------ |
| [BigQuery](/docs/guides/database/replication/pipelines/bigquery) | Public alpha |
| [ClickHouse](/docs/guides/database/replication/pipelines/clickhouse) | Public alpha |
| [DuckLake](/docs/guides/database/replication/pipelines/ducklake) | Public alpha |
| [Snowflake](/docs/guides/database/replication/pipelines/snowflake) | Public alpha |
## Use cases
@@ -14,7 +14,7 @@ Pipelines requires a Pro, Team, or Enterprise plan. During public alpha, availab
## What destinations are supported?
BigQuery is in public alpha. ClickHouse, DuckLake, and Snowflake are in private alpha and require access approval. See [supported destinations](/docs/guides/database/replication#supported-destinations) for their status and access request.
BigQuery, ClickHouse, DuckLake, and Snowflake are in public alpha. For setup guides, see [supported destinations](/docs/guides/database/replication#supported-destinations).
## Does the destination's region affect performance?
@@ -8,8 +8,6 @@ sidebar_label: 'ClickHouse'
<$Partial path="pipelines-public-alpha.mdx" />
The ClickHouse destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
[ClickHouse](https://clickhouse.com/) is a database for analytics. Supabase Pipelines replicates Postgres tables to ClickHouse as either current-state tables or an append-only history of changes.
To replicate data to ClickHouse:
@@ -8,8 +8,6 @@ sidebar_label: 'DuckLake'
<$Partial path="pipelines-public-alpha.mdx" />
The DuckLake destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
Replicate Postgres tables to [DuckLake](https://ducklake.select/) for current-state lakehouse queries. [Prepare resources](#understand-the-ducklake-components), [configure the destination](#choose-a-configuration-mode), then [query replicated data](#query-the-destination).
## Source table requirements
@@ -102,7 +100,7 @@ select *
from my_ducklake.public.orders;
```
See the [DuckDB connection guide](https://ducklake.select/docs/stable/duckdb/usage/connecting) for the current `ducklake` extension and `ATTACH` syntax. If your query client can't read a Supabase-backed catalog during private alpha, [contact support](/dashboard/support/new).
See the [DuckDB connection guide](https://ducklake.select/docs/stable/duckdb/usage/connecting) for the current `ducklake` extension and `ATTACH` syntax. If your query client can't read a Supabase-backed catalog during public alpha, [contact support](/dashboard/support/new).
## Replica identity
@@ -8,8 +8,6 @@ sidebar_label: 'Snowflake'
<$Partial path="pipelines-public-alpha.mdx" />
The Snowflake destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
[Snowflake](https://www.snowflake.com/) is a managed data platform. Supabase Pipelines replicates each Postgres table to Snowflake as an append-only history of changes.
To replicate data to Snowflake:
@@ -199,61 +199,62 @@ Features in Beta are tested by an external penetration tester for security issue
In addition to the Beta requirements, features in GA are covered by the [uptime SLA](/sla).
| Product | Feature | Stage | Available on self-hosted |
| -------------- | -------------------------- | -------------- | ------------------------------------------- |
| Database | Postgres | `GA` | ✅ |
| Database | Vector Database | `GA` | ✅ |
| Database | Auto-generated Rest API | `GA` | ✅ |
| Database | Auto-generated GraphQL API | `GA` | ✅ |
| Database | Webhooks | `beta` | ✅ |
| Database | Vault | `public alpha` | ✅ |
| Database | Supabase Pipelines | `public alpha` | N/A |
| Platform | | `GA` | ✅ |
| Platform | Point-in-Time Recovery | `GA` | 🚧 [wal-g](https://github.com/wal-g/wal-g) |
| Platform | Custom Domains | `GA` | N/A |
| Platform | Network Restrictions | `GA` | N/A |
| Platform | SSL enforcement | `GA` | N/A |
| Platform | Branching | `beta` | N/A |
| Platform | Terraform Provider | `public alpha` | N/A |
| Platform | Read Replicas | `GA` | N/A |
| Platform | Log Drains | `public alpha` | ✅ |
| Platform | MCP | `public alpha` | ✅ |
| Platform | PrivateLink | `beta` | N/A |
| Studio | | `GA` | ✅ |
| Studio | SSO | `GA` | ✅ |
| Studio | Column Privileges | `public alpha` | ✅ |
| Realtime | Postgres Changes | `GA` | ✅ |
| Realtime | Broadcast | `GA` | ✅ |
| Realtime | Presence | `GA` | ✅ |
| Realtime | Broadcast Authorization | `public beta` | ✅ |
| Realtime | Presence Authorization | `public beta` | ✅ |
| Realtime | Broadcast from Database | `public beta` | ✅ |
| Storage | | `GA` | ✅ |
| Storage | CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Smart CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Image Transformations | `GA` | ✅ |
| Storage | Resumable Uploads | `GA` | ✅ |
| Storage | S3 compatibility | `GA` | ✅ |
| Edge Functions | | `GA` | ✅ |
| Edge Functions | Regional Invocations | `GA` | ✅ |
| Edge Functions | NPM compatibility | `GA` | ✅ |
| Auth | | `GA` | ✅ |
| Auth | Email sign-in | `GA` | ✅ |
| Auth | Social login | `GA` | ✅ |
| Auth | Phone sign-in | `GA` | ✅ |
| Auth | Passwordless sign-in | `GA` | ✅ |
| Auth | SSO with SAML | `GA` | ✅ |
| Auth | Authorization via RLS | `GA` | ✅ |
| Auth | CAPTCHA protection | `GA` | ✅ |
| Auth | Server-side Auth | `beta` | ✅ |
| Auth | Third-Party Auth | `GA` | ✅ |
| Auth | Hooks | `beta` | ✅ |
| CLI | | `GA` | ✅ Works with self-hosted |
| Management API | | `GA` | N/A |
| Client Library | JavaScript | `GA` | N/A |
| Client Library | Flutter | `GA` | N/A |
| Client Library | Swift | `GA` | N/A |
| Client Library | Python | `beta` | N/A |
| Product | Feature | Stage | Available on self-hosted |
| -------------- | -------------------------- | --------------- | ------------------------------------------- |
| Database | Postgres | `GA` | ✅ |
| Database | Vector Database | `GA` | ✅ |
| Database | Auto-generated Rest API | `GA` | ✅ |
| Database | Auto-generated GraphQL API | `GA` | ✅ |
| Database | Webhooks | `beta` | ✅ |
| Database | Vault | `public alpha` | ✅ |
| Database | Supabase Pipelines | `public alpha` | N/A |
| Database | Multigres | `private alpha` | N/A |
| Platform | | `GA` | ✅ |
| Platform | Point-in-Time Recovery | `GA` | 🚧 [wal-g](https://github.com/wal-g/wal-g) |
| Platform | Custom Domains | `GA` | N/A |
| Platform | Network Restrictions | `GA` | N/A |
| Platform | SSL enforcement | `GA` | N/A |
| Platform | Branching | `beta` | N/A |
| Platform | Terraform Provider | `public alpha` | N/A |
| Platform | Read Replicas | `GA` | N/A |
| Platform | Log Drains | `public alpha` | ✅ |
| Platform | MCP | `public alpha` | ✅ |
| Platform | PrivateLink | `beta` | N/A |
| Studio | | `GA` | ✅ |
| Studio | SSO | `GA` | ✅ |
| Studio | Column Privileges | `public alpha` | ✅ |
| Realtime | Postgres Changes | `GA` | ✅ |
| Realtime | Broadcast | `GA` | ✅ |
| Realtime | Presence | `GA` | ✅ |
| Realtime | Broadcast Authorization | `public beta` | ✅ |
| Realtime | Presence Authorization | `public beta` | ✅ |
| Realtime | Broadcast from Database | `public beta` | ✅ |
| Storage | | `GA` | ✅ |
| Storage | CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Smart CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Image Transformations | `GA` | ✅ |
| Storage | Resumable Uploads | `GA` | ✅ |
| Storage | S3 compatibility | `GA` | ✅ |
| Edge Functions | | `GA` | ✅ |
| Edge Functions | Regional Invocations | `GA` | ✅ |
| Edge Functions | NPM compatibility | `GA` | ✅ |
| Auth | | `GA` | ✅ |
| Auth | Email sign-in | `GA` | ✅ |
| Auth | Social login | `GA` | ✅ |
| Auth | Phone sign-in | `GA` | ✅ |
| Auth | Passwordless sign-in | `GA` | ✅ |
| Auth | SSO with SAML | `GA` | ✅ |
| Auth | Authorization via RLS | `GA` | ✅ |
| Auth | CAPTCHA protection | `GA` | ✅ |
| Auth | Server-side Auth | `beta` | ✅ |
| Auth | Third-Party Auth | `GA` | ✅ |
| Auth | Hooks | `beta` | ✅ |
| CLI | | `GA` | ✅ Works with self-hosted |
| Management API | | `GA` | N/A |
| Client Library | JavaScript | `GA` | N/A |
| Client Library | Flutter | `GA` | N/A |
| Client Library | Swift | `GA` | N/A |
| Client Library | Python | `beta` | N/A |
- ✅ = Fully Available
- 🚧 = Available, but requires external tools or configuration
@@ -1,21 +1,19 @@
---
id: 'advisors'
title: 'Advisors'
description: 'Deterministic security and performance findings you or an agent can pull as part of ongoing observability.'
description: 'Health, security, and performance checks you or an agent can run against a project.'
---
Advisors are programmatic checks that ship with the platform. They inspect the live schema and return deterministic findings, such as missing indexes or incorrectly configured RLS policies.
Advisors are deterministic checks that ship with the platform. They flag health, security, and performance issues in your project, such as elevated error rates, misconfigured RLS policies, or missing indexes.
Confirm each finding against the intended schema and access model. Search [Troubleshooting](/docs/guides/troubleshooting) for its check name or affected object; logs can provide additional context but are not required to establish a schema finding.
You or an agent can run them from:
You or an agent can pull the same checks from:
- Studio: [Security Advisor](/dashboard/project/_/advisors/security) and [Performance Advisor](/dashboard/project/_/advisors/performance)
- Studio: [Health Advisor](/dashboard/project/_/advisors/health), [Security Advisor](/dashboard/project/_/advisors/security), and [Performance Advisor](/dashboard/project/_/advisors/performance)
- MCP: `get_advisors` with `type` set to `security` or `performance`
- CLI: [`supabase db advisors`](/docs/reference/cli/supabase-db-advisors)
- Management API: [security advisors](/docs/reference/api/v1-get-security-advisors) and [performance advisors](/docs/reference/api/v1-get-performance-advisors)
- Management API: [security](/docs/reference/api/v1-get-security-advisors), [performance](/docs/reference/api/v1-get-performance-advisors), and [health](/docs/reference/api/v2-run-project-advisors) advisors
Prioritize warning and error findings. Each finding names a check, severity, affected object, and remediation guidance. Informational findings provide context and do not always require a change. The advisors run automatically in Studio. After an authorized fix, rerun the relevant advisor and confirm that the finding no longer appears.
Some findings may be intentional, so check them against your intended schema and access model before you change anything. Health findings can take a while to clear after a fix, since the check measures error rates over a period of time.
## Available checks
@@ -102,6 +102,7 @@ Before you activate your domain, prepare your applications and integrations for
- Supabase Auth will use the custom domain immediately once activated.
- OAuth flows will advertise the custom domain as a callback URL.
- SAML will use the custom domain instead. This means that the `EntityID` of your project has changed, and this may cause SAML with existing identity providers to stop working.
- MCP servers that use Supabase Auth need `authorizationServer` set explicitly to the project Auth issuer, not the custom domain. See [Use a custom domain](/docs/guides/ai-tools/byo-mcp#use-a-custom-domain) in the BYO-MCP guide.
To prevent issues for your users, follow these steps:
@@ -94,3 +94,27 @@ export const databaseNextSteps: ContentListingGroup = {
},
],
}
export const databaseMultigresWhatYouGet: ContentListingGroup = {
id: 'database-multigres-what-you-get',
heading: 'What you get',
description:
'When you enable Multigres on a project, your database runs as a small cluster instead of a single instance:',
type: 'grid',
items: [
{
title: 'Automatic failover',
description:
'If a node fails, another in the cluster is promoted within seconds, without you having to intervene.',
},
{
title: 'No connection changes',
description:
'Use the same connection string. Coordination is transparent to your application.',
},
{
title: 'Consensus-backed durability',
description: 'Writes are acknowledged only after the cluster agrees they are durable.',
},
],
}
+2 -1
View File
@@ -2,7 +2,7 @@ import type { ContentListingGroup } from '~/lib/content-listings.schema'
import { aiToolsBuildingIntoApp, aiToolsSupportedAgents } from './ai-tools.data'
import { authGetStarted, authNextSteps, authPricing } from './auth.data'
import { databaseGetStarted, databaseNextSteps } from './database.data'
import { databaseGetStarted, databaseMultigresWhatYouGet, databaseNextSteps } from './database.data'
import {
functionsExamplesAiMedia,
functionsExamplesMessaging,
@@ -47,6 +47,7 @@ const ALL_GROUPS: readonly ContentListingGroup[] = [
authPricing,
authNextSteps,
databaseGetStarted,
databaseMultigresWhatYouGet,
databaseNextSteps,
functionsGetStarted,
functionsExamplesSupabase,
+55
View File
@@ -0,0 +1,55 @@
/**
* Health advisors read service logs rather than the schema, so they aren't documented in
* splinter alongside the security and performance lints. `DatabaseAdvisorsIndex` prepends
* these, matching the order of the advisors in Studio.
*/
export const healthAdvisors = [
{
path: 'log_data_api_error_rate_high',
content: `**Summary:** Data API error rate is persistently high
**Ramification:** Data API requests are returning 5xx errors, so reads and writes from your app may fail.
***
### How to Resolve
Pull up to five recent 5xx responses on \`/rest/v1\` paths from \`edge_logs\` with their IDs, timestamps, and status. You can use [Logs](/dashboard/project/_/logs/edge-logs) in Studio, the MCP [\`query_logs\`](/docs/guides/observability/advanced-log-filtering#mcp) tool, or the [Management API](/docs/guides/observability/advanced-log-filtering#api). Then follow [API error troubleshooting](/docs/guides/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9).`,
},
{
path: 'log_auth_error_rate_high',
content: `**Summary:** Auth error rate is persistently high
**Ramification:** Users may be unable to sign in or refresh their session.
***
### How to Resolve
Pull up to five recent errors from \`auth_logs\` with their IDs, timestamps, and status. You can use [Logs](/dashboard/project/_/logs/auth-logs) in Studio, the MCP [\`query_logs\`](/docs/guides/observability/advanced-log-filtering#mcp) tool, or the [Management API](/docs/guides/observability/advanced-log-filtering#api). Then use [Auth error codes](/docs/guides/auth/debugging/error-codes) to interpret them.`,
},
{
path: 'log_storage_error_rate_high',
content: `**Summary:** Storage error rate is persistently high
**Ramification:** File uploads and downloads may fail.
***
### How to Resolve
Pull up to five recent errors from \`storage_logs\` with their IDs, timestamps, and status. You can use [Logs](/dashboard/project/_/logs/storage-logs) in Studio, the MCP [\`query_logs\`](/docs/guides/observability/advanced-log-filtering#mcp) tool, or the [Management API](/docs/guides/observability/advanced-log-filtering#api). Then use [Storage error codes](/docs/guides/storage/debugging/error-codes) to interpret them.`,
},
{
path: 'log_edge_function_error_rate_high',
content: `**Summary:** Edge Function error rate is persistently high
**Ramification:** Features that call your Edge Functions may fail.
***
### How to Resolve
Pull up to five recent failed invocations from \`function_edge_logs\` with their IDs, timestamps, and status. You can use [Logs](/dashboard/project/_/logs/edge-functions-logs) in Studio, the MCP [\`query_logs\`](/docs/guides/observability/advanced-log-filtering#mcp) tool, or the [Management API](/docs/guides/observability/advanced-log-filtering#api). Then use [Edge Functions error codes](/docs/guides/functions/error-codes) to interpret them.`,
},
]
@@ -34,6 +34,11 @@ export function serializeContentListingGroupToMarkdown(
}
for (const item of items) {
if (!item.href) {
lines.push(`- **${item.title}:** ${item.description}`)
continue
}
const href = isExternalContentListingHref(item.href)
? item.href
: `${linkBaseUrl}${withDocsBasePath(item.href)}`
@@ -1,5 +1,6 @@
import { readFileSync } from 'node:fs'
import path from 'node:path'
import { healthAdvisors } from '~/data/health-advisors.data'
const ADVISORS_PATH = path.join(process.cwd(), 'features/docs/generated/database-advisors.json')
@@ -11,7 +12,7 @@ interface Lint {
export const DatabaseAdvisorsIndex = (): string => {
const lints: Lint[] = JSON.parse(readFileSync(ADVISORS_PATH, 'utf-8'))
return lints
return [...healthAdvisors, ...lints]
.map(
(lint) => `### ${lint.path}
+36 -3
View File
@@ -147,6 +147,27 @@ describe('serializeContentListingGroupToMarkdown', () => {
)
})
it('renders items without href as unlinked list entries', () => {
const markdown = serializeContentListingGroupToMarkdown(
{
id: 'what-you-get',
heading: 'What you get',
items: [
{
title: 'Automatic failover',
description: 'Another node is promoted if a node goes down.',
},
],
},
'https://supabase.com'
)
expect(markdown).toContain(
'- **Automatic failover:** Another node is promoted if a node goes down.'
)
expect(markdown).not.toContain('](')
})
it('omits heading line when heading is not set', () => {
const markdown = serializeContentListingGroupToMarkdown(
{
@@ -260,9 +281,11 @@ describe('dashboard content listing hrefs', () => {
// Root-relative /dashboard hrefs get the docs basePath and 404; use absolute URLs.
it('uses absolute https://supabase.com dashboard URLs', () => {
const dashboardLinks = Object.values(CONTENT_LISTINGS).flatMap((group) =>
group.items
.filter((item) => isDashboardHref(item.href))
.map((item) => ({ listingId: group.id, title: item.title, href: item.href }))
group.items.flatMap((item) =>
item.href && isDashboardHref(item.href)
? [{ listingId: group.id, title: item.title, href: item.href }]
: []
)
)
expect(dashboardLinks.length).toBeGreaterThan(0)
@@ -275,6 +298,16 @@ describe('dashboard content listing hrefs', () => {
})
})
describe('contentListingItemSchema href', () => {
it('accepts an item without href', () => {
const result = contentListingItemSchema.safeParse({
title: 'Automatic failover',
description: 'Another node is promoted if a node goes down.',
})
expect(result.success).toBe(true)
})
})
describe('contentListingItemSchema icon', () => {
const baseItem = {
title: 'Datadog',
+1 -1
View File
@@ -22,7 +22,7 @@ export const contentListingIconSchema = z.union([z.string().min(1), contentListi
export const contentListingItemSchema = z.object({
title: z.string().min(1),
href: z.string().min(1),
href: z.string().min(1).optional(),
description: z.string().min(1),
/** Shown under the title on grid cards, before the description. */
subtitle: z.string().min(1).optional(),
+4
View File
@@ -539,6 +539,10 @@ Write _microservices_, not _micro-services_.
Use _might_ for possibility or an uncertain outcome.
### Multigres
Use _Multigres_ for the product name. Don't write _multi-gres_ or _MultiGres_.
### must
Use _must_ or _need to_ for a requirement. Don't use _must_ for a recommendation.
+9 -9
View File
@@ -11,6 +11,8 @@ import { defineConfig } from 'astro/config'
import rehypeAdmonitions from './src/lib/mdx/rehype-admonitions.js'
import supabaseTheme from '../learn/lib/themes/supabase-2.json' with { type: 'json' }
import sitemap from '@astrojs/sitemap';
// Absolute dir of lodash-es, for the SSR-only lodash alias below (same fix
// apps/studio/vite.config.ts uses). `packages/ui`'s clipboard util does
// `import { noop } from 'lodash'` — under Vite's dev-mode SSR module runner,
@@ -41,18 +43,16 @@ const ssrLodashEs = {
// https://astro.build/config
export default defineConfig({
site: 'https://supabase.com',
base: '/kb',
trailingSlash: 'ignore',
integrations: [
react(),
// rehype-admonitions is a custom rehype plugin and Astro's default pipeline is
// satteri, so .mdx gets its own unified processor. Plain .md stays on satteri.
mdx({
processor: unified({
rehypePlugins: [rehypeAdmonitions],
}),
integrations: [react(), // rehype-admonitions is a custom rehype plugin and Astro's default pipeline is
// satteri, so .mdx gets its own unified processor. Plain .md stays on satteri.
mdx({
processor: unified({
rehypePlugins: [rehypeAdmonitions],
}),
],
}), sitemap()],
vite: {
ssr: {
noExternal: ['lodash'],
+2
View File
@@ -18,6 +18,7 @@
"@astrojs/markdown-remark": "7.2.4",
"@astrojs/mdx": "^7.0.7",
"@astrojs/react": "^6.0.4",
"@astrojs/sitemap": "^3.7.4",
"astro": "^7.2.6",
"lucide-react": "*",
"react": "catalog:",
@@ -34,6 +35,7 @@
},
"devDependencies": {
"@tailwindcss/vite": "4.2.4",
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"config": "workspace:*",
+1
View File
@@ -59,6 +59,7 @@ const { title, description } = Astro.props
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Manrope:wght@400;500;600;700;800&display=swap"
/>
<link rel="sitemap" href={`${import.meta.env.BASE_URL}/sitemap-index.xml`} />
<title>{title} | Supabase Knowledge Base</title>
</head>
<body>
@@ -1,4 +1,4 @@
import { fireEvent, screen } from '@testing-library/react'
import { fireEvent, screen, within } from '@testing-library/react'
import { platformComponents as components } from 'api-types'
import { mockAnimationsApi } from 'jsdom-testing-mocks'
import { HttpResponse } from 'msw'
@@ -52,16 +52,15 @@ const addBackgroundMocks = () => {
describe('DestinationTypeSelection', () => {
beforeEach(() => {
window.localStorage.clear()
})
test('shows placeholder when no type is selected', async () => {
mockBigQueryEnabled.mockReturnValue(false)
mockIcebergEnabled.mockReturnValue(false)
mockDucklakeEnabled.mockReturnValue(false)
mockSnowflakeEnabled.mockReturnValue(false)
mockClickHouseEnabled.mockReturnValue(false)
addBackgroundMocks()
})
test('shows placeholder when no type is selected', async () => {
customRender(<DestinationTypeSelection />)
expect(await screen.findByText('Select a destination type')).toBeInTheDocument()
@@ -71,69 +70,53 @@ describe('DestinationTypeSelection', () => {
mockBigQueryEnabled.mockReturnValue(true)
mockIcebergEnabled.mockReturnValue(true)
mockDucklakeEnabled.mockReturnValue(true)
mockSnowflakeEnabled.mockReturnValue(false)
mockClickHouseEnabled.mockReturnValue(false)
addBackgroundMocks()
mockSnowflakeEnabled.mockReturnValue(true)
mockClickHouseEnabled.mockReturnValue(true)
customRender(<DestinationTypeSelection />)
fireEvent.click(await screen.findByRole('combobox'))
expect(await screen.findByText('Public Alpha')).toBeInTheDocument()
expect(screen.getByText('Early Access')).toBeInTheDocument()
const publicAlphaGroup = await screen.findByRole('group', { name: 'Public Alpha' })
expect(screen.queryByText('Early Access')).not.toBeInTheDocument()
expect(screen.getByText('Deprecated')).toBeInTheDocument()
expect(screen.getByText('BigQuery')).toBeInTheDocument()
expect(screen.getByText('DuckLake')).toBeInTheDocument()
for (const destination of ['BigQuery', 'ClickHouse', 'DuckLake', 'Snowflake']) {
expect(within(publicAlphaGroup).getByText(destination)).toBeInTheDocument()
}
expect(screen.getByText('Analytics Bucket')).toBeInTheDocument()
expect(screen.queryByText('Pipelines')).not.toBeInTheDocument()
})
test('hides destinations behind disabled feature flags', async () => {
mockBigQueryEnabled.mockReturnValue(false)
mockIcebergEnabled.mockReturnValue(false)
mockDucklakeEnabled.mockReturnValue(false)
mockSnowflakeEnabled.mockReturnValue(false)
mockClickHouseEnabled.mockReturnValue(false)
addBackgroundMocks()
customRender(<DestinationTypeSelection />)
fireEvent.click(await screen.findByRole('combobox'))
expect(screen.queryByText('Read Replica')).not.toBeInTheDocument()
expect(screen.queryByText('BigQuery')).not.toBeInTheDocument()
expect(screen.queryByText('DuckLake')).not.toBeInTheDocument()
expect(screen.queryByText('Analytics Bucket')).not.toBeInTheDocument()
expect(screen.queryByText('Pipelines')).not.toBeInTheDocument()
expect(screen.queryAllByRole('option')).toHaveLength(0)
})
test('shows the public alpha warning for a Pipelines destination', async () => {
mockBigQueryEnabled.mockReturnValue(true)
mockIcebergEnabled.mockReturnValue(false)
mockDucklakeEnabled.mockReturnValue(false)
mockSnowflakeEnabled.mockReturnValue(false)
mockClickHouseEnabled.mockReturnValue(false)
addBackgroundMocks()
test.each(['BigQuery', 'ClickHouse', 'DuckLake', 'Snowflake'])(
'shows the public alpha warning for %s',
async (destination) => {
mockBigQueryEnabled.mockReturnValue(true)
mockDucklakeEnabled.mockReturnValue(true)
mockSnowflakeEnabled.mockReturnValue(true)
mockClickHouseEnabled.mockReturnValue(true)
customRender(<DestinationTypeSelection />)
customRender(<DestinationTypeSelection />)
fireEvent.click(await screen.findByRole('combobox'))
fireEvent.click(await screen.findByText('BigQuery'))
fireEvent.click(await screen.findByRole('combobox'))
fireEvent.click(await screen.findByText(destination))
expect(
await screen.findByText(
'Destination type cannot be changed after creation. BigQuery support is in public alpha.'
)
).toBeInTheDocument()
})
expect(
await screen.findByText(
`Destination type cannot be changed after creation. ${destination} support is in public alpha.`
)
).toBeInTheDocument()
}
)
test('disables the selector in edit mode so the destination type cannot be changed', async () => {
mockBigQueryEnabled.mockReturnValue(true)
mockIcebergEnabled.mockReturnValue(false)
mockDucklakeEnabled.mockReturnValue(false)
mockSnowflakeEnabled.mockReturnValue(false)
mockClickHouseEnabled.mockReturnValue(false)
addBackgroundMocks()
// Edit mode triggers useDestinationInformation({ id: 1 }) which fires destination-by-id
addAPIMock({
method: 'get',
@@ -25,7 +25,7 @@ interface DestinationTypeOption {
value: DestinationType
label: string
description: string
stage: 'Public Alpha' | 'Early Access' | 'Deprecated' | null
stage: 'Public Alpha' | 'Deprecated' | null
enabled: boolean
}
@@ -78,30 +78,25 @@ export const DestinationTypeSelection = () => {
stage: 'Public Alpha',
enabled: isOptionVisible('BigQuery', etlEnableBigQuery),
},
],
},
{
label: 'Early Access',
options: [
{
value: 'DuckLake',
label: 'DuckLake',
description: 'Replicate changes to DuckLake for open lakehouse storage',
stage: 'Early Access',
stage: 'Public Alpha',
enabled: isOptionVisible('DuckLake', etlEnableDucklake),
},
{
value: 'Snowflake',
label: 'Snowflake',
description: 'Replicate changes to Snowflake for cloud data warehousing',
stage: 'Early Access',
stage: 'Public Alpha',
enabled: isOptionVisible('Snowflake', etlEnableSnowflake),
},
{
value: 'ClickHouse',
label: 'ClickHouse',
description: 'Replicate changes to ClickHouse for real-time analytics',
stage: 'Early Access',
stage: 'Public Alpha',
enabled: isOptionVisible('ClickHouse', etlEnableClickHouse),
},
],
@@ -132,7 +127,6 @@ export const DestinationTypeSelection = () => {
(type: DestinationType) => string
> = {
'Public Alpha': (type) => `${type} support is in public alpha.`,
'Early Access': (type) => `${type} support is in early access.`,
Deprecated: (type) => `${type} is deprecated.`,
}
@@ -37,7 +37,7 @@ export function HighAvailabilityBadge({ size = 'default' }: HighAvailabilityBadg
globally distributed deployments.
</p>
<Link
href={`${DOCS_URL}/guides/deployment/high-availability`}
href={`${DOCS_URL}/guides/database/multigres`}
target="_blank"
rel="noopener noreferrer"
className="mt-1 inline-flex items-center gap-1 text-xs text-foreground-lighter transition-colors hover:text-foreground"
@@ -11,6 +11,8 @@ date: '2025-12-02T11:00'
toc_depth: 2
---
> **Update: October 2, 2026.** BigQuery, ClickHouse, DuckLake, and Snowflake are now available in public alpha. The destination early-access form has been retired. To get started, see the [destination guides](/docs/guides/database/replication#supported-destinations). The original announcement follows.
Today we're introducing **Supabase Pipelines**: managed change-data-capture pipelines that replicate your Postgres tables to analytical destinations in near real time.
Pipelines reads changes from your Postgres database and writes them to supported destination systems. It uses logical replication to capture inserts, updates, deletes, and truncates as they happen. **Setup takes minutes in the Supabase Dashboard.**
@@ -14,6 +14,8 @@ date: '2026-07-21'
toc_depth: 2
---
> **Update: October 2, 2026.** BigQuery, ClickHouse, DuckLake, and Snowflake are now available in public alpha. The destination early-access form has been retired. To get started, see the [destination guides](/docs/guides/database/replication#supported-destinations). The original announcement follows.
Today we're moving **Supabase Pipelines** into public alpha. The biggest addition is schema change support: Pipelines can now detect supported schema changes in your source tables and apply them to the destination automatically. This release also brings a faster initial sync and a new destination request form for ClickHouse, Snowflake, and DuckLake.
Supabase Pipelines replicates your Supabase Postgres data to external analytical systems in near real time. It is powered by [Supabase ETL](https://github.com/supabase/etl), our open source change-data-capture pipeline written in Rust. Supabase ETL reads changes from Postgres through logical replication, copies existing table data, streams inserts, updates, deletes, and truncates, and writes them to your destination.
@@ -0,0 +1,72 @@
---
title: 'Build anything: Supabase from code, and an MCP server for your app'
description: "Your agent sets up the backend from code, your users' agents work with your app through its own MCP server, and long-running tasks run in Supabase Compute."
author: wenbo, laktek, jgoux, avallete, rand_arete, katerina_skroumpelou
date: '2026-10-02T10:15:00'
categories:
- product
tags:
- ai
- mcp
- developer-tools
imgSocial: 'select-2026-build-anything/og.png'
imgThumb: 'select-2026-build-anything/thumb.png'
toc_depth: 2
---
Today at Supabase Select, we announced new tools that let your coding agent set up your backend, test changes locally, and deploy the services behind your app. We also gave your users’ agents a way to work inside your app as the signed-in user. Your agent already writes your application code, but the backend was still your job, because most of that work happened in the dashboard: create a table, change an RLS policy, then pull the change into a migration with the CLI. Your agent works in your repo, and changes made in the dashboard don't appear there.
Now your schema and project config can live in your repo, where your agent can work on them. The agent writes the schema as SQL files, and `pg-delta` works out the migration. A setting changed in the dashboard comes back to your config file with one command. Before a change ships, your agent can try it locally: local development doesn’t need Docker, and each directory gets its own stack, so the agent can test two changes side by side and keep the one that works.
Many apps require long-running processes: agents, embeddings for a large set agents, embeddings for a large set of files, a service that stays up, or code that needs its own sandbox. Supabase Compute runs that work as a long-lived service in the same project as your database.
Your users are already in Claude, ChatGPT, or Cursor, and when one of them asks their agent to do something in your app, the agent needs a way in. Your app can now have its own MCP server, deployed inside the Supabase project you already have. Users sign in the way they already do, and their agent sees only what they're allowed to see.
## Agent-ready local development
<video className="wide rounded-md border m-0 w-full" autoPlay loop muted playsInline controls>
<source src="/images/blog/select-2026-build-anything/autonomy.mp4" type="video/mp4" />
</video>
Local Supabase can now run as native processes, so it starts on machines without a Docker daemon: Claude Code's sandbox, Codex, Perplexity Computer, and CI runners. On a machine with Docker, nothing changes. You can also run multiple local Supabase instances, one per directory, so several checkouts or git worktrees of the same repo run at the same time. It's in alpha today, off by default.
Declarative Schemas 2.0: coding agents are good at editing schema files and bad at writing migrations. Your agent edits the SQL files, which are the source of truth, and `pg-delta`, the CLI's new diff engine, generates the migration from them. New projects created with `supabase init` use `pg-delta` by default, and existing projects can turn it on in `config.toml`.
Config in code: settings like auth providers, API limits, and storage buckets live in `config.toml` next to the schema. A setting changed in the dashboard comes back into the file with `supabase config pull`, and `supabase pull` pulls config, schema, and Edge Functions in one command.
## Supabase Compute
<Img
alt="A Compute service defined in config.toml and deployed with supabase compute deploy, running three instances with 2 GB RAM and 1 CPU"
src="/images/blog/select-2026-build-anything/compute.png"
wide
/>
Compute runs web services and agents in any language next to your database. There's no limit on how long a service runs, you choose the memory and CPU, and each service gets a full Linux environment, which Edge Functions don't have.
Deploy from the Supabase CLI, or manage services through the Management API. The service definition lives in `config.toml`, and agent skills for Compute let your coding agent write, deploy, monitor, and debug a service for you. A service gets the same default environment variables as your Edge Functions, so it connects to your database and other Supabase services. In the dashboard you see each service's runtime, invocations, and logs.
Each service gets a public HTTP URL, like an Edge Function. Set the number of instances, and Supabase balances requests across them. You can also deploy a service as private, with no HTTP endpoint, for background jobs from a database queue or as a sandbox for an agent. To tighten security further, network restrictions can limit database access to your Compute instances.
## Your app's MCP server
<Img
alt="The MCP Server block in the Supabase library, showing the files it adds under supabase/functions/mcp"
src="/images/blog/select-2026-build-anything/mcp-server.png"
wide
/>
MCP is the standard that lets agents talk to your app on behalf of your users. Your app's MCP server is separate from the official Supabase MCP server, which helps you build your app.
Add a customizable MCP server to your own app from the [Supabase library](https://supabase.com/library). One shadcn command adds an authenticated Edge Function to your codebase, ready to deploy to Supabase. You own the code, so your agent can use the included instructions and Supabase client to add the tools that fit your product, and your RLS policies still decide which rows each user can reach.
It's built on `@supabase/server` and the new Supabase Middleware, which also work on their own in any server code that needs to know who is signed in.
We also built a [headless app template](https://supabase.com/library/docs/tanstack/headless-app): a backend with an agent as the main interface, ready to deploy to Supabase.
## Get started
- Agent-ready local development: update the [Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started), then add `[experimental]` and `stack = true` to `supabase/config.toml`, or set `SUPABASE_EXPERIMENTAL_STACK=1`.
- Declarative Schemas 2.0: put your schema in `supabase/schemas/*.sql`, run `supabase db schema declarative sync` to generate and apply the migration locally, then run `supabase db push`. Existing projects: add `[experimental.pgdelta]` and `enabled = true` to `supabase/config.toml`. [Docs](https://supabase.com/docs/guides/local-development/declarative-database-schemas).
- Supabase Compute: in private alpha. [Join the waitlist](https://supabase.com/compute).
- Your app's MCP server: get your project into code with `supabase pull`, then run `npx shadcn@latest add @supabase/mcp-server` from the [MCP server block](https://supabase.com/library/docs/headless/mcp). It needs asymmetric signing keys and the Supabase Auth OAuth server turned on.
@@ -0,0 +1,128 @@
---
title: 'Operate with confidence'
description: 'More data, more tools and more control so your agent has what it needs to observe your project, investigate issues and propose fixes, autonomously.'
author: steven_eubank, joshenlim, cemal_kilic, riccardo_busetti, joe_sciarrino
date: '2026-10-02T10:25:00'
categories:
- product
tags:
- ai
- mcp
- observability
imgSocial: 'select-2026-operate-with-confidence/og.png'
imgThumb: 'select-2026-operate-with-confidence/thumb.png'
toc_depth: 2
---
Today at Supabase Select, we announced new tools that let your coding agent find production problems, test fixes, and report back, and new controls that set what the agent can access and when it stops to ask you first.
Diagnosing a production problem today means reading logs, usage charts, and database reports separately and correlating them yourself. Your agent could already read that data, but it had no procedure for investigating and no safe place to test a fix.
For an agent to confidently operate a project:
- It needs [data](#data) to observe
- It needs [knowledge](#knowledge) on what to look for in that data
- It needs [autonomy](#autonomy) to test and validate fixes in its own environment
- It needs [permission](#permissions) to do only what is required
## Data
### query_logs
Previously your agents were limited in what logs they could access via our MCP. We’ve introduced a new MCP tool that gives your agents raw access to your project logs via SQL, which enables more in-depth and precise investigations.
### More advisor checks
<Img
alt="Health Advisor in the Supabase dashboard flagging persistently high Data API and Edge Function error rates"
src="/images/blog/select-2026-operate-with-confidence/health-check.png"
wide
/>
Programmatic checks can catch obvious issues and provide signal for an agent to investigate further. Advisor previously focused on security and performance checks. We’ve now extended it to health. Advisor will signal when error rates go beyond what is considered normal across Data API, Auth, Storage, and Edge Functions. Checks run on demand from the dashboard or the Management API, and results show up under a new Health tab on the Advisors page.
### Database Connections
<Img
alt="Database Connections page showing connections, active queries, idle in transaction, and blocked queries"
src="/images/blog/select-2026-operate-with-confidence/connections.png"
wide
/>
See which sessions hold connections, which queries run long, which are idle in a transaction, which are blocked, and who holds the lock. You can cancel a query or terminate its connection from there. It's on by default for every project, including self-hosted.
### Introducing Notebooks
<Img
alt="A notebook in Explorer combining markdown notes with database queries and charts"
src="/images/blog/select-2026-operate-with-confidence/notebooks.png"
wide
/>
A notebook is a file in your supabase folder that combines saved database or log queries with markdown notes. Run Notebooks yourself or get your agents to run them as part of their ongoing observations. You can create notebooks directly in the dashboard via the Assistant, then pull them down locally as files with `supabase notebooks pull` if needed. You can also create notebooks locally (including with your own agent) and push them with `supabase notebooks push` to make them accessible in the dashboard.
Notebooks can be found in the new Explorer, an evolution of the SQL editor, which is rolling out to every project through October 12. Once it reaches your project, you can turn it on under Feature Previews in the dashboard. Notebook CLI tools are available in the beta version of our CLI.
## Knowledge
### Updated Skills
Supabase skills now point to a living document of common health, security, performance, and resource signals your agent should watch for and how to monitor those signals.
```bash
npm install supabase --save-dev
npx plugins add supabase-community/supabase-plugin
```
## Autonomy
<video className="wide rounded-md border m-0 w-full" autoPlay loop muted playsInline controls>
<source src="/images/blog/select-2026-operate-with-confidence/autonomy.mp4" type="video/mp4" />
</video>
Agents operate best in code. Today at Supabase Select we announced several improvements to how Supabase projects are expressed as code, and how that code can run in more environments. This is an important upgrade for the observing → detection → resolving loop: it lets agents test and validate proposed fixes in their own environment before opening a PR. That environment may not be your local machine.
Read more about pg-delta and upgrades to the local runtime in the [Build post](https://supabase.com/blog/select-2026-build-anything).
## Permissions
Give your agent only the access it needs to do its job, and get alerted when it attempts a riskier action.
### Enterprise-Managed Auth for MCP
Your company decides who can connect to the Supabase MCP server through its identity provider, starting with Okta. Each token is short-lived and bound to the member who signed in. To cut off access, remove the app from Authorized Apps, or remove the member. This is generally available.
### Scoped Personal Access Tokens
Limit a token to the organizations, projects, and permissions you choose. Start with a read-only token. It's generally available and is now the default for new tokens created in the dashboard.
### MCP Elicitations
<video className="wide rounded-md border m-0 w-full" autoPlay loop muted playsInline controls>
<source
src="/images/blog/select-2026-operate-with-confidence/mcp-elicitations.mp4"
type="video/mp4"
/>
</video>
Before the agent creates a paid project or branch, the Supabase MCP server asks you to confirm the resource, rate, and billing interval in your agent client, then waits for your answer. It also asks for confirmation before running SQL that could delete data. This helps prevent unwanted charges and data loss, but it’s not a guarantee. Your agent client must support elicitations for the prompt to appear.
## Supabase Pipelines
<video className="wide rounded-md border m-0 w-full" autoPlay loop muted playsInline controls>
<source src="/images/blog/select-2026-operate-with-confidence/pipelines.mp4" type="video/mp4" />
</video>
Pipelines stream your Postgres data to analytical destinations in near real time, so heavy analytics queries don’t impact primary Postgres. Create a pipeline in the dashboard, choose the destination, and select the tables to replicate. The initial sync starts, and schema changes are detected and applied to the destination automatically. The dashboard shows each pipeline's health and the status of every replicated table.
Pipelines are in public alpha on the Pro, Team, and Enterprise plans, with BigQuery, ClickHouse, DuckLake, and Snowflake as destinations.
## Getting started
Setting up an agent that autonomously observes your project, detects issues, and proposes fixes can be daunting, but it’s really only a prompt away with your favorite agent harness. We’ve created a few prompts and suggested schedules to set your agent up for success.
- [Health](https://supabase.com/docs/guides/observability/automate-with-agents/health)
- [Security](https://supabase.com/docs/guides/observability/automate-with-agents/security)
- [Performance](https://supabase.com/docs/guides/observability/automate-with-agents/performance)
- [Resources](https://supabase.com/docs/guides/observability/automate-with-agents/usage)
- Supabase Pipelines: on a paid plan, open Database, then Pipelines in the Dashboard, add a BigQuery, ClickHouse, DuckLake, or Snowflake destination, and pick your tables. [Docs](https://supabase.com/docs/guides/database/replication/pipelines).
@@ -0,0 +1,140 @@
---
title: 'Scale without limits: Multigres, OrioleDB, and dbarena'
description: 'The app your agent built in minutes stays on the same Postgres from prototype to petabyte.'
author: joe_sciarrino, alexander_korotkov, daniel_mitterdorfer, aditya_maruvada
date: '2026-10-02T10:35:00'
categories:
- product
tags:
- postgres
- database
- scaling
imgSocial: 'select-2026-scale-without-limits/og.png'
imgThumb: 'select-2026-scale-without-limits/thumb.png'
toc_depth: 2
---
Today at Supabase Select, we announced Multigres for high availability and scalable connection pooling, and OrioleDB for high performance storage. We launched dbarena, an open benchmarks site for comparing managed Postgres providers’ performance results and costs.
Every Supabase project starts with a single Postgres database. As your project grows, vertically upgrading the database’s available RAM & CPU resources can help, but it isn’t a solution to every challenge.
Scaling Postgres isn’t a singular problem — users encounter new challenges at different stages of scale and under different workloads. Our users often report needing help scaling concurrent client connections, reducing the overhead of bloat and frequent VACUUM operations, increasing read and write throughput, avoiding transaction ID wraparound, and guaranteeing uptime with high availability.
Our focus is to remove every scaling limitation from our users’ journey. That means tackling bottlenecks at every layer of Postgres, building in public, and making the improvements fully open source and available to the broader builder community.
<svg
className="-mb-8 mt-12 not-sr-only"
aria-hidden="true"
width="101"
height="40"
viewBox="0 0 101 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_2218_147314)">
<path
d="M31.3735 4.16153V3.17301H37.4313V4.16153H31.3735ZM33.9081 6.69618V0.638357H34.8967V6.69618H33.9081ZM53.3111 3.90806V2.91955H59.0648V3.90806H53.3111ZM39.6747 3.90806V2.91955H45.4157V3.90806H39.6747ZM46.4929 3.90806V2.91955H52.2339V3.90806H46.4929ZM61.4685 4.16153V3.17301H67.5264V4.16153H61.4685ZM64.0032 6.69618V0.638357H64.9917V6.69618H64.0032ZM16.326 20.1615V19.173H22.3838V20.1615H16.326ZM18.8606 22.6962V16.6384H19.8491V22.6962H18.8606ZM38.2636 19.9081V18.9195H44.0173V19.9081H38.2636ZM24.6272 19.9081V18.9195H30.3681V19.9081H24.6272ZM31.4454 19.9081V18.9195H37.1864V19.9081H31.4454ZM46.421 20.1615V19.173H52.4788V20.1615H46.421ZM48.9557 22.6962V16.6384H49.9442V22.6962H48.9557ZM68.3587 19.9081V18.9195H74.1123V19.9081H68.3587ZM54.7222 19.9081V18.9195H60.4632V19.9081H54.7222ZM61.5404 19.9081V18.9195H67.2814V19.9081H61.5404ZM76.5161 20.1615V19.173H82.5739V20.1615H76.5161ZM79.0507 22.6962V16.6384H80.0393V22.6962H79.0507ZM1.27844 36.1615V35.173H7.33626V36.1615H1.27844ZM3.81309 38.6962V32.6384H4.80161V38.6962H3.81309ZM23.2161 35.9081V34.9195H28.9697V35.9081H23.2161ZM9.57963 35.9081V34.9195H15.3206V35.9081H9.57963ZM16.3978 35.9081V34.9195H22.1388V35.9081H16.3978ZM31.3735 36.1615V35.173H37.4313V36.1615H31.3735ZM33.9081 38.6962V32.6384H34.8967V38.6962H33.9081ZM53.3111 35.9081V34.9195H59.0648V35.9081H53.3111ZM39.6747 35.9081V34.9195H45.4157V35.9081H39.6747ZM46.4929 35.9081V34.9195H52.2339V35.9081H46.4929ZM61.4685 36.1615V35.173H67.5264V36.1615H61.4685ZM64.0032 38.6962V32.6384H64.9917V38.6962H64.0032ZM83.4062 35.9081V34.9195H89.1598V35.9081H83.4062ZM69.7697 35.9081V34.9195H75.5107V35.9081H69.7697ZM76.588 35.9081V34.9195H82.329V35.9081H76.588ZM91.5636 36.1615V35.173H97.6214V36.1615H91.5636ZM94.0983 38.6962V32.6384H95.0868V38.6962H94.0983Z"
fill="#797B72"
/>
</g>
<defs>
<clipPath id="clip0_2218_147314">
<rect width="100.99" height="40" fill="white" />
</clipPath>
</defs>
</svg>
## Multigres
<video className="wide rounded-md border m-0 w-full" autoPlay loop muted playsInline controls>
<source src="/images/blog/select-2026-scale-without-limits/failover.mp4" type="video/mp4" />
</video>
Multigres is an open source operating system for Postgres, built by the team behind Vitess. It adds scalable connection pooling and automated multi-node failover to Postgres out-of-the-box. With Multigres, there's no separate pooler to run, and your app can connect far more clients than one Postgres instance can hold.
Many developers are familiar with basic Primary / Standby HA architecture and its known issues. Traditionally, if the primary database fails before data has been replicated to the standby, those rows may be lost. In contrast, Multigres uses a generalized consensus protocol built on top of postgres synchronous replication. If a Multigres node fails, the cluster agrees on exactly which writes were committed before accepting new ones, then promotes a replica in seconds. You keep every committed write through the failover.
Multigres runs three Postgres nodes across availability zones in one region, so losing one zone doesn't take your database down. You don't need to change your application code to move to Multigres.
You can also add read replicas and gateways for more read throughput and client connections. During the alpha, our team adds them for you.
Multigres is in private alpha, by invite. It works with Supabase Auth, Storage, and Edge Functions, and it's built for testing during the alpha, not production workloads. [Request access](https://supabase.com/go/multigres-early-access).
<svg
className="-mb-8 mt-12 not-sr-only"
aria-hidden="true"
width="109"
height="40"
viewBox="0 0 109 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_2218_147312)">
<path
d="M1.35291 6.98767V5.89776L6.34617 3.66727V3.81935L1.35291 1.58885V0.498951L7.13192 3.07163V4.41499L1.35291 6.98767ZM31.448 6.98767V5.89776L36.4412 3.66727V3.81935L31.448 1.58885V0.498951L37.227 3.07163V4.41499L31.448 6.98767ZM38.9717 6.98767V5.89776L43.965 3.66727V3.81935L38.9717 1.58885V0.498951L44.7507 3.07163V4.41499L38.9717 6.98767ZM69.0668 6.98767V5.89776L74.06 3.66727V3.81935L69.0668 1.58885V0.498951L74.8458 3.07163V4.41499L69.0668 6.98767ZM76.5905 6.98767V5.89776L81.5838 3.66727V3.81935L76.5905 1.58885V0.498951L82.3696 3.07163V4.41499L76.5905 6.98767ZM84.1143 6.98767V5.89776L89.1076 3.66727V3.81935L84.1143 1.58885V0.498951L89.8933 3.07163V4.41499L84.1143 6.98767ZM1.35291 22.9877V21.8978L6.34617 19.6673V19.8193L1.35291 17.5889V16.499L7.13192 19.0716V20.415L1.35291 22.9877ZM31.448 22.9877V21.8978L36.4412 19.6673V19.8193L31.448 17.5889V16.499L37.227 19.0716V20.415L31.448 22.9877ZM38.9717 22.9877V21.8978L43.965 19.6673V19.8193L38.9717 17.5889V16.499L44.7507 19.0716V20.415L38.9717 22.9877ZM69.0668 22.9877V21.8978L74.06 19.6673V19.8193L69.0668 17.5889V16.499L74.8458 19.0716V20.415L69.0668 22.9877ZM76.5905 22.9877V21.8978L81.5838 19.6673V19.8193L76.5905 17.5889V16.499L82.3696 19.0716V20.415L76.5905 22.9877ZM84.1143 22.9877V21.8978L89.1076 19.6673V19.8193L84.1143 17.5889V16.499L89.8933 19.0716V20.415L84.1143 22.9877ZM1.35291 38.9877V37.8978L6.34617 35.6673V35.8193L1.35291 33.5889V32.499L7.13192 35.0716V36.415L1.35291 38.9877ZM31.448 38.9877V37.8978L36.4412 35.6673V35.8193L31.448 33.5889V32.499L37.227 35.0716V36.415L31.448 38.9877ZM38.9717 38.9877V37.8978L43.965 35.6673V35.8193L38.9717 33.5889V32.499L44.7507 35.0716V36.415L38.9717 38.9877ZM69.0668 38.9877V37.8978L74.06 35.6673V35.8193L69.0668 33.5889V32.499L74.8458 35.0716V36.415L69.0668 38.9877ZM76.5905 38.9877V37.8978L81.5838 35.6673V35.8193L76.5905 33.5889V32.499L82.3696 35.0716V36.415L76.5905 38.9877ZM84.1143 38.9877V37.8978L89.1076 35.6673V35.8193L84.1143 33.5889V32.499L89.8933 35.0716V36.415L84.1143 38.9877Z"
fill="#797B72"
/>
</g>
<defs>
<clipPath id="clip0_2218_147312">
<rect width="108.515" height="40" fill="white" />
</clipPath>
</defs>
</svg>
## OrioleDB
<video
alt="Postgres heap leaves dead row versions in the table and needs VACUUM, while OrioleDB moves old versions to an undo log and reclaims space automatically"
className="wide rounded-md border m-0 w-full"
poster="/images/blog/select-2026-scale-without-limits/orioledb.png"
autoPlay
loop
muted
playsInline
controls
>
<source src="/images/blog/select-2026-scale-without-limits/orioledb.mp4" type="video/mp4" />
</video>
OrioleDB is an open source, scalable storage engine for Postgres. It replaces Postgres traditional heap storage and eliminates its fundamental limitations, such as table bloat, VACUUM overhead, and txid wraparound inherent to the limited range of 32-bit transaction IDs.
With heap storage, Postgres never updates a row in place: every update writes a new row version and leaves the old one behind as a dead tuple. On hot tables with frequent updates and deletes, this creates significant bloat over time, and cleaning it up requires constant VACUUM activity. VACUUM is one of the most common causes of Postgres performance degradation and outages under load. Teams typically mitigate it with careful tuning, scheduled `pg_repack` runs, and over-provisioned compute.
OrioleDB's undo log removes this problem at the source. Instead of leaving dead tuples behind, updates and deletes write page-level undo records, which the system reclaims automatically. This eliminates bloat entirely and VACUUM is no longer needed.
Allowing lock-free page reads also makes OrioleDB more efficient under high concurrency, especially in IOPS use. OrioleDB delivers up to 1.8x higher throughput than Postgres heap in our public, TPC-C-derived benchmarks, published on [dbarena.com](https://dbarena.com/).
<Admonition type="note">
During the public beta, you can choose OrioleDB under advanced configuration when you create a project. You can also use OrioleDB and heap storage per table in one project, with `USING orioledb` or `USING heap`.
</Admonition>
OrioleDB uses 64-bit transaction IDs (XIDs) by default, so it avoids Postgres's wraparound problem. With 32-bit XIDs, wraparound hits after roughly 4 billion transactions and forces the database to aggressively freeze old rows. With heap storage, XIDs are directly stored in every tuple, so expanding them from 32 to 64 bits would add 8 bytes to every row version. That simple 8-byte change cascades across billions of row versions with dead tuples, resulting in more pages, more I/O, greater cache pressure, and larger indexes.
Because OrioleDB replaces heap's vacuum-based MVCC with an undo log, it sidesteps this constraint entirely: transaction metadata can use 64-bit XIDs without inheriting heap's legacy tuple format.
OrioleDB has been under active development by the Supabase team and open source contributors since 2021. Supabase employs the engine's creators, including major Postgres contributor Alexander Korotkov, who have shipped eighteen beta releases.
## dbarena
<Img
alt="A dbarena comparison of two XLarge configurations, showing throughput per dollar, monthly cost, throughput, p95 latency, and throughput over time"
src="/images/blog/select-2026-scale-without-limits/dbarena.png"
wide
/>
[dbarena.com](https://dbarena.com) publishes open, reproducible database benchmarks across providers: the benchmark code, published methodology, downloadable raw data per result, and shareable comparison links. It compares Supabase, Amazon RDS, and Google Cloud SQL at launch. For each run, dbarena reports transactions per dollar, monthly total cost, transactions per minute, p95, and machine specs, and it plots throughput over time.
Developers evaluating hosted Postgres have few trustworthy sources for comparing providers. Vendor benchmarks often run under favorable conditions, community benchmarks are one-off snapshots, and a rigorous in-house evaluation costs weeks to produce.
dbarena follows three rules: every published result can be checked independently, comparisons are normalized for cost, and the methodology is public.
Subscribe to the [dbarena newsletter](https://dbarena.com/?subscribe) to keep up with the latest comparisons and performance tracking over time.
## Get started
- Multigres: private alpha. [Request access](https://supabase.com/go/multigres-early-access).
- OrioleDB: create a new project and choose OrioleDB at project creation. Public beta. [Docs](https://supabase.com/docs/guides/database/orioledb).
- dbarena: public, at [dbarena.com](https://dbarena.com).
@@ -0,0 +1,43 @@
---
title: 'Supabase is acquiring Turso'
description: 'Supabase is acquiring Turso to build the database infrastructure for agentic AI'
author: paul_copplestone
date: '2026-10-02T09:00:00'
categories:
- company
tags:
- ai
- open-source
- database
imgSocial: '2026-10-02-supabase-is-acquiring-turso/thumb.png'
imgThumb: '2026-10-02-supabase-is-acquiring-turso/thumb.png'
toc_depth: 2
---
AI is enabling builders to create an immense amount of software. Today, agents are spinning up millions of databases to power the prototypes, explorations, dashboards, and apps they're building. This new pattern, at this massive scale, requires an evolution in database infrastructure. Turso is joining Supabase to build this evolution.
For existing users, nothing changes. Supabase will continue building around Postgres, while Turso will continue its work on SQLite. And together, we’re creating something new that will bring the Supabase experience to every agent.
## Databases for agents
Supabase is already launching over one million databases per week. As agents build more software, we believe database demand will outpace the world’s current capacity to support them. So we need infrastructure that can scale to meet this growth and is suited to how we build with agents.
Agents should be able to create a database as easily as creating a file, with just as little concern about cost. For smaller workloads, that shouldn’t require provisioning a dedicated machine every time. Databases should be cheap to create, available on demand, and have a clear path to production when needed.
SQLite is well suited to these small, on-demand workloads. Postgres is what you want as your application scales. We want builders to have the same developer experience from prototyping to production.
## Turso
Turso has built an architecture for exactly this pattern. They rebuilt SQLite in Rust and created a cloud platform where a single server can manage millions of databases, loading them when needed and suspending them when they’re not.
This architecture makes it possible to provision a database for each agent on demand, whether on Turso Cloud or in customers’ own clouds, as Superhuman, Sauna.ai, CTO.new, and Mastra do.
We share a vision for how infrastructure needs to evolve to support agentic AI. Turso will continue operating, with a clear path into the broader Supabase ecosystem as workloads grow.
## Open source
Turso and Supabase have a lot in common: a commitment to open source, a focus on developer experience, and an appetite to tackle hard infrastructure problems.
We’re excited to welcome Glauber Costa and Pekka Enberg to Supabase with the rest of the Turso team. Glauber will lead this agentic infrastructure effort.
Our mission is to store the world’s data, and agents are going to create a lot more of it. This gets us closer to that goal.
@@ -0,0 +1,99 @@
---
title: 'Supabase Select 2026 Recap'
description: 'Build anything, operate with confidence, scale without limits. Supabase carries your application from prototype to petabyte.'
author: oli_rice, inian, jonny
date: '2026-10-02T10:50:00'
categories:
- product
tags:
- ai
- mcp
- postgres
imgSocial: 'supabase-select-2026-recap/og.png'
imgThumb: 'supabase-select-2026-recap/thumb.png'
toc_depth: 2
---
Today at Supabase Select, we showed how Supabase works for your app from day one to millions of users, and how your agent builds and runs it with you.
Your coding agent already writes your application code. Setting up the backend is still your job. So is watching it in production and fixing it when it breaks. That work happens in the dashboard and the docs, and your agent can't do it end to end.
Supabase now works code first. Schema and config can live in code, so your agent can set up and change a project the same way you do. It can also check the project and report the problems it finds. You decide what gets fixed and merged.
You can build anything, because your agent works in the same code you do. You can operate with confidence, because your agent finds problems and you decide what merges. And you can scale without limits, because when the app grows, the same Postgres carries it from prototype to petabyte.
## Build anything
### Local development without Docker
Local Supabase can now run as native processes, so it starts on machines without a Docker daemon, like Claude Code's sandbox. You can also run multiple local Supabase instances, one per directory, so several checkouts of the same repo run at the same time. In alpha, off by default. Update the [Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started) to try it.
### Declarative Schemas 2.0
Write your schema as SQL files and pg-delta generates the migration, so the schema lives in your repo. Project settings live in code too, and a dashboard change comes back into the file with `supabase config pull`. [Docs](https://supabase.com/docs/guides/local-development/declarative-database-schemas).
### Supabase Compute
Run web services and agents in any language next to your database, with no limit on how long they run. Each service gets a full Linux environment and the same default environment variables as your Edge Functions. Private alpha. [Join the waitlist](https://supabase.com/compute).
### Your app's MCP server
Let your users connect their own agents to your app. The server runs as an Edge Function next to your data, users sign in through your existing Auth flow, and every tool call runs as that user, with your RLS policies deciding what it can reach. It's separate from the official Supabase MCP server, and it's built on `@supabase/server` and the new Supabase Middleware, which also work on their own in any server code that needs to know who is signed in. [Add the MCP server block](https://supabase.com/library/docs/headless/mcp).
Learn more in [Build anything: Supabase from code, and an MCP server for your app](https://supabase.com/blog/select-2026-build-anything).
## Operate with confidence
### Agent prompts
Pick a prompt and suggested schedule for health, security, performance, or resource checks, and run it in Claude, Codex, or Cursor. Your agent reads your project through the Supabase MCP server, connected read-only, and reports what it finds. [Pick a prompt](https://supabase.com/docs/guides/observability/automate-with-agents).
### Health Check Advisors
Advisors now flag elevated error rates in the Data API, Auth, Storage, and Edge Functions, next to the security and performance issues they already catch. Open the Health tab on your project's Advisors page. [Changelog](https://supabase.com/changelog/50577-health-check-advisors).
### Database Connections
See which sessions hold connections, run long, or are blocked, and who holds the lock, then cancel the query or terminate the connection. On by default for every project, including self-hosted. [Open it in the dashboard](https://supabase.com/dashboard/project/_/observability/connections).
### `query_logs` and the Supabase agent skill
A new MCP tool lets your agent query your logs directly, and the Supabase agent skill now points to a living document of the health, security, performance, and resource signals your agent should watch for. [Install the Supabase plugin](https://supabase.com/docs/guides/ai-tools/plugins).
### Explorer and Notebooks
Explorer is the next version of the SQL editor. Query your logs or your database in one workspace, and save the investigation as a Notebook anyone on your team can rerun. Rolling out to every project through October 12. Once it reaches your project, turn it on under Feature Previews. [Open Explorer](https://supabase.com/dashboard/project/_/explorer).
### Enterprise-Managed Auth for MCP
Your company decides who can connect to the Supabase MCP server through its identity provider, starting with Okta. Each token is bound to the member who signs in. Generally available. [Set it up](https://supabase.com/docs/guides/platform/sso/enterprise-mcp-authentication) on a Team or Enterprise plan with SSO configured.
### Scoped Personal Access Tokens
Limit a token to the organizations, projects, and permissions you choose. Generally available, and the default for new tokens created in the dashboard. Create one at [Account, Access Tokens](https://supabase.com/dashboard/account/tokens).
### MCP Elicitations
Before your agent creates a paid project or branch, or runs SQL that could delete data, the Supabase MCP server asks you to confirm first. It helps prevent unwanted charges and data loss, but it isn't a guarantee. On by default. [MCP docs](https://supabase.com/docs/guides/ai-tools/mcp).
### Supabase Pipelines, new destinations
Stream Postgres data to BigQuery, ClickHouse, DuckLake, or Snowflake in near real time, so analytics queries run there instead of on your production database. Public alpha on the Pro, Team, and Enterprise plans. [Docs](https://supabase.com/docs/guides/database/replication/pipelines).
Learn more in [Operate with confidence](https://supabase.com/blog/select-2026-operate-with-confidence).
## Scale without limits
### Multigres
Multi-node high availability for Postgres, built by the team behind Vitess. When a node fails, Multigres promotes a replica in seconds and committed writes survive, with no changes to your application. Connection pooling is built in. The Multigres project is open source. On Supabase, it's in private alpha, by invite. [Request access](https://supabase.com/go/multigres-early-access).
### OrioleDB
A storage engine that replaces the default heap with an undo log, avoids table bloat and VACUUM, and keeps familiar Postgres behavior. Public beta. Choose it at project creation. [Docs](https://supabase.com/docs/guides/database/orioledb).
### dbarena
Open, reproducible database benchmarks. The benchmark code, the data, absolute throughput, and throughput per dollar are all published, so you can inspect the method and rerun the result. [Visit the website](https://dbarena.com).
Learn more in [Scale without limits: Multigres, OrioleDB, and dbarena](https://supabase.com/blog/select-2026-scale-without-limits).
-4
View File
@@ -38,8 +38,6 @@ import contestRules from './legal/contest-rules'
import byocEarlyAccess from './pre-release/byoc-early-access'
import multigresEarlyAccess from './pre-release/multigres-early-access'
import multigresEarlyAccessThankYou from './pre-release/multigres-early-access-thank-you'
import supabasePipelinesNewDestinations from './pre-release/supabase-pipelines-new-destinations'
import supabasePipelinesNewDestinationsThankYou from './pre-release/supabase-pipelines-new-destinations-thank-you'
import supabaseStripeProjects from './stripe-projects/supabase-stripe-projects'
const pages: GoPageInput[] = [
@@ -47,8 +45,6 @@ const pages: GoPageInput[] = [
awsActivateOffer, // maintain forever
exampleLeadGen, // sample lead gen page
byocEarlyAccess, // maintain until PM says to remove
supabasePipelinesNewDestinations, // maintain while Pipelines destination early access is active
supabasePipelinesNewDestinationsThankYou, // maintain while Pipelines destination early access is active
multigresEarlyAccess, // maintain while the Multigres private alpha is active
multigresEarlyAccessThankYou, // maintain while the Multigres private alpha is active
amoe, // maintain forever
+17 -4
View File
@@ -23,21 +23,30 @@ const themes: Theme[] = [
name: 'Build anything',
description:
"Your agent sets up the backend from code, your users' agents work with your app through its own MCP server, and long-running tasks run in Supabase Compute.",
cta: { label: 'Read the Build Blog', href: '/docs' },
cta: {
label: 'Read the Build Blog',
href: 'https://supabase.com/blog/select-2026-build-anything',
},
icon: Hammer,
},
{
name: 'Scale without limits',
description:
'The app your agent built in minutes stays on the same Postgres, from prototype to petabyte.',
cta: { label: 'Read the Scale Blog', href: '/docs' },
cta: {
label: 'Read the Scale Blog',
href: 'https://supabase.com/blog/select-2026-scale-without-limits',
},
icon: Maximize2,
},
{
name: 'Operate with confidence',
description:
'Your agent finds the problem, tests the fix, and reports what it found. You decide what ships.',
cta: { label: 'Read the Operate Blog', href: '/docs' },
cta: {
label: 'Read the Operate Blog',
href: 'https://supabase.com/blog/select-2026-operate-with-confidence',
},
icon: ShieldCheck,
},
]
@@ -88,9 +97,13 @@ const page: GoPageInput = {
ctas: [
{
label: 'Read the Recap',
href: '/docs',
href: 'https://supabase.com/blog/select-2026-build-anything',
variant: 'secondary',
},
{
label: 'Join our Discord',
href: 'https://discord.supabase.com/',
},
],
},
sections: [
@@ -1,26 +0,0 @@
import type { GoPageInput } from 'marketing'
const page: GoPageInput = {
template: 'thank-you',
slug: 'supabase-pipelines-new-destinations/thank-you',
metadata: {
title: 'Supabase Pipelines destination request received',
description: 'Thanks for requesting early access to upcoming Supabase Pipelines destinations.',
ogImage: '/images/blog/2025-12-02-introducing-supabase-pipelines/og.png',
},
hero: {
title: 'Thanks for your request',
subtitle: 'Early Access',
description:
"We received your destination preferences for Supabase Pipelines. If your workspace is selected for early access to ClickHouse, Snowflake, or DuckLake destinations, we'll reach out with next steps.",
ctas: [
{
label: 'Back to Supabase',
href: '/',
variant: 'secondary',
},
],
},
}
export default page
@@ -1,181 +0,0 @@
import type { GoPageInput } from 'marketing'
const page: GoPageInput = {
template: 'lead-gen',
slug: 'supabase-pipelines-new-destinations',
metadata: {
title: 'Supabase Pipelines Destinations - Early Access',
description:
'Request early access to upcoming Supabase Pipelines destinations for ClickHouse, Snowflake, and DuckLake.',
ogImage: '/images/blog/2025-12-02-introducing-supabase-pipelines/og.png',
},
hero: {
title: 'Supabase Pipelines destinations',
subtitle: 'Early Access',
description:
"Managed change-data-capture pipelines that replicate your Supabase Postgres data to analytical systems in near real time. Request early access to the destinations we're adding next: ClickHouse, Snowflake, and DuckLake.",
image: {
src: '/images/blog/2025-12-02-introducing-supabase-pipelines/thumb.png',
alt: 'Introducing Supabase Pipelines',
width: 2400,
height: 1260,
},
ctas: [
{
label: 'Request early access',
href: '#form',
variant: 'primary',
},
{
label: 'Read the announcement',
href: '/blog/introducing-supabase-pipelines',
variant: 'secondary',
},
],
},
sections: [
{
type: 'feature-grid',
className: 'border-y border-muted bg-surface-75 py-16 sm:py-24',
title: 'Bring Supabase Postgres into your analytics stack',
description:
'Pipelines keeps your application workload on Postgres while ongoing replication sends production changes to systems built for analytics, reporting, and lakehouse workflows.',
columns: 3,
items: [
{
title: 'ClickHouse',
description:
'Replicate operational data into ClickHouse for high-volume analytical queries, dashboards, and event workloads.',
},
{
title: 'Snowflake',
description:
'Replicate Supabase Postgres data into Snowflake for warehouse analytics, BI, and governed data workflows.',
},
{
title: 'DuckLake',
description:
'Move data into an open lakehouse destination for portable analytics and long-term data workflows.',
},
],
},
{
type: 'form',
id: 'form',
className: 'py-4 sm:py-8',
title: 'Request early access to new Pipelines destinations',
description:
"This form is for early access to upcoming destinations for Supabase Pipelines, not access to Supabase Pipelines itself. Tell us which destinations your team wants to use. If your workspace is selected, we'll reach out with next steps.",
fields: [
{
type: 'email',
name: 'email',
label: 'Email address',
placeholder: 'Work email',
required: true,
},
{
type: 'text',
name: 'org_slug',
label: 'Supabase organization slug',
placeholder: 'acme-inc',
description: 'Use the slug from your Supabase Dashboard URL, for example /org/acme-inc.',
required: true,
},
{
type: 'checkbox',
name: 'destination_clickhouse',
label: 'ClickHouse',
description:
'For high-throughput analytical queries, event data, logs, and dashboard workloads.',
group: 'requested_destinations',
groupRequired: true,
},
{
type: 'checkbox',
name: 'destination_snowflake',
label: 'Snowflake',
description: 'For teams running warehouse analytics, BI, or governed data workflows.',
group: 'requested_destinations',
groupRequired: true,
},
{
type: 'checkbox',
name: 'destination_ducklake',
label: 'DuckLake',
description:
'For open lakehouse workflows where you want portable data and flexible analytics.',
group: 'requested_destinations',
groupRequired: true,
},
],
submitLabel: 'Request destination access',
successRedirect: '/go/supabase-pipelines-new-destinations/thank-you',
disclaimer:
'By submitting this form, I confirm that I have read and understood the [Privacy Policy](https://supabase.com/privacy).',
crm: {
notion: {
database_id: '3825004b775f80828179e7bdd7ee4b8d',
columnMap: {
email: 'Email',
org_slug: 'Organization Slug',
destination_clickhouse: 'ClickHouse',
destination_snowflake: 'Snowflake',
destination_ducklake: 'DuckLake',
},
},
},
},
{
type: 'three-column',
className: 'pb-16 sm:pb-24',
title: 'Suggested reading',
description: 'Get the product context and setup details behind Supabase Pipelines.',
children: (
<>
<a
href="/blog/introducing-supabase-pipelines"
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
>
<span className="text-sm text-foreground-lighter">Blog</span>
<span className="text-lg font-medium text-foreground group-hover:text-primary">
Introducing Supabase Pipelines
</span>
<span className="text-sm leading-relaxed text-foreground-light">
Learn how managed CDC pipelines move Postgres changes to analytical destinations in
near real time.
</span>
</a>
<a
href="/docs/guides/database/replication/pipelines"
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
>
<span className="text-sm text-foreground-lighter">Docs</span>
<span className="text-lg font-medium text-foreground group-hover:text-primary">
Set up Pipelines
</span>
<span className="text-sm leading-relaxed text-foreground-light">
Review publications, destination setup, monitoring, and how pipelines are managed from
the Dashboard.
</span>
</a>
<a
href="/blog/realtime-or-pipelines-how-to-choose-the-right-tool"
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
>
<span className="text-sm text-foreground-lighter">Guide</span>
<span className="text-lg font-medium text-foreground group-hover:text-primary">
Realtime or Pipelines?
</span>
<span className="text-sm leading-relaxed text-foreground-light">
Compare live user experiences over WebSocket with reliable data movement into
analytical systems.
</span>
</a>
</>
),
},
],
}
export default page
@@ -1,5 +1,6 @@
'use client'
import SectionContainerWithCn from 'components/Layouts/SectionContainerWithCn'
import { AnimatePresence, motion, useReducedMotion } from 'framer-motion'
import { Database } from 'icons'
import type { LucideIcon } from 'lucide-react'
@@ -7,7 +8,6 @@ import { Bot, User } from 'lucide-react'
import { useCallback, useEffect, useId, useRef, useState } from 'react'
import { cn } from 'ui'
import SectionContainerWithCn from '../../../../components/Layouts/SectionContainerWithCn'
import styles from './compute-visual.module.css'
import { ComputeLogo } from './ComputeLogo'
@@ -185,6 +185,7 @@ function ComputeCardHeader({
<ComputeIcon />
<div className="flex min-w-0 flex-col leading-tight">
<span className="truncate text-xs text-foreground">{name}</span>
{/* eslint-disable-next-line shadcn/no-arbitrary-values -- 11px is a deliberate micro-size for this diagram's dense card header, not a token gap */}
<span className="truncate font-mono text-[11px] text-foreground-muted">{runtime}</span>
</div>
</div>
@@ -513,9 +514,9 @@ function buildConnectors(geometry: Geometry, live: Record<string, boolean>): Con
const box = (key: NodeKey) => boxes[key] as Box
const top = (key: NodeKey) => box(key).y
const bottom = (key: NodeKey) => box(key).y + box(key).height
const cx = (key: NodeKey) => box(key).x + box(key).width / 2
const cy = (key: NodeKey) => box(key).y + box(key).height / 2
const center = (key: NodeKey): Point => ({ x: cx(key), y: cy(key) })
const centerX = (key: NodeKey) => box(key).x + box(key).width / 2
const centerY = (key: NodeKey) => box(key).y + box(key).height / 2
const center = (key: NodeKey): Point => ({ x: centerX(key), y: centerY(key) })
const at = (x: number, y: number): Point => ({ x, y })
// Horizontal bands: the empty strips above and below the card grid, where
@@ -533,16 +534,16 @@ function buildConnectors(geometry: Geometry, live: Record<string, boolean>): Con
// Each source feeds its own column.
connector('human-embeddings', [
center('human'),
at(cx('human'), sourceBand),
at(cx('embeddings'), sourceBand),
at(centerX('human'), sourceBand),
at(centerX('embeddings'), sourceBand),
center('embeddings'),
]),
connector(
'agent1-sandboxBottomMid',
[
center('agent1'),
at(cx('agent1'), sourceBand),
at(cx('sandboxBottomMid'), sourceBand),
at(centerX('agent1'), sourceBand),
at(centerX('sandboxBottomMid'), sourceBand),
center('sandboxBottomMid'),
],
live.sandboxBottomMid
@@ -551,8 +552,8 @@ function buildConnectors(geometry: Geometry, live: Record<string, boolean>): Con
'agent2-sandboxBottomRight',
[
center('agent2'),
at(cx('agent2'), sourceBand),
at(cx('sandboxBottomRight'), sourceBand),
at(centerX('agent2'), sourceBand),
at(centerX('sandboxBottomRight'), sourceBand),
center('sandboxBottomRight'),
],
live.sandboxBottomRight
@@ -561,8 +562,8 @@ function buildConnectors(geometry: Geometry, live: Record<string, boolean>): Con
// The always-on column serves the application.
connector('api-app', [
center('api'),
at(cx('api'), appBand),
at(cx('app'), appBand),
at(centerX('api'), appBand),
at(centerX('app'), appBand),
center('app'),
]),
]
@@ -592,6 +593,7 @@ function ConnectorLayer({
aria-hidden="true"
>
<mask id={maskId} maskUnits="userSpaceOnUse" x="0" y="0" width={width} height={height}>
{/* eslint-disable-next-line shadcn/no-raw-colors -- SVG mask luminance requires literal white, not a theme color */}
<rect x="0" y="0" width={width} height={height} fill="white" />
{Object.entries(boxes).map(([key, node]) => (
<rect
@@ -601,6 +603,7 @@ function ConnectorLayer({
width={node.width}
height={node.height}
rx={CARD_RADIUS}
// eslint-disable-next-line shadcn/no-raw-colors -- SVG mask luminance requires literal black, not a theme color
fill="black"
/>
))}
@@ -5,32 +5,32 @@ const features = [
{
title: 'Short-lived credentials',
paragraph: 'Access runs through Supabase Auth with short-lived keys, not standing secrets.',
icon: <KeyRound className="w-5 h-5 stroke-[1.4px]" />,
icon: <KeyRound className="w-5 h-5" strokeWidth={1.4} />,
},
{
title: 'Zero-config data access',
paragraph: 'Reach your database and Storage with the permissions your key already carries.',
icon: <Plug className="w-5 h-5 stroke-[1.4px]" />,
icon: <Plug className="w-5 h-5" strokeWidth={1.4} />,
},
{
title: 'Per-workload firewalls',
paragraph: 'Define which external endpoints and ports each workload can reach.',
icon: <Network className="w-5 h-5 stroke-[1.4px]" />,
icon: <Network className="w-5 h-5" strokeWidth={1.4} />,
},
{
title: 'Cloaked secrets',
paragraph: 'Scope secrets per workload, and cloak values so your code never sees them.',
icon: <EyeOff className="w-5 h-5 stroke-[1.4px]" />,
icon: <EyeOff className="w-5 h-5" strokeWidth={1.4} />,
},
{
title: 'Patched automatically',
paragraph: 'Kernel-level security patches roll out automatically. Nothing to do on your part.',
icon: <ShieldCheck className="w-5 h-5 stroke-[1.4px]" />,
icon: <ShieldCheck className="w-5 h-5" strokeWidth={1.4} />,
},
{
title: 'Dependency scanning',
paragraph: 'Dependencies are scanned at runtime, with alerts as new vulnerabilities land.',
icon: <ScanSearch className="w-5 h-5 stroke-[1.4px]" />,
icon: <ScanSearch className="w-5 h-5" strokeWidth={1.4} />,
},
]
@@ -46,9 +46,9 @@ export function TrustBoundarySection() {
<span className="text-foreground-lighter block">preconfigured</span>
</h2>
<p className="text-foreground-lighter text-sm lg:text-base">
Every sandbox and service inherits your project's auth, roles, and permissions the moment
it starts, running in its own microVM with dedicated CPU and memory. Agents get a sandbox
that is already scoped to the data it is allowed to touch — nothing more.
Every sandbox and service inherits your project&apos;s auth, roles, and permissions the
moment it starts, running in its own microVM with dedicated CPU and memory. Agents get a
sandbox that is already scoped to the data it is allowed to touch — nothing more.
</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
@@ -7,7 +7,6 @@ import {
Pause,
Server,
Shield,
Terminal,
TrendingUp,
} from 'lucide-react'
@@ -89,7 +88,8 @@ export function WorkloadsSection() {
className="flex items-start gap-2 text-foreground-light text-sm"
>
<Icon
className="w-4 h-4 text-brand shrink-0 mt-0.5 stroke-[1.5px]"
className="w-4 h-4 text-brand shrink-0 mt-0.5"
strokeWidth={1.5}
aria-hidden
/>
{feature.text}
+4 -2
View File
@@ -192,9 +192,11 @@ const Nav = ({ hideNavbar, stickyNavbar = true }: Props) => {
forceMount
data-open={activeDropdown !== ''}
data-switching={isSwitchingDropdown}
containerProps={{ className: 'inset-x-0' }}
// The wrapper keeps the last menu's height while closed, so it must
// not capture pointer events over the page below the nav.
containerProps={{ className: 'inset-x-0 pointer-events-none' }}
className={cn(
'group/viewport origin-top scale-100 rounded-xl bg-surface-75 md:w-[960px]',
'group/viewport pointer-events-auto origin-top scale-100 rounded-xl bg-surface-75 md:w-[960px]',
'data-[state=open]:animate-none! data-[state=closed]:animate-none!',
'data-[state=open]:duration-200 data-[state=open]:ease-out data-[state=closed]:duration-200',
'data-[open=false]:invisible data-[open=false]:scale-[0.97] data-[open=false]:opacity-0',
+1 -1
View File
@@ -654,7 +654,7 @@ Foreign Data Wrappers simplify data integration by bringing external data into y
4. Workload isolation: Keep analytical queries away from the primary database.
## Destinations
BigQuery is currently available. ClickHouse, DuckLake, and Snowflake are in Early Access. [Request access](/go/supabase-pipelines-new-destinations) to these destinations.
BigQuery, ClickHouse, DuckLake, and Snowflake are available in public alpha. See the [destination guides](/docs/guides/database/replication#supported-destinations) to get started.
## Setup
Create a Postgres publication for the tables to replicate. In Database > Pipelines, add a Pipelines destination, configure its settings, and monitor the pipeline from the Dashboard.
+32
View File
@@ -1047,5 +1047,37 @@
"position": "Product Manager",
"author_url": "https://github.com/nrichers",
"author_image_url": "https://github.com/nrichers.png"
},
{
"author_id": "aditya_maruvada",
"author": "Aditya Maruvada",
"username": "supa-aditya",
"position": "Engineering",
"author_url": "https://github.com/supa-aditya",
"author_image_url": "https://github.com/supa-aditya.png"
},
{
"author_id": "daniel_mitterdorfer",
"author": "Daniel Mitterdorfer",
"username": "danielmitterdorfer",
"position": "Engineering",
"author_url": "https://github.com/danielmitterdorfer",
"author_image_url": "https://github.com/danielmitterdorfer.png"
},
{
"author_id": "alexander_korotkov",
"author": "Alexander Korotkov",
"username": "akorotkov",
"position": "Engineering",
"author_url": "https://github.com/akorotkov",
"author_image_url": "https://github.com/akorotkov.png"
},
{
"author_id": "rand_arete",
"author": "Rand Arete",
"username": "rand",
"position": "Engineering",
"author_url": "https://github.com/rand",
"author_image_url": "https://github.com/rand.png"
}
]
+10
View File
@@ -40,6 +40,16 @@ module.exports = [
source: '/features/supabase-etl',
destination: '/features/supabase-pipelines',
},
{
permanent: true,
source: '/go/supabase-pipelines-new-destinations',
destination: '/docs/guides/database/replication#supported-destinations',
},
{
permanent: true,
source: '/go/supabase-pipelines-new-destinations/thank-you',
destination: '/docs/guides/database/replication#supported-destinations',
},
{
permanent: true,
source: '/ui/docs/ai-editors-rules/prompts',
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -144,6 +144,41 @@ type Select26FieldProps = HTMLAttributes<HTMLDivElement> & {
* radar beam falloff. Stepped updates mirror the Select glyph-engine without
* shipping its canvas runtime.
*/
/**
* One shared, throttled rAF loop for every mounted field, so multiple fields
* (e.g. the mirrored www pair) paint in the same frame instead of each
* running its own loop.
*/
type FieldPainter = (timeMs: number) => void
const fieldPainters = new Set<FieldPainter>()
let fieldRaf = 0
let fieldLastPaint = 0
let fieldStarted = 0
const fieldTick = (now: number) => {
if (now - fieldLastPaint >= FRAME_INTERVAL_MS) {
fieldLastPaint = now
const timeMs = now - fieldStarted
fieldPainters.forEach((paint) => paint(timeMs))
}
fieldRaf = fieldPainters.size > 0 ? requestAnimationFrame(fieldTick) : 0
}
const subscribeFieldPainter = (paint: FieldPainter) => {
fieldPainters.add(paint)
if (!fieldRaf) {
if (!fieldStarted) fieldStarted = performance.now()
fieldRaf = requestAnimationFrame(fieldTick)
}
return () => {
fieldPainters.delete(paint)
if (fieldPainters.size === 0 && fieldRaf) {
cancelAnimationFrame(fieldRaf)
fieldRaf = 0
}
}
}
export const Select26Field = ({
cols = 10,
rows = 6,
@@ -154,8 +189,6 @@ export const Select26Field = ({
...props
}: Select26FieldProps) => {
const rootRef = useRef<HTMLDivElement>(null)
const [timeMs, setTimeMs] = useState(0)
const [isVisible, setIsVisible] = useState(true)
const widths = useMemo(() => {
if (rowWidths) return rowWidths
@@ -163,50 +196,62 @@ export const Select26Field = ({
}, [rowWidths, rows, cols])
const fieldRows = widths.length
// Static first frame for SSR / reduced motion; animation then mutates the
// existing spans directly instead of re-rendering through React.
const initialCells = useMemo(
() =>
widths.map((rowCols, y) =>
Array.from({ length: rowCols }, (_, x) => cellAt(x, y, rowCols, fieldRows, 0, mirror))
),
[widths, fieldRows, mirror]
)
useEffect(() => {
const node = rootRef.current
if (!node || typeof IntersectionObserver === 'undefined') return
if (!node) return
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return
const spans = Array.from(node.querySelectorAll<HTMLSpanElement>('[data-cell]'))
const coords = widths.flatMap((rowCols, y) => Array.from({ length: rowCols }, (_, x) => [x, y]))
const previous = initialCells.flat()
const paint: FieldPainter = (timeMs) => {
for (let i = 0; i < spans.length; i++) {
const [x, y] = coords[i]
const next = cellAt(x, y, widths[y], fieldRows, timeMs, mirror)
const prev = previous[i]
const span = spans[i]
if (next.ch !== prev.ch) span.textContent = next.ch
if (next.band !== prev.band) span.dataset.band = String(next.band)
if (next.weight !== prev.weight) span.style.opacity = String(next.weight)
previous[i] = next
}
}
let unsubscribe: (() => void) | undefined
const start = () => {
if (!unsubscribe) unsubscribe = subscribeFieldPainter(paint)
}
const stop = () => {
unsubscribe?.()
unsubscribe = undefined
}
// Only animate while on screen (also covers `display: none` breakpoints).
if (typeof IntersectionObserver === 'undefined') {
start()
return stop
}
const observer = new IntersectionObserver(
([entry]) => setIsVisible(entry?.isIntersecting ?? false),
([entry]) => (entry?.isIntersecting ? start() : stop()),
{ rootMargin: '80px' }
)
observer.observe(node)
return () => observer.disconnect()
}, [])
useEffect(() => {
if (!isVisible) return
if (
typeof window !== 'undefined' &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches
) {
return
return () => {
observer.disconnect()
stop()
}
let raf = 0
let lastPaint = 0
const started = performance.now()
const tick = (now: number) => {
if (now - lastPaint >= FRAME_INTERVAL_MS) {
lastPaint = now
setTimeMs(now - started)
}
raf = requestAnimationFrame(tick)
}
raf = requestAnimationFrame(tick)
return () => cancelAnimationFrame(raf)
}, [isVisible])
const cellsByRow = useMemo(() => {
return widths.map((rowCols, y) => {
const rowCells: FieldCell[] = []
for (let x = 0; x < rowCols; x++) {
rowCells.push(cellAt(x, y, rowCols, fieldRows, timeMs, mirror))
}
return rowCells
})
}, [widths, fieldRows, timeMs, mirror])
}, [widths, fieldRows, mirror, initialCells])
return (
<div
@@ -219,7 +264,7 @@ export const Select26Field = ({
)}
{...props}
>
{cellsByRow.map((rowCells, y) => {
{initialCells.map((rowCells, y) => {
const rowCols = widths[y]
const cellWidth = 'calc(22 / 34 * 1em)'
@@ -235,6 +280,7 @@ export const Select26Field = ({
{rowCells.map((cell, index) => (
<span
key={index}
data-cell
className={styles.cell}
data-band={cell.band}
style={{ opacity: cell.weight }}
+431 -27
View File
@@ -753,6 +753,9 @@ importers:
'@astrojs/react':
specifier: ^6.0.4
version: 6.0.4(@types/node@22.13.14)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(esbuild@0.28.1)(jiti@2.7.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
'@astrojs/sitemap':
specifier: ^3.7.4
version: 3.7.4
astro:
specifier: ^7.2.6
version: 7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
@@ -796,6 +799,9 @@ importers:
'@tailwindcss/vite':
specifier: 4.2.4
version: 4.2.4(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
'@types/node':
specifier: 'catalog:'
version: 22.13.14
'@types/react':
specifier: 'catalog:'
version: 19.2.14
@@ -1596,7 +1602,7 @@ importers:
version: 0.52.2
next:
specifier: 'catalog:'
version: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
version: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next-themes:
specifier: 'catalog:'
version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -1678,10 +1684,10 @@ importers:
version: 7.29.7(supports-color@8.1.1)
'@react-router/dev':
specifier: ^7.17.1
version: 7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0)
version: 7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0)
'@react-router/fs-routes':
specifier: ^7.18.4
version: 7.18.4(@react-router/dev@7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0))(typescript@6.0.2)
version: 7.18.4(@react-router/dev@7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0))(typescript@6.0.2)
'@shikijs/compat':
specifier: ^1.1.7
version: 1.6.0
@@ -1783,7 +1789,7 @@ importers:
version: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: 'catalog:'
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
apps/www:
dependencies:
@@ -1831,7 +1837,7 @@ importers:
version: 21.1.1
'@sentry/nextjs':
specifier: 'catalog:'
version: 10.59.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))(encoding@0.1.13)(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
version: 10.59.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))(encoding@0.1.13)(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
'@supabase/ssr':
specifier: 'catalog:'
version: 0.12.7(@supabase/supabase-js@2.116.0(@opentelemetry/api@1.9.1))
@@ -1930,19 +1936,19 @@ importers:
version: 1.0.1
next:
specifier: ^15.5.24
version: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
version: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next-mdx-remote-client:
specifier: ^1.1.7
version: 1.1.7(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(supports-color@8.1.1)(unified@11.0.5)
next-seo:
specifier: ^6.5.0
version: 6.5.0(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
version: 6.5.0(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
next-themes:
specifier: 'catalog:'
version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
nuqs:
specifier: ^2.8.1
version: 2.8.1(@tanstack/react-router@1.170.41(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)
version: 2.8.1(@tanstack/react-router@1.170.41(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)
ogl:
specifier: ^1.0.11
version: 1.0.11
@@ -2017,7 +2023,7 @@ importers:
version: link:../../packages/ui-patterns
unicornstudio-react:
specifier: 2.0.1-1
version: 2.0.1-1(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
version: 2.0.1-1(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
use-debounce:
specifier: ^7.0.1
version: 7.0.1(react@19.2.6)
@@ -2105,7 +2111,7 @@ importers:
version: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: 'catalog:'
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
zod:
specifier: 'catalog:'
version: 3.25.76
@@ -2501,10 +2507,10 @@ importers:
version: link:../config
next:
specifier: 'catalog:'
version: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
version: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next-router-mock:
specifier: ^0.9.13
version: 0.9.13(next@16.3.6(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)
version: 0.9.13(next@16.3.6(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)
react:
specifier: 'catalog:'
version: 19.2.6
@@ -2525,7 +2531,7 @@ importers:
version: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: 'catalog:'
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
packages/eslint-config-supabase:
devDependencies:
@@ -2558,7 +2564,7 @@ importers:
version: 6.0.2
vitest:
specifier: 'catalog:'
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
packages/generator:
devDependencies:
@@ -2675,7 +2681,7 @@ importers:
version: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: 'catalog:'
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
packages/shared-data:
dependencies:
@@ -3287,6 +3293,9 @@ packages:
react: ^17.0.2 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.2 || ^18.0.0 || ^19.0.0
'@astrojs/sitemap@3.7.4':
resolution: {integrity: sha512-LbKNC24bdUWcQf/pThB6qLlSqHojxGjZDURIzFocY8rlWnAn2t74nnhnK6S5x0NHriHoAduLEpVjRykmeGiVvA==}
'@astrojs/telemetry@3.3.3':
resolution: {integrity: sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
@@ -9232,6 +9241,9 @@ packages:
'@types/node@22.13.14':
resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==}
'@types/node@24.19.0':
resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==}
'@types/papaparse@5.3.9':
resolution: {integrity: sha512-sZcrKD63qA4/6GyBcVvX6AIp0AkpfyYk00CUQHMBvb4+OVXTZWyXUvidUZaai1wyKUVyJoxO7mgREam/pMRrDw==}
@@ -9273,6 +9285,9 @@ packages:
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
'@types/sax@1.2.7':
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
'@types/stats.js@0.17.3':
resolution: {integrity: sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==}
@@ -17136,6 +17151,11 @@ packages:
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
sitemap@9.0.1:
resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==}
engines: {node: '>=20.19.5', npm: '>=10.8.2'}
hasBin: true
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -17926,6 +17946,9 @@ packages:
undici-types@6.20.0:
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
undici-types@7.24.6:
resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
undici@7.30.0:
resolution: {integrity: sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==}
engines: {node: '>=20.18.1'}
@@ -19362,6 +19385,11 @@ snapshots:
- tsx
- yaml
'@astrojs/sitemap@3.7.4':
dependencies:
sitemap: 9.0.1
zod: 4.6.5
'@astrojs/telemetry@3.3.3':
dependencies:
ci-info: 4.4.0
@@ -21665,6 +21693,14 @@ snapshots:
optionalDependencies:
'@types/node': 22.13.14
'@inquirer/confirm@5.1.21(@types/node@24.19.0)':
dependencies:
'@inquirer/core': 10.3.2(@types/node@24.19.0)
'@inquirer/type': 3.0.10(@types/node@24.19.0)
optionalDependencies:
'@types/node': 24.19.0
optional: true
'@inquirer/core@10.3.2(@types/node@22.13.14)':
dependencies:
'@inquirer/ansi': 1.0.2
@@ -21678,6 +21714,20 @@ snapshots:
optionalDependencies:
'@types/node': 22.13.14
'@inquirer/core@10.3.2(@types/node@24.19.0)':
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/figures': 1.0.15
'@inquirer/type': 3.0.10(@types/node@24.19.0)
cli-width: 4.1.0
mute-stream: 2.0.0
signal-exit: 4.1.0
wrap-ansi: 6.2.0
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 24.19.0
optional: true
'@inquirer/editor@4.2.23(@types/node@22.13.14)':
dependencies:
'@inquirer/core': 10.3.2(@types/node@22.13.14)
@@ -21771,6 +21821,11 @@ snapshots:
optionalDependencies:
'@types/node': 22.13.14
'@inquirer/type@3.0.10(@types/node@24.19.0)':
optionalDependencies:
'@types/node': 24.19.0
optional: true
'@ioredis/commands@1.5.1': {}
'@isaacs/cliui@8.0.2':
@@ -22186,7 +22241,7 @@ snapshots:
'@modelcontextprotocol/core@2.0.0':
dependencies:
zod: 4.4.3
zod: 4.6.5
'@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76)':
dependencies:
@@ -24302,6 +24357,56 @@ snapshots:
- tsx
- yaml
'@react-router/dev@7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0)':
dependencies:
'@babel/core': 7.29.7(supports-color@8.1.1)
'@babel/generator': 7.29.7
'@babel/parser': 7.29.8
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.7(supports-color@8.1.1))
'@babel/preset-typescript': 7.27.1(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1)
'@babel/traverse': 7.29.7(supports-color@8.1.1)
'@babel/types': 7.29.8
'@react-router/node': 7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.2)
'@remix-run/node-fetch-server': 0.13.0
arg: 5.0.2
babel-dead-code-elimination: 1.0.12(supports-color@8.1.1)
chokidar: 4.0.3
dedent: 1.7.2(babel-plugin-macros@3.1.0)
es-module-lexer: 1.7.0
exit-hook: 2.2.1
isbot: 5.1.36
jsesc: 3.0.2
lodash: 4.18.1
p-map: 7.0.4
pathe: 1.1.2
picocolors: 1.1.1
pkg-types: 2.3.1
prettier: 3.8.1
react-refresh: 0.14.2
react-router: 7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
semver: 7.8.5
tinyglobby: 0.2.17
valibot: 1.4.2(typescript@6.0.2)
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vite-node: 3.2.4(@types/node@24.19.0)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
optionalDependencies:
'@react-router/serve': 7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2)
typescript: 6.0.2
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- jiti
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
'@react-router/express@7.18.4(express@4.22.1(supports-color@8.1.1))(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.2)':
dependencies:
'@react-router/node': 7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.2)
@@ -24317,6 +24422,13 @@ snapshots:
optionalDependencies:
typescript: 6.0.2
'@react-router/fs-routes@7.18.4(@react-router/dev@7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0))(typescript@6.0.2)':
dependencies:
'@react-router/dev': 7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0)
minimatch: 9.0.7
optionalDependencies:
typescript: 6.0.2
'@react-router/node@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.2)':
dependencies:
'@mjackson/node-fetch-server': 0.2.0
@@ -24695,6 +24807,32 @@ snapshots:
- vite
- webpack
'@sentry/nextjs@10.59.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))(encoding@0.1.13)(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
dependencies:
'@opentelemetry/api': 1.9.1
'@rollup/plugin-commonjs': 28.0.1(rollup@4.60.3)
'@sentry/browser-utils': 10.59.0
'@sentry/bundler-plugin-core': 5.3.0(encoding@0.1.13)(supports-color@8.1.1)
'@sentry/conventions': 0.12.0
'@sentry/core': 10.59.0
'@sentry/node': 10.59.0(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
'@sentry/opentelemetry': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))
'@sentry/react': 10.59.0(react@19.2.6)
'@sentry/vercel-edge': 10.59.0
'@sentry/webpack-plugin': 5.3.0(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.105.4(esbuild@0.28.1))
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
rollup: 4.60.3
stacktrace-parser: 0.1.11
transitivePeerDependencies:
- '@opentelemetry/core'
- '@opentelemetry/exporter-trace-otlp-http'
- '@opentelemetry/sdk-trace-base'
- encoding
- react
- supports-color
- vite
- webpack
'@sentry/nextjs@10.59.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))(encoding@0.1.13)(next@16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
dependencies:
'@opentelemetry/api': 1.9.1
@@ -26461,6 +26599,10 @@ snapshots:
dependencies:
undici-types: 6.20.0
'@types/node@24.19.0':
dependencies:
undici-types: 7.24.6
'@types/papaparse@5.3.9':
dependencies:
'@types/node': 22.13.14
@@ -26511,6 +26653,10 @@ snapshots:
'@types/resolve@1.20.2': {}
'@types/sax@1.2.7':
dependencies:
'@types/node': 22.13.14
'@types/stats.js@0.17.3': {}
'@types/statuses@2.0.5': {}
@@ -27004,6 +27150,26 @@ snapshots:
msw: 2.11.3(@types/node@22.13.14)(typescript@7.0.2)
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
'@vitest/mocker@5.0.0(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@jridgewell/trace-mapping': 0.3.31
'@vitest/spy': 5.0.0
estree-walker: 3.0.3
magic-string: 1.2.3
optionalDependencies:
msw: 2.11.3(@types/node@24.19.0)(typescript@6.0.2)
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
'@vitest/mocker@5.0.0(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@jridgewell/trace-mapping': 0.3.31
'@vitest/spy': 5.0.0
estree-walker: 3.0.3
magic-string: 1.2.3
optionalDependencies:
msw: 2.11.3(@types/node@24.19.0)(typescript@6.0.2)
vite: 8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
'@vitest/pretty-format@5.0.0':
dependencies:
tinyrainbow: 3.1.1
@@ -29705,8 +29871,8 @@ snapshots:
'@babel/parser': 7.29.8
eslint: 9.37.0(jiti@2.7.0)(supports-color@8.1.1)
hermes-parser: 0.25.1
zod: 4.4.3
zod-validation-error: 4.0.2(zod@4.4.3)
zod: 4.6.5
zod-validation-error: 4.0.2(zod@4.6.5)
transitivePeerDependencies:
- supports-color
@@ -33476,6 +33642,33 @@ snapshots:
- '@types/node'
optional: true
msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2):
dependencies:
'@bundled-es-modules/cookie': 2.0.1
'@bundled-es-modules/statuses': 1.0.1
'@inquirer/confirm': 5.1.21(@types/node@24.19.0)
'@mswjs/interceptors': 0.39.7
'@open-draft/deferred-promise': 2.2.0
'@types/cookie': 0.6.0
'@types/statuses': 2.0.5
graphql: 16.11.0
headers-polyfill: 4.0.3
is-node-process: 1.2.0
outvariant: 1.4.3
path-to-regexp: 6.3.0
picocolors: 1.1.1
rettime: 0.7.0
strict-event-emitter: 0.5.1
tough-cookie: 6.0.0
type-fest: 4.30.0
until-async: 3.0.2
yargs: 17.7.2
optionalDependencies:
typescript: 6.0.2
transitivePeerDependencies:
- '@types/node'
optional: true
muggle-string@0.4.1: {}
mustache@4.2.0: {}
@@ -33545,9 +33738,14 @@ snapshots:
next: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
react: 19.2.6
next-seo@6.5.0(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
next-router-mock@0.9.13(next@16.3.6(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6):
dependencies:
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
react: 19.2.6
next-seo@6.5.0(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
dependencies:
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
@@ -33585,6 +33783,33 @@ snapshots:
- '@types/node'
- babel-plugin-macros
next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4):
dependencies:
'@next/env': 15.5.25
'@swc/helpers': 0.5.15
caniuse-lite: 1.0.30001809
postcss: 8.5.28
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@8.1.1))(babel-plugin-macros@3.1.0)(react@19.2.6)
optionalDependencies:
'@next/swc-darwin-arm64': 15.5.25
'@next/swc-darwin-x64': 15.5.25
'@next/swc-linux-arm64-gnu': 15.5.25
'@next/swc-linux-arm64-musl': 15.5.25
'@next/swc-linux-x64-gnu': 15.5.25
'@next/swc-linux-x64-musl': 15.5.25
'@next/swc-win32-arm64-msvc': 15.5.25
'@next/swc-win32-x64-msvc': 15.5.25
'@opentelemetry/api': 1.9.1
'@playwright/test': 1.59.1
sass: 1.77.4
sharp: 0.35.4(@types/node@24.19.0)
transitivePeerDependencies:
- '@babel/core'
- '@types/node'
- babel-plugin-macros
next@16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4):
dependencies:
'@next/env': 16.3.6
@@ -33613,6 +33838,34 @@ snapshots:
- '@types/node'
- babel-plugin-macros
next@16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4):
dependencies:
'@next/env': 16.3.6
'@swc/helpers': 0.5.23
baseline-browser-mapping: 2.11.13
caniuse-lite: 1.0.30001809
postcss: 8.5.28
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@8.1.1))(babel-plugin-macros@3.1.0)(react@19.2.6)
optionalDependencies:
'@next/swc-darwin-arm64': 16.3.6
'@next/swc-darwin-x64': 16.3.6
'@next/swc-linux-arm64-gnu': 16.3.6
'@next/swc-linux-arm64-musl': 16.3.6
'@next/swc-linux-x64-gnu': 16.3.6
'@next/swc-linux-x64-musl': 16.3.6
'@next/swc-win32-arm64-msvc': 16.3.6
'@next/swc-win32-x64-msvc': 16.3.6
'@opentelemetry/api': 1.9.1
'@playwright/test': 1.59.1
sass: 1.77.4
sharp: 0.35.4(@types/node@24.19.0)
transitivePeerDependencies:
- '@babel/core'
- '@types/node'
- babel-plugin-macros
nf3@0.3.24: {}
nice-try@1.0.5: {}
@@ -33907,13 +34160,13 @@ snapshots:
next: 16.3.6(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
react-router: 7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
nuqs@2.8.1(@tanstack/react-router@1.170.41(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6):
nuqs@2.8.1(@tanstack/react-router@1.170.41(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6):
dependencies:
'@standard-schema/spec': 1.0.0
react: 19.2.6
optionalDependencies:
'@tanstack/react-router': 1.170.41(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
react-router: 7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
nuxt@4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.150.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.148.0)(rolldown@1.2.9)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.9)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0):
@@ -36300,6 +36553,40 @@ snapshots:
'@img/sharp-win32-x64': 0.35.4
'@types/node': 22.13.14
sharp@0.35.4(@types/node@24.19.0):
dependencies:
'@img/colour': 1.1.0
detect-libc: 2.1.2
semver: 7.8.5
optionalDependencies:
'@img/sharp-darwin-arm64': 0.35.4
'@img/sharp-darwin-x64': 0.35.4
'@img/sharp-freebsd-wasm32': 0.35.4
'@img/sharp-libvips-darwin-arm64': 1.3.3
'@img/sharp-libvips-darwin-x64': 1.3.3
'@img/sharp-libvips-linux-arm': 1.3.3
'@img/sharp-libvips-linux-arm64': 1.3.3
'@img/sharp-libvips-linux-ppc64': 1.3.3
'@img/sharp-libvips-linux-riscv64': 1.3.3
'@img/sharp-libvips-linux-s390x': 1.3.3
'@img/sharp-libvips-linux-x64': 1.3.3
'@img/sharp-libvips-linuxmusl-arm64': 1.3.3
'@img/sharp-libvips-linuxmusl-x64': 1.3.3
'@img/sharp-linux-arm': 0.35.4
'@img/sharp-linux-arm64': 0.35.4
'@img/sharp-linux-ppc64': 0.35.4
'@img/sharp-linux-riscv64': 0.35.4
'@img/sharp-linux-s390x': 0.35.4
'@img/sharp-linux-x64': 0.35.4
'@img/sharp-linuxmusl-arm64': 0.35.4
'@img/sharp-linuxmusl-x64': 0.35.4
'@img/sharp-webcontainers-wasm32': 0.35.4
'@img/sharp-win32-arm64': 0.35.4
'@img/sharp-win32-ia32': 0.35.4
'@img/sharp-win32-x64': 0.35.4
'@types/node': 24.19.0
optional: true
shebang-command@1.2.0:
dependencies:
shebang-regex: 1.0.0
@@ -36440,6 +36727,13 @@ snapshots:
sisteransi@1.0.5: {}
sitemap@9.0.1:
dependencies:
'@types/node': 24.19.0
'@types/sax': 1.2.7
arg: 5.0.2
sax: 1.6.1
slash@3.0.0: {}
slash@4.0.0: {}
@@ -36814,7 +37108,7 @@ snapshots:
supabase-management-js@2.0.2(supports-color@8.1.1):
dependencies:
axios: 1.18.1(supports-color@8.1.1)
zod: 4.4.3
zod: 4.6.5
transitivePeerDependencies:
- debug
- supports-color
@@ -37267,6 +37561,8 @@ snapshots:
undici-types@6.20.0: {}
undici-types@7.24.6: {}
undici@7.30.0: {}
undici@8.11.2: {}
@@ -37305,12 +37601,12 @@ snapshots:
unicorn-magic@0.4.0: {}
unicornstudio-react@2.0.1-1(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
unicornstudio-react@2.0.1-1(next@15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
dependencies:
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
optionalDependencies:
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@24.19.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
unified@10.1.2:
dependencies:
@@ -37807,6 +38103,27 @@ snapshots:
- tsx
- yaml
vite-node@3.2.4(@types/node@24.19.0)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
cac: 6.7.14
debug: 4.4.3(supports-color@8.1.1)
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 7.3.5(@types/node@24.19.0)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
transitivePeerDependencies:
- '@types/node'
- jiti
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
vite-node@6.0.0(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
cac: 7.0.0
@@ -37885,6 +38202,24 @@ snapshots:
tsx: 4.22.4
yaml: 2.9.0
vite@7.3.5(@types/node@24.19.0)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
esbuild: 0.28.1
fdir: 6.5.0(picomatch@4.0.7)
picomatch: 4.0.7
postcss: 8.5.28
rollup: 4.60.3
tinyglobby: 0.2.17
optionalDependencies:
'@types/node': 24.19.0
fsevents: 2.3.3
jiti: 2.7.0
lightningcss: 1.33.0
sass: 1.77.4
terser: 5.48.0
tsx: 4.22.4
yaml: 2.9.0
vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
lightningcss: 1.33.0
@@ -37902,6 +38237,23 @@ snapshots:
tsx: 4.22.4
yaml: 2.9.0
vite@8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.7
postcss: 8.5.28
rolldown: 1.2.9
tinyglobby: 0.2.17
optionalDependencies:
'@types/node': 24.19.0
esbuild: 0.28.1
fsevents: 2.3.3
jiti: 2.7.0
sass: 1.77.4
terser: 5.48.0
tsx: 4.22.4
yaml: 2.9.0
vitefu@1.1.3(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)):
optionalDependencies:
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
@@ -37958,6 +38310,58 @@ snapshots:
transitivePeerDependencies:
- msw
vitest@5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@types/chai': 5.2.2
'@vitest/mocker': 5.0.0(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
chai: 6.2.2
es-module-lexer: 2.3.2
expect-type: 1.4.0
magic-string: 1.2.3
obug: 2.1.4
picomatch: 4.0.7
std-env: 4.2.0
tinybench: 6.1.4
tinyexec: 1.3.0
tinyglobby: 0.2.17
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@opentelemetry/api': 1.9.1
'@types/node': 22.13.14
'@vitest/coverage-v8': 5.0.0(vitest@5.0.0)
'@vitest/ui': 5.0.0(vitest@5.0.0)
happy-dom: 20.14.5
jsdom: 28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1)
transitivePeerDependencies:
- msw
vitest@5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@types/chai': 5.2.2
'@vitest/mocker': 5.0.0(msw@2.11.3(@types/node@24.19.0)(typescript@6.0.2))(vite@8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
chai: 6.2.2
es-module-lexer: 2.3.2
expect-type: 1.4.0
magic-string: 1.2.3
obug: 2.1.4
picomatch: 4.0.7
std-env: 4.2.0
tinybench: 6.1.4
tinyexec: 1.3.0
tinyglobby: 0.2.17
vite: 8.2.1(@types/node@24.19.0)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@opentelemetry/api': 1.9.1
'@types/node': 22.13.14
'@vitest/coverage-v8': 5.0.0(vitest@5.0.0)
'@vitest/ui': 5.0.0(vitest@5.0.0)
happy-dom: 20.14.5
jsdom: 28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1)
transitivePeerDependencies:
- msw
vscode-languageserver-types@3.17.5: {}
vue-bundle-renderer@2.3.2:
@@ -38365,9 +38769,9 @@ snapshots:
dependencies:
zod: 3.25.76
zod-validation-error@4.0.2(zod@4.4.3):
zod-validation-error@4.0.2(zod@4.6.5):
dependencies:
zod: 4.4.3
zod: 4.6.5
zod@3.25.76: {}