Commit Graph
2805 Commits
Author SHA1 Message Date
Ivan Vasilov 99fd5d0117 fix: Refactor some suspicious Valtio uses (#48141)
This PR is partly driven by changes in
https://github.com/supabase/supabase/pull/48102. Claude identified code
smells of Valtio state which are not bugs at the moment, but we should
address in case their usage changes.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved AI assistant message updates to prevent unexpected state
changes.
* Fixed table editing behavior to preserve shared data and prevent
accidental in-place mutations.
* Improved consent handling by preventing SDK internals from being
altered by state management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 16:36:47 +02:00
Danny White 6cff728742 feat(studio): polish Connect sheet mode selector and steps (#48266)
## What kind of change does this PR introduce?

UI polish for the Connect sheet: clearer mode selection, wider sheet
layout, and step/content chrome across Direct, Server, MCP, and shadcn
flows.

## What is the current behavior?

- Connect modes use a weak selected state and an awkward grid layout.
- The sheet can jump width below the `lg` breakpoint when switching
modes.
- Direct connection chrome is noisy (reset in a footer, Title Case /
mono pooler labels, mismatched copy-button sizes).
- Several steps use admonitions or extra tips that repeat footer
guidance.
- Case-sensitive import of `InlineLink` breaks Linux/Vercel builds.

## What is the new behavior?

### Mode selector and sheet
- Stronger selected/hover treatment; comfortable single row that wraps
via `@container`.
- Empty odd slots use a sunk placeholder cell.
- Sheet uses `size="lg"` with `max-w-4xl` and `w-full min-w-0` so width
stays stable when switching modes.

### Steps chrome
- “Follow these steps” header with a copy-prompt action for coding
agents.
- Optional steps labelled `(optional)`.
- Shared `CodeBlock` for install snippets; MCP feature groups preselect
all except Storage.
- Server / shadcn tips folded into footers; IPv4 add-on admonition is
responsive with an inline Learn more link and a single Enable action.

### Direct connection
- Connection string and connection parameters stay one step (same
credentials, two formats).
- Reset database password lives in the string card title row beside
Shared/Dedicated pooler.
- Card titles use sans + sentence case (`Shared pooler`, `Connection
parameters`); `.env` stays mono.
- Icon-only copy buttons match CodeBlock square sizing; row actions sit
slightly closer to the right edge (`pr-2`).
- Shared pooler toggle copy clarified.

| Before | After |
| --- | --- |
| <img width="390" height="763" alt="API Keys Settings Chisel Toolshed
Supabase"
src="https://github.com/user-attachments/assets/adca3cc5-94f8-47e5-a4a2-2831790f430a"
/> | <img width="390" height="763" alt="API Keys Settings Chisel
Toolshed Supabase"
src="https://github.com/user-attachments/assets/f03afe58-e654-435e-a821-835f6243ca95"
/> |
| <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed
Supabase"
src="https://github.com/user-attachments/assets/79f08620-7e1e-4246-a70f-801606c0f499"
/> | <img width="1718" height="1323" alt="API Keys Settings Chisel
Toolshed Supabase"
src="https://github.com/user-attachments/assets/fb45e851-955e-46c2-90f1-afecb93d6ac4"
/> |
| <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed
Supabase"
src="https://github.com/user-attachments/assets/eda36d21-bba7-46ab-ad48-134acf93b471"
/> | <img width="1718" height="1323" alt="API Keys Settings Chisel
Toolshed Supabase"
src="https://github.com/user-attachments/assets/b7b728c6-fc92-46a7-8e3f-2f182c56ece7"
/> |

### Test plan

- [ ] Open **Connect** and confirm mode cells select/hover clearly;
narrow the sheet and confirm wrap + stable width.
- [ ] Direct: switch Direct / Transaction / Session; confirm pooler
title, reset in title row, parameters table, and percent-encode note.
- [ ] Toggle IPv4 shared pooler on Transaction; confirm string updates
and admonition/Learn more behaviour when on IPv4-only paths.
- [ ] Server: `.env` Copy all / row copy sizing; install command copy.
- [ ] MCP / shadcn / Framework: steps still resolve and copy prompt
still builds a useful agent prompt.
- [ ] Spot-check light/dark and a Linux/Vercel build (InlineLink import
casing).
2026-07-25 00:13:54 +10:00
Joshen Lim afd1d326bd Add default aria label for MetricCard tooltip (#48298)
## Context

As per PR title

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Accessibility Improvements**
* Added an accessible “More information” label to metric card tooltip
triggers, improving support for screen readers.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 21:46:10 +08:00
Joshen Lim 34e2585756 Fix MetricCard tooltip not tabbable (#48294)
## Context

`MetricCard` component in ui-patterns has a tooltip that currently isn't
tabbable as `asChild` is applied to `TooltipTrigger` which the child is
just an SVG.

Removing `asChild` as the fix so that `TooltipTrigger` is rendered as a
`button`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved tooltip behavior for metric card help icons.
* Ensured the tooltip trigger renders consistently when users interact
with it.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 11:02:04 +00:00
Alaister YoungandAlaister Young a06eb5f26f [FE-3724] feat(studio): add enable cleanup button to cron jobs page (#48200)
Adds a standalone **Enable cleanup** button to the Cron Jobs page header
so users can schedule the daily `delete-job-run-details` cleanup job
proactively — previously this was only reachable inside the conditional
"table too big" overflow dialog. Addresses
[FE-3724](https://linear.app/supabase/issue/FE-3724/enable-pg-cron-cleanup-job-from-ui-and-api)
(the UI half; the Management API half needs platform-side work).

**Added:**
- `Enable cleanup` button in the cron jobs header (left of Refresh),
hidden while the existence check loads and whenever a
`delete-job-run-details` job already exists
- Confirmation dialog with a retention-period select (defaults to 7
days), live SQL preview, and telemetry
(`cron_job_cleanup_enable_button_clicked` with `origin` +
`retentionInterval`)
- Component tests (MSW) for visibility gating and the schedule/cancel
flows
- E2E regression test for the full schedule → delete → button-reappears
cycle

**Fixed:**
- Name-based `useCronJobQuery` lookup: the `queryFn` dropped the `name`
param, and a not-found job returned `undefined` (rejected by react-query
v5) — now passes `name` through and returns `CronJob | null`
- Cache invalidation gaps: create/delete now invalidate the whole
cron-jobs prefix (list, count, job details), so the footer count updates
after create/delete and the button reappears after the cleanup job is
deleted. The schedule mutation deliberately invalidates only the
existence check + count (see inline comment)
- Pre-existing e2e leak: the cleanup-workflow test left
`delete-job-run-details` scheduled; it now cleans up after itself

## Screenshots

| Header button | Dialog |
| --- | --- |
| <img width="890" height="325" alt="Screenshot 2026-07-22 at 9 44
40 PM"
src="https://github.com/user-attachments/assets/966cd640-d8a6-4c8f-92e7-73151bf4de9c"
/> | <img width="512" height="461" alt="fe3724-dialog"
src="https://github.com/user-attachments/assets/6be1785f-cc7e-4048-a648-9ef260b0949f"
/> |

## To test

- Go to a project's Integrations → Cron → Jobs with pg_cron enabled and
no `delete-job-run-details` job → the `Enable cleanup` button shows next
to Refresh
- Open the dialog, switch retention intervals → the SQL preview updates;
confirm → success toast, the job appears in the grid (`0 12 * * *`), and
the button disappears without a reload
- Delete the `delete-job-run-details` job from the grid → the button
reappears without a reload
- Create then delete any other job → the footer `Total: N jobs` count
updates both ways without a reload
- Regression: with the high-query-cost banner forced (or via the e2e),
the overflow dialog's "Schedule cleanup job" step still shows its
success state — the dialog must not close mid-flow

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Added an **Enable cleanup** action to the Cron Jobs tab header,
including a retention selector and SQL preview.
* Enabling schedules the daily cleanup, shows a success toast, updates
the grid, and hides the enable button; **Cancel** closes the dialog
without scheduling.

* **Bug Fixes**
  * Improved cron job lookup to work by name when needed.
* Refreshed related cron job data more reliably after scheduling and
deletion.

* **Telemetry**
  * Added an event for cleanup enable button clicks.

* **Tests**
* Added component and Playwright coverage for
enable/cancel/schedule/delete and cleanup banner flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-24 16:43:00 +08:00
b2b150fa3c feat(pipelines): Add UI selector for choosing which tables to skip copy of (#47808)
## Summary

Adds initial-copy scoping to Pipelines in Studio. Users can copy all
existing rows, skip all initial copies, copy only selected publication
tables, or skip selected table copies. All publication tables continue
streaming new changes regardless of the initial-copy policy.

The policy now round-trips through create, edit, validation, and the
generated Management API contract. Initial-copy estimates and
table-restart confirmations use the same scope. Edit requests also
preserve redacted credentials and pipeline settings that Studio does not
own.

This completes the Studio layer of the [ETL API
change](https://github.com/supabase/etl/pull/897) and [Management API
change](https://github.com/supabase/platform/pull/35479).

## Screenshots

### Selector

<img width="1153" height="465" alt="image"
src="https://github.com/user-attachments/assets/bf615e82-ee61-4222-979d-a8695a957e82"
/>

### Select certain tables only

<img width="1153" height="465" alt="image"
src="https://github.com/user-attachments/assets/28adaa24-f239-4d1d-8fb8-fdb1988320cd"
/>

### Confirm copy costs

As the final step before the pipeline is created:

<img width="597" height="619" alt="image"
src="https://github.com/user-attachments/assets/a660bd87-bfb8-41c5-8099-4cdbdef943bf"
/>


### Policy-aware initial-copy estimate

#### Copy no table is selected

<img width="407" height="464" alt="image"
src="https://github.com/user-attachments/assets/99d859ec-2ec3-452a-ab69-11924a8db260"
/>

#### Some tables are selected

<img width="407" height="464" alt="image"
src="https://github.com/user-attachments/assets/e68aedf4-66bc-4372-98ef-0dd7fecef324"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added configurable “initial table copy” policies (copy/skip all and
copy/skip selected) during replication setup, including table-picker
behavior, pruning of stale selections, and updated restart/cost
estimates.
- **Bug Fixes**
- Improved restart flows to consistently use `schema.table` identity and
simplified “errored tables” targeting to match error-state tables.
- Reduced unnecessary loading by gating publication/table fetches to
when panels are visible; improved validation/toast handling when
publication tables are unavailable.
- **Tests**
- Added/expanded coverage for destination form submission, table-copy
selection, restart/cost dialogs, and copy-estimate summarization.
- **Style**
- Refreshed warning/label text for clearer configuration and
confirmation messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-24 10:29:46 +03:00
Andrew ValleteauandClaude Fable 5 6c6a721cb7 fix(pg-meta): scope remaining O(catalog) introspection queries behind pgMetaScopedIntrospection (#48148)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix (performance), follow-up to #47894, plus regression-guard tests.

## What is the current behavior?

#47894 scoped the Table Editor and entity-definition introspection
queries, but four more `@supabase/pg-meta` query families still do
O(catalog) work per request. On a production project with a very large
catalog (hundreds of schemas, ~465K `pg_constraint` rows) they run 5 to
55 seconds each, trip the 58s `statement_timeout`, and spill sorts to
temp files. During a recent "DB CPU > 85%" incident on such a project,
24 of 27 active backends were running these queries concurrently.

1. **`tables.retrieve()` (single-table lookup by name+schema or id)**:
the `tables`/`columns` CTEs scan the whole catalog (`pg_class`,
`pg_constraint`, `pg_index`, all of `pg_attribute`, per-table sizes) and
the one-table predicate is applied only on the outer select. Same bug
class #47894 fixed for the OID-based table editor query; this sibling
path never got the treatment. It accounted for 94 of the 96
statement-timeout cancellations in the incident.
2. **Types listing**: the `t_enums` and `t_attributes` subqueries
aggregate the entire `pg_enum` and every composite relation before the
wrapper's schema filter applies.
3. **Table privileges**: `aclexplode` + double `pg_roles` join + GROUP
BY over every relation in the database; schema/OID filters applied only
after aggregation, in both `list()` and `retrieve()`.
4. **Row counts**: `getTableRowsCountSql` treats `reltuples = -1`
(never-analyzed table) as "small table, run exact count(*)". A freshly
bulk-loaded multi-million-row table times out on every Table Editor
pagination render.

Two Studio-side amplifiers turned one slow query into a sustained load
storm:

- `useTableQuery` (behind `tables.retrieve()`) mounts once per visible
foreign-key grid cell via `ForeignKeyFormatter`, so a single Table
Editor view fires ~20 concurrent copies against the FK target table. A
timed-out query caches nothing, and TanStack retries errored no-data
queries on every observer mount by default, so scrolling kept re-issuing
the 58s scan.
- `useTableApiAccessQuery` fetched table privileges for the entire
database and filtered down to one schema client-side.

## What is the new behavior?

**pg-meta (all behind the existing `pgMetaScopedIntrospection` flag,
same rollout mechanism as #47894; `scoped: false` keeps serving the
current SQL):**

- `tables.retrieve()`: the identifier is resolved to a scalar
`targetOid` init-plan and pushed into the base scan, primary-key,
relationships (both FK directions kept: `conrelid` or `confrelid`) and
columns CTEs. A materialized `target` CTE was deliberately avoided: it
acts as an optimization barrier and forces the very seq scans being
removed.
- Types: filter `pg_type`/`pg_namespace` first, then compute
enums/attributes per surviving row via correlated index-scan subqueries
(`pg_enum(enumtypid, enumsortorder)`, `pg_attribute(attrelid, attnum)`).
- Table privileges: schema/OID predicates injected into the base WHERE
before `aclexplode`/GROUP BY for `list()` and `retrieve()`.
- Row counts: `reltuples = -1` is treated as "unknown" and gated on
physical size via `pg_relation_size` (a cheap stat call; `relpages` is
equally stale pre-vacuum). At or below `THRESHOLD_ESTIMATE_BYTES`
(~10MB, derived from `THRESHOLD_COUNT` at a conservative ~200 bytes/row)
the exact count runs as before: fast by construction, and it avoids
bogus estimates since Postgres floors never-vacuumed heaps at 10 pages,
so an empty table would otherwise report ~2K estimated rows. Above the
gate the count routes through the EXPLAIN-based
`pg_temp.count_estimate`, or returns `-1`/`is_estimate = true` in
read-only contexts where the temp function cannot be created. The scoped
branch embeds the estimated select via `literal()` instead of legacy's
apostrophe-only escaping, so it stays correct under
`standard_conforming_strings = off`. `enforceExactCount` unchanged.

**Studio:**

- The flag decision is contained in the data layer instead of
prop-drilled: a small imperative accessor
(`apps/studio/data/scoped-introspection.ts`) is hydrated from `useFlag`
via a one-line `useSyncScopedIntrospection()` call in `DefaultLayout`,
and the query functions read it internally when building the pg-meta
SQL. `DefaultLayout` is shared by both the Next and TanStack router
trees; hydrating from `_app.tsx` alone would leave TanStack-served pages
permanently unscoped since `routes/__root.tsx` mounts its own flag
provider. Cold loads cannot race the flag: the query functions await a
readiness promise that resolves only after the sync hook has hydrated
the accessor with a loaded flag store (immediately on self-hosted where
flags are disabled; a 5s safety net armed lazily on the first `ready()`
call - not at module import, which would let the timer expire before a
project page ever mounts - bounds genuine ConfigCat outages). No
component threading, no query-key changes (remaining tradeoff,
documented in the module: a mid-session flag flip can serve stale-keyed
caches until refetch, fine for a session-stable rollout flag). #47894's
existing threading is left as-is and gets deleted together with the flag
in the cleanup PR. Also fixes the previously-missing `scoped`
pass-through in `getTableRowsCount`.
- Flag-independent hardening: `useTableQuery` now sets `retryOnMount:
false`, `refetchOnWindowFocus: false` and `staleTime: 5min`. Errored
(timed-out) queries no longer refire on every grid cell remount, while
stale successful metadata still revalidates on mount after `staleTime`.
- `useTableApiAccessQuery` now passes `includedSchemas: [schemaName]`;
the client-side filter stays as a safety net.
- The rows-count query is `enabled`-gated on the permission check
settling, so a transiently-false `canSQLAdminWrite` can no longer cache
a read-only `-1` count for a writable user (read replicas short-circuit
synchronously as before).

**Regression guards (extending the #47894 infrastructure):**

- Execution-based scoped-vs-legacy equivalence tests for all four
queries: both variants run against the test database and are compared
with raw `toEqual` - no normalization, ids included (types across 6
option combos, privileges incl. multi-grantee + PUBLIC,
`tables.retrieve` for both identifier branches, row counts for every
case where the two paths must agree). Two documented exceptions where
only the LEGACY side is sorted, because a de-normalized diagnostic run
proved legacy emits genuinely plan-dependent order there (an
adversarial-FK fixture shows it is neither oid, name, nor creation
order): the `types.list` outer row order (scoped adds `order by t.oid`;
legacy has no ORDER BY) and the `tables.retrieve` relationships array
(scoped orders by `constraint_name` + column-name tie-breakers - a
composite two-column FK expands to 4 entries sharing one
constraint_name). Everything else (privileges via `aclexplode` over the
same relacl, columns by `ordinal_position`, primary keys by `indkey`
order, enums by `enumsortorder`) is byte-identical between the two paths
with no test-side help. The one intentional value divergence,
never-analyzed tables above the size gate where legacy's exact count is
the timeout bug itself, is asserted explicitly as a divergence.
- Plan-guard budgets for every scoped query against the stress catalog
(extended with 200 enums + 200 composite types). Residual seq scans are
justified in-budget: `pg_constraint` max 2 (no index on `confrelid`),
`pg_attrdef` max 1, `pg_authid` max 2 (scales with role count, not
schema count).
- Legacy templates carry a FROZEN do-not-edit marker (they must keep
matching production behavior until the flag cleanup deletes them); the
ordinary test suite runs against the legacy default, so behavioral drift
there fails regular tests.

### Validation

- pg-meta: typecheck clean; the affected suites (types,
table-privileges, tables, rows-count, catalog-plan-guard) pass in full.
- Cross-version: the scoped-vs-legacy equivalence and rows-count
behavioral suites were validated on PostgreSQL 14, 15, and 17 (identical
results on all three). Two version-marginal planner choices surfaced on
17 (`pg_type` / `pg_class` seq scan vs full-index bitmap for per-schema
listings, both structurally unavoidable without an index leading on the
namespace column) and are carried as justified plan-guard budget
entries. A full 468-test suite run sequentially: 452 passed, 16 failures
verified environmental (13 timeouts in an untouched file that passes
27/27 in isolation on the marathon-run cluster, 3 cluster-global role
collisions from container reuse).
- Studio: `pnpm --filter studio typecheck` clean; 39/39 tests across the
touched data hooks; eslint clean on touched files.

### Rollout

Same staged ConfigCat rollout as #47894 via `pgMetaScopedIntrospection`
(user-email targeting first, then percentage, then 100%). The
`useTableQuery` hardening and the API-access schema scoping ship
unflagged (behavior-safe). Gate before percentage rollout: functionally
verify the FK popover/selector UX under the new
`staleTime`/`retryOnMount` settings (a just-edited FK target must not
look stale anywhere Studio does not already refetch on save). Once fully
rolled out, the legacy templates and flag get deleted together with
#47894's in one cleanup PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:07:08 +02:00
Nik RichersandNik Richers e0ecaadc21 docs: make AI tools section agent-first (#48167)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

This PR reworks the `/guides/ai-tools` docs section to be agent-first.
The overview now leads with the fastest path to a working setup (the
plugin install command), a "What's supported?" card grid showing which
coding agents and IDEs work via Plugin and/or MCP (with each product's
own tagline, not a generated sentence), and a concepts glossary —
instead of a plain four-item list. The sidebar "AI Tools" widget, shown
on every guides page, now links to this hub ("Connect your AI agent")
instead of opening a ChatGPT/Claude chat frontend.

Closes DOCS-1201.

## What is the current behavior?

- The `/guides/ai-tools` overview is a plain four-item bullet list with
no getting-started path, compatibility info, or concepts explanation.
- The sidebar "AI Tools" widget offers "Copy as Markdown", "Ask
ChatGPT", and "Ask Claude" — the latter two send you to a chat frontend
instead of agent setup.

## What is the new behavior?

- `ai-tools.mdx`: intro → plugin install callout → "What's supported?"
card grid (`<ContentListings id="ai-tools-supported-agents" />`, icon +
tagline + Plugin/MCP badge per agent) → "Key concepts" glossary →
"Building AI into your app?" (also converted to `ContentListings`).
- New `data/content-listings/ai-tools.data.ts` builds the card grid from
the existing `PLUGIN_CLIENTS`/`MCP_CLIENT_DATA` client lists (no new
hand-maintained data) — fixing two latent bugs found along the way:
GitHub Copilot was keyed differently between the two sources (would have
produced duplicate cards), and Windsurf has no upstream docs URL (would
have been silently dropped).
- New opt-in `badgePosition` field on `ContentListingItem` so the badge
renders under the title for the agent grid, without changing the one
other existing badge usage (self-hosting's "Official" tag, still
inline).
- `plugins.mdx`/`mcp.mdx`/`ai-skills.mdx` each get a one-line "Quick
start" lead-in so they stand alone via the `.md` content-negotiation
route.
- `GuidesSidebar.tsx` + `telemetry-constants.ts`: Added "Connect your AI
agent" → `/guides/ai-tools`, and the `ask_ai_clicked` event with
`agent_setup_clicked`.
- Accessibility fix (from review): the "Not supported" indicator now
exposes an `sr-only` label instead of being fully `aria-hidden`.

## Additional context

- Worktree:
`~/GitHub/supabase/supabase-worktrees/nikrichers/docs-1201-make-guidesai-tools-agent-first-and-replace-chat-frontend`
- **Open question — Windsurf card**: `windsurf.com` now redirects to a
Devin Desktop page (Cognition acquired Windsurf in 2025), but Supabase's
own `MCP_CLIENT_DATA` still targets Windsurf's distinct config path
(`~/.codeium/windsurf/mcp_config.json`), so the card is still labeled
"Windsurf" with its pre-acquisition tagline ("The first agentic IDE.
Tomorrow's editor, today."). Needs a follow-up decision on whether to
relabel/merge/drop this card once Devin Desktop's MCP support (if any)
is confirmed.
- Follow-up (not in this PR): deeper IA rework of the ai-tools section
belongs to the broader agent-first audit;
`content/guides/resources/glossary.mdx` has no MCP/Agent
Skills/Plugin/Prompts entries yet — this PR's "Key concepts" is
currently the only definition of these terms site-wide.
- Verification:

  | Check | Result |
  | --- | --- |
| Lint (`lint:mdx`, `eslint`), `typecheck`, `test:local
lib/content-listings.test.ts` | Pass — 13/13 tests, 0 errors |
| `build:guides-markdown` | Pass — card grid flattens cleanly to
markdown |
| Playwright: broken icon requests, light + dark theme, PR preview |
Pass — 0 in either theme |
| `/guides/self-hosting` "Official" badge (existing `ContentListings`
usage) | Pass — unaffected by the new `badgePosition` opt-in |

### Before & After

#### [`/guides/ai-tools`](https://supabase.com/docs/guides/ai-tools)

Also shows the sidebar change (right rail): "Ask ChatGPT" / "Ask Claude"
→ "Connect your AI agent".

| [Before](https://supabase.com/docs/guides/ai-tools) |
[After](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools)
|
| --- | --- |
|
![Before](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr48167/ai-tools-before-79e9cdcf.png)
|
![After](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr48167/ai-tools-final-full-7ab9f52f.png)
|

Sub-pages each just add a one-line "Quick start" callout under the intro
(no other layout change):
[plugins](https://supabase.com/docs/guides/ai-tools/plugins)
([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/plugins))
· [mcp](https://supabase.com/docs/guides/ai-tools/mcp)
([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/mcp))
· [ai-skills](https://supabase.com/docs/guides/ai-tools/ai-skills)
([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/ai-skills)).

### Test plan

- [x] `/guides/ai-tools` renders callout → card grid → concepts →
Building AI into your app, in order
- [x] Card grid: one card per agent (no duplicate Copilot), Windsurf
present, icons clean in both themes, taglines shown, badges below title
- [x] Sidebar shows "Connect your AI agent"; self-hosting's "Official"
badge unaffected
- [x] `.md` route still serves clean markdown; no lingering
`ask_ai_clicked`, ChatGPT/Claude icon, or `SupportedAgentsTable`
references

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
2026-07-23 16:01:54 -07:00
Ali Waseem f653600517 fix(studio): make failed Postgres upgrade banner dismissible (#48260)
- The failed-upgrade banner reflects the API's last-known upgrade
status, which stays "Failed" indefinitely even after a project is
restored, so it never went away
- A hard refresh didn't help, since this isn't client-cached state
- Adds a dismiss action, scoped to the attempt's `initiated_at` so a
future failed upgrade still shows the banner

Fixes FE-3964

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added a dismiss control to project upgrade failure notifications.
* Dismissed notifications remain hidden for the current project until a
new upgrade failure occurs.
  * Contact support remains available alongside the dismiss option.

* **Bug Fixes**
* Improved upgrade failure banner behavior by persisting dismissal state
across page visits.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 14:02:10 -06:00
Danny White 3bca21b3f8 chore(a11y): convert leftover focus recipes to focus-ring (#48219)
## What kind of change does this PR introduce?

Accessibility cleanup (DEPR-628).

## What is the current behavior?

Leftover call sites still use ad-hoc focus recipes
(`ring-foreground-muted`, `outline-brand`, Dialog/Sheet `focus:` rings,
etc.) instead of the shared utilities from #41575.

## What is the new behavior?

Converts those leftovers across `packages/ui`, Studio, www, docs, and
design-system to `focus-ring`, preferring `focus-visible`. Keeps
documented exceptions (`group-focus-visible`, InputGroup `:has()`).

## To test

Tab through controls (keyboard only). Expect a consistent offset ring on
`:focus-visible`, not a green/brand/custom stack, and no ring animation.

### www (marketing)

Preview:
https://zone-www-dot-com-git-danny-depr-628-focus-ring-fbccf9-supabase.vercel.app

- Global nav on `/`: Product, Developers, Solutions dropdowns; logo;
hamburger + mobile menu
- `/features`: view toggles and feature cards
- `/company`: card links
- `/changelog`: timeline / entry links
- `/partners/catalog`: grid/list toggle and partner cards
- `/pricing`: compute section expand control
- Product / Modules / Solutions sticky navs on product pages (e.g.
`/database`, `/storage`)
- `/state-of-startups`: TwoOptionToggle if present

### docs

Preview:
https://docs-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Any guide page: top nav dropdowns and items
- Narrow viewport: hamburger, then mobile menu links + close
- Guide with PromptPanel / tabs: tab to prompt actions and tab list

### studio (dashboard)

Preview:
https://studio-staging-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Project home: Connect section tiles; drag-handle focus on sortable
sections
- Integrations marketplace (`/project/<ref>/integrations`): featured
cards, list/grid toggle, list rows
- Auth (`/project/<ref>/auth/oauth-apps`,
`/project/<ref>/auth/providers`): open create/edit sheet, tab to close
(X)
- Database policies (`/project/<ref>/database/policies`): open policy
editor sheet, tab to close
- Storage policies (`/project/<ref>/storage/files/policies`): bucket
section links; policy modal close
- Query performance (`/project/<ref>/observability/query-performance`):
info icon buttons on metrics
- Replication pipeline detail (if available): slot lag / status info
icons
- Support (`/support/new`): attachment add/remove controls
- Table editor: spreadsheet import preview checkboxes; row text/JSON
editor TwoOptionToggle
- Any Dialog/Sheet/toast close (X): ring on keyboard focus only, not
mouse click

### design-system

Preview:
https://design-system-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Colour palette swatches (keyboard focus)
- Form patterns sidepanel example: avatar / focusable control in the
example

## Additional context

- Linear: [DEPR-628](https://linear.app/supabase/issue/DEPR-628)
- Follow-ups: form-group CSS (DEPR-629), Storage columns selection
(DEPR-630), ESLint rule (DEPR-632)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Accessibility & Usability**
* Standardized keyboard focus indicators across navigation, dialogs,
forms, buttons, toggles, links, and tooltips using a consolidated focus
style.
* Improved toggle controls to use proper button semantics (instead of
clickable text), including `aria-pressed`/disabled handling and better
keyboard navigation.

* **Visual Updates**
* Harmonized hover/focus ring visuals across the design system, Studio,
documentation, and marketing pages while preserving existing layout and
interaction behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 08:52:22 +10:00
Danny White 6f6badae51 fix(eslint): promote require-explicit-tabindex to error (#48170)
## What kind of change does this PR introduce?

Accessibility / lint hardening (Safari keyboard focus).

## What is the current behavior?

`supabase/require-explicit-tabindex` is `'warn'`. Studio’s ratchet was
at 0 but the rule was still ratcheted; www / docs / design-system still
had raw `<button>` / `role="button"` call sites without an explicit
`tabIndex`.

[DEPR-627](https://linear.app/supabase/issue/DEPR-627) · follow-up to
#47984 / #48040

## What is the new behavior?

- Shared config: `'supabase/require-explicit-tabindex': 'error'`
- Swept www / docs / design-system (+ Studio test fixtures the ratchet
skipped)
- Removed the rule from the Studio ratchet + baselines

## To test

Prefer **Safari**. This PR only adds explicit `tabIndex` to raw
`<button>` / `role="button"` call sites — not links, and not controls
that already go through `Button` from `ui`.

### Marketing (`www`) ([staging
link](https://zone-www-dot-com-git-danny-depr-627-promote-req-7ae43c-supabase.vercel.app/))

- [x] Homepage frameworks / dashboard feature tabs — Tab through each
tab button
- [x] Product pages (e.g. `/auth`, `/database`) — section tab switchers
- [x] Narrow viewport — open the hamburger; Tab through menu buttons
- [x] `/partners/catalog` — filter / view controls
- [x] Blog view toggle (list ↔ grid)

### Docs ([staging
link](https://docs-git-danny-depr-627-promote-require-explici-25e46d-supabase.vercel.app/))

- [x] **Desktop (≥ lg):** top-right **⋯ menu** (hamburger icon) — opens
a dropdown that includes Theme. Not a separate theme button.
- [x] **Mobile (< lg):** top-right **hamburger** opens the sheet; close
(X) is the raw button we tagged. Theme inside the sheet uses
`ThemeToggle` / `DropdownMenuTrigger` from `ui` (already supposed to set
`tabIndex`).
- [x] **Code blocks** — copy / language controls
- [x] **Is this helpful?** — X / check are `Button` from `ui` (should
already Tab). After voting **while signed in**, the follow-up “What went
well?” / “How can we improve?” text button is the raw one we tagged.
- [x] **AI Tools → Copy as Markdown** (right rail on a guide) — this is
the only GuidesSidebar control this PR changed. “On this page” TOC items
are **links**, not covered by this lint.
- [x] **Reference docs** (e.g. JS client reference) — section headers
that expand/collapse in the left nav (`Collapsible.Trigger`)
- [x] **Troubleshooting index** — type in the search field, then Tab to
the **clear (X)** control

### Dashboard (`studio`)

No production UI changes in this PR (tests + lint config only). Quick
Safari smoke that prior tabindex work still holds:

- [x] Project sidebar — Tab through primary nav links
- [x] Settings → General — Tab through inputs / buttons
- [x] Storage → Files — Tab a bucket row / file actions
2026-07-23 05:21:15 +10:00
Miranda Limonczenko 359974d071 fix(docs) Fix local broken links (#48212)
Closes DOCS-1202

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## Problem

We have broken local links in docs.

I ran locally tests that crawl through all of our docs and flags broken
local links.

## Solution

This PR fixes local links where they were errored. The report I
generated had false-positives, so there are fewer fixes than initially
thought.

## Preview checklist

Docs preview:
https://docs-git-docs-fix-broken-local-links-supabase.vercel.app
WWW preview (redirects):
https://zone-www-dot-com-git-docs-fix-broken-local-links-supabase.vercel.app

| Page | Live (broken) | Preview (fixed) | Where to look |
| --- | --- | --- | --- |
| Amazon Bedrock |
[Live](https://supabase.com/docs/guides/ai/integrations/amazon-bedrock)
|
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/ai/integrations/amazon-bedrock)
| **You'll also need** → `A Postgres database with the pgvector
extension` |
| Getting started |
[Live](https://supabase.com/docs/guides/getting-started) |
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/getting-started)
| Tutorial cards → **Expo React Native Social Auth** |
| Product security |
[Live](https://supabase.com/docs/guides/security/product-security) |
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/security/product-security)
| **Database** list → `Superuser access and unsupported operations` |
| OAuth flows |
[Live](https://supabase.com/docs/guides/auth/oauth-server/oauth-flows) |
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/auth/oauth-server/oauth-flows)
| End of page, before **Next steps** → `OAuth methods in supabase-js` |
| ElevenLabs TTS |
[Live](https://supabase.com/docs/guides/functions/examples/elevenlabs-generate-speech-stream)
|
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/functions/examples/elevenlabs-generate-speech-stream)
| **Dependencies** → ElevenLabs `JavaScript SDK` |
| ElevenLabs STT |
[Live](https://supabase.com/docs/guides/functions/examples/elevenlabs-transcribe-speech)
|
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/functions/examples/elevenlabs-transcribe-speech)
| **Dependencies** → ElevenLabs `JavaScript SDK` |
| Realtime error codes |
[Live](https://supabase.com/docs/guides/realtime/error_codes) |
[Preview](https://docs-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/realtime/error_codes)
| `RealtimeDisabledForTenant` → reference link |
| Expo social auth redirect (legacy) |
[Live](https://supabase.com/docs/guides/with-expo-social-auth) |
[Preview](https://zone-www-dot-com-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/with-expo-social-auth)
| Should land on the Expo social auth quickstart |
| Expo social auth redirect (old tutorials path) |
[Live](https://supabase.com/docs/guides/getting-started/tutorials/with-expo-social-auth)
|
[Preview](https://zone-www-dot-com-git-docs-fix-broken-local-links-supabase.vercel.app/docs/guides/getting-started/tutorials/with-expo-social-auth)
| Should land on the Expo social auth quickstart |

### Manual testing

1. For each row, open the **Live** link and find the linked text in
**Where to look**.
2. Click the link and confirm it 404s or lands on the wrong page.
3. Open the matching **Preview** link, find the same linked text, and
click it.
4. Confirm the preview link resolves to the correct destination:
   - Amazon Bedrock → `/docs/guides/database/extensions/pgvector`
- Getting started →
`/docs/guides/auth/quickstarts/with-expo-react-native-social-auth`
   - Product security → `/docs/guides/database/postgres/roles-superuser`
   - OAuth flows → `/docs/reference/javascript/auth-admin-oauth-server`
- ElevenLabs TTS / STT → `https://github.com/elevenlabs/elevenlabs-js`
- Realtime error codes →
`/docs/guides/troubleshooting/realtime-project-suspended-for-exceeding-quotas`
- Redirect rows →
`/docs/guides/auth/quickstarts/with-expo-react-native-social-auth`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Updated links for pgvector, OAuth, ElevenLabs SDK, and database
security guidance.
  * Corrected the Expo React Native social authentication tutorial link.
* Updated Realtime troubleshooting references to the current
documentation path.

* **Bug Fixes**
* Fixed redirects for Expo social authentication guides so legacy URLs
reach the correct quickstart.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 11:49:04 -07:00
Alaister YoungandAlaister Young 25658ab733 chore(lint): ignore dist build output in shared ESLint config (#48216)
Follow-up to #48202. The shared ESLint flat config only globally ignored
`.next`, `public`, and `.contentlayer`, so with the TanStack Start
migration, Studio's Vite build output in `dist/` was getting linted too
— making `pnpm --filter studio run lint:ratchet` (and regular lint) far
slower than it should be. ESLint flat config doesn't respect
`.gitignore`, so being gitignored didn't help.

**Changed:**

- Added `dist` to the global `ignores` in `eslint-config-supabase/next`
(applies to all apps extending the shared config)

## To test

- In `apps/studio` (with a `dist/` folder present from a TanStack
build), run `npx eslint dist/server/server.js` — it should report "File
ignored because of a matching ignore pattern"
- `pnpm --filter studio run lint:ratchet` no longer spends time linting
`dist/**`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated linting exclusions to ignore generated build output and static
asset directories.
  * Generalized related configuration documentation for clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-22 18:29:41 +00:00
Danny White 90a53a5ee2 feat(studio): add shadcn tweet to sign-in testimonials (#48204)
## What kind of change does this PR introduce?

Chore

## What is the current behavior?

Sign-in testimonials are drawn from the weighted tweet pool in
`packages/shared-data/tweets.ts`. shadcn's quote is not included.

Resolves
[FE-3978](https://linear.app/supabase/issue/FE-3978/add-shadcn-tweet-to-sign-in-page).

## What is the new behavior?

Adds [@shadcn](https://x.com/shadcn/status/1672913636132790272)'s tweet
("Supabase is really good. ⚡") with weight `10`, plus the profile image
under `twitter-profiles`.

## Additional context

Weighted selection on the Studio sign-in page and `topTweets` on www
both pick this up from the shared list.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Updated tweet module documentation to explain how tweet `weight`
impacts Studio sign-in weighted random selection and the `topTweets`
list (top 18 by weight).
* **New Content**
* Added a new tweet to the collection with an explicit `weight` of 10,
making it eligible for weighted selection and top-ranked inclusion.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 02:21:41 +10:00
Danny White c8aca8d3a0 chore(design-system): standardise keyboard focus rings (#41575)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

UI / design-system consistency (accessibility).

## What is the current behavior?

Keyboard focus rings are inconsistent across Studio and `packages/ui`:

- Custom Button uses thick `outline` with per-variant colours (brand /
grey / destructive / warning)
- Form controls use muted grey rings (`ring-background-control`)
- Tabs / NavMenu / Radio use soft brand `ring-ring`
- Studio `.inset-focus` uses dark green `outline-brand-600`

Related: [DEPR-354](https://linear.app/supabase/issue/DEPR-354).

## What is the new behavior?

One shared focus recipe, exposed as Tailwind `@utility` classes in
`packages/config/css/utilities.css`:

| Utility | Use when |
| --- | --- |
| `focus-ring` | Buttons, inputs, most controls (offset ring) |
| `focus-inset` | Dense/flush surfaces such as interactive table rows
(renamed from `inset-focus`) |

```txt
# focus-ring
outline-hidden
focus-visible:ring-2
focus-visible:ring-ring
focus-visible:ring-offset-2
focus-visible:ring-offset-background
```

Applied on Button, shadcn form controls, Menu/NavMenu, Command palette
trigger, Studio table rows, and related call sites. Documented in the
design-system accessibility docs. Variants do not change focus ring
colour.

When the ring must appear on a different element than the focused one
(e.g. Menu + ProductMenu `Link` via `group-focus-visible`, or InputGroup
via `:has()`), keep an explicit ring stack. The utilities bake in
`:focus-visible` on the same element.

## Additional context

**Out of scope**

- Full `packages/ui` / Studio / www sweep
- Legacy Studio form-group green box-shadow cleanup
- ESLint rule for bare `outline-none`

## Test plan

Prefer Safari (“hard mode” for `tabIndex`). Expect one soft brand ring
everywhere: not grey, not solid green outline.

### Design system

- [ ]
[Accessibility](https://design-system-git-dnywh-choreimprove-tab-focus-styles-supabase.vercel.app/design-system/docs/accessibility):
recipe docs match what you see
- [ ]
[Button](https://design-system-git-dnywh-choreimprove-tab-focus-styles-supabase.vercel.app/design-system/docs/components/button):
Tab primary / default / danger; same ring colour
- [ ] [Table → Row-level
navigation](https://design-system-git-dnywh-choreimprove-tab-focus-styles-supabase.vercel.app/design-system/docs/components/table#row-level-navigation):
Tab an interactive row; inset outline (`focus-inset`) sits inside the
row

### Studio

- [ ] **Org home → table view** (`/organizations/_` or org projects):
switch to the table layout, Tab onto a project row; inset outline sits
inside the row (list/card view uses CardButton, not `focus-inset`)
- [ ] **Project sidebar** (Database, Auth, Storage, …): Tab the main
product nav links; ring follows the focused item (not the nested section
menus like Tables / Roles)
- [ ] **Storage → Files**: Tab a bucket row; same inset outline as org
table rows
- [ ] **Project Settings → General** (or Compute and Disk): Tab through
inputs, checkboxes, switches, selects; same offset ring, no ring on
mouse click
- [ ] **Header ⌘K** (desktop width): Tab to the search control after
Feedback; same soft brand `focus-ring` (was a thicker
`ring-border-strong` before)
- [ ] **Table Editor or SQL Editor tabs**: focus a tab, Tab to × if
active; close shows a ring
- [ ] **Light + dark**: ring stays visible against both backgrounds
2026-07-22 12:10:07 -04:00
Ivan Vasilov 2428bddcb5 chore: Bump vulnerable deps (#48178)
Fixes the following vulnerabilities:
- https://github.com/supabase/supabase/security/dependabot/3963
- https://github.com/supabase/supabase/security/dependabot/3963
- https://github.com/supabase/supabase/security/dependabot/3964
- https://github.com/supabase/supabase/security/dependabot/3965
- https://github.com/supabase/supabase/security/dependabot/3966
- https://github.com/supabase/supabase/security/dependabot/3927
- https://github.com/supabase/supabase/security/dependabot/3955
- https://github.com/supabase/supabase/security/dependabot/3913
- https://github.com/supabase/supabase/security/dependabot/3972
- https://github.com/supabase/supabase/security/dependabot/3959
- https://github.com/supabase/supabase/security/dependabot/3960
- https://github.com/supabase/supabase/security/dependabot/3916
- https://github.com/supabase/supabase/security/dependabot/3918
- https://github.com/supabase/supabase/security/dependabot/3947
- https://github.com/supabase/supabase/security/dependabot/3948
- https://github.com/supabase/supabase/security/dependabot/3956
- https://github.com/supabase/supabase/security/dependabot/3957
- https://github.com/supabase/supabase/security/dependabot/3958
- https://github.com/supabase/supabase/security/dependabot/3917
- https://github.com/supabase/supabase/security/dependabot/3919
- https://github.com/supabase/supabase/security/dependabot/3970
- https://github.com/supabase/supabase/security/dependabot/3928
- https://github.com/supabase/supabase/security/dependabot/3949
- https://github.com/supabase/supabase/security/dependabot/3950
- https://github.com/supabase/supabase/security/dependabot/3973
- https://github.com/supabase/supabase/security/dependabot/3920
- https://github.com/supabase/supabase/security/dependabot/3951

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated the bundled `tar` dependency to a newer patch version for
consistency and security across the workspace.
* Added/adjusted overrides to pin a few transitive dependencies to
specific versions.
* Normalized workspace configuration formatting and made minor
development configuration cleanup (no functional change).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 14:45:45 +02:00
Joshen Lim cf7da58eb3 Add overview section for database connections (#48147)
## Context

Building on top of "Database Connections" - this adds a top summary
section, again from `pg_stat_activity`
<img width="948" height="324" alt="image"
src="https://github.com/user-attachments/assets/f4968193-0a5f-4754-a630-40685b747999"
/>

Each block comes with a tooltip in hopes to educate the significance of
each metric
- Connections: Spread of connections per database role
<img width="313" height="164" alt="image"
src="https://github.com/user-attachments/assets/8ceeab5d-b960-4be3-9a5b-8600bd5cf303"
/>
- Active queries: Rough representative of activity
<img width="350" height="196" alt="image"
src="https://github.com/user-attachments/assets/f9705ff1-a869-409a-86b6-50170a169674"
/>
- Idle in transaction: Important to identify as this indicates locks
(Suggests root cause)
<img width="350" height="196" alt="image"
src="https://github.com/user-attachments/assets/f9705ff1-a869-409a-86b6-50170a169674"
/>
- Blocked queries: Also important to identify stuck queries
<img width="335" height="183" alt="image"
src="https://github.com/user-attachments/assets/57255fb8-24f6-4ddd-aa54-850a77173b5c"
/>
- Longest running query: Might be useful to identify unusually long
queries
- Will be `text-warning` if exceeds 30 seconds for active queries,
`text-destructive` if exceeds 10 seconds for queries idle in transaction
<img width="342" height="119" alt="image"
src="https://github.com/user-attachments/assets/f6783b43-058a-4a32-a40c-0bc64f23d2ce"
/>

"Summarize activity" CTA leverages on the Assistant to give a quick
overview - highlights any potential issues for quick reference
<img width="1918" height="958" alt="image"
src="https://github.com/user-attachments/assets/340121fe-3186-48a5-8023-fbac2a93397a"
/>

## Other changes
- Hides "View running queries" in SQL Editor if `topForPostgres` feature
flag is enabled (since this UI is meant to replace that)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Database Connections observability overview with metric cards
(connections, longest-running, active, blocked, idle-in-transaction) and
an interactive “Longest running” PID selector.
* Added a “Summarize activity” AI assistant dropdown that starts a
timestamped, activity-aware summary chat.
* **Improvements**
* Enhanced live activity refresh (including window-focus updates) and
standardized duration warning thresholds for active and
idle-in-transaction sessions.
* Improved hover details for query previews and allowed richer tooltip
content for metric labels.
* **Feature Changes**
  * Gated the “View running queries” bottom panel behind a feature flag.
* **Bug Fixes**
* Refined running-too-long badge and warning styling for
idle-in-transaction cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 17:25:56 +08:00
Vaibhav 2e12cdc2e1 fix: empty search_path (#48151)
## TL;DR
Restores handling for functions with `search_path` set to `''` editing
them in the UI was failing with a Postgres `zero-length delimited
identifier` error since the SafeSql refactor dropped the empty-string
sentinel conversion

## ref
- closes #48149


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Preserved empty `search_path` configuration values when updating
database functions.
* Prevented empty configuration values from being altered or lost during
function updates.

* **Tests**
* Added coverage verifying that function definitions can be updated
without changing an existing empty `search_path` setting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-21 15:34:50 +00:00
Danny WhiteandJoshen Lim 0324f3422a chore(studio): polish vercel deploy-button new project interstitial (#48113)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Studio UI polish for the Vercel deploy-button new-project connect flow
(DEPR-616 follow-up).

## What is the current behavior?

- Deploy-button project creation still used
`VercelIntegrationWindowLayout` (top bar + Docs/Support footer) while
install and choose-project already use shared `InterstitialLayout`
- The remove-integration note sat as a floating admonition above the
form
- Advanced / internal-only config sections could show double dividers,
and the Oriole radio bottom border could clip inside the collapsible

## What is the new behavior?

- Deploy-button new-project uses `InterstitialLayout` with
`VercelIntegrationLogo` and `VercelIntegrationFooter`, matching the
other Vercel connect surfaces
- Regular `/new` project creation is unchanged; Panel chrome is only
flattened when `isVercelIntegrationFlow` is set
- Removes unused `VercelIntegrationWindowLayout` /
`IntegrationWindowLayout`
- Fixes Advanced/Internal-only dividers and collapsible border clipping

| Before | After |
| --- | --- |
| <img width="965" height="1107" alt="Supabase"
src="https://github.com/user-attachments/assets/99c1225c-c9e5-4fac-bd64-17920403e447"
/> | <img width="965" height="1107" alt="Create Vercel Project Supabase"
src="https://github.com/user-attachments/assets/c42bff96-5f9f-4c8b-8f3c-093e380f90ed"
/> |

## Additional context

### Testing

With Studio running locally and while signed in:

1. Open
`http://localhost:8082/integrations/vercel/<your-org-slug>/deploy-button/new-project`
2. Confirm the interstitial card: Vercel + Supabase logo pair, “Create a
new project” title, form fields, and the muted remove-integration footer
under the card
3. Confirm there is no old window chrome (no “Marketplace Connector” /
“Deploy Button” top bar, no Docs/Support footer)
4. Optionally submit and confirm project creation still works
5. Spot-check `/new` to confirm the normal project creation form is
unchanged

If you have advanced config enabled, expand Advanced Configuration and
confirm single dividers (not doubles) and that the Oriole option’s
bottom border is not clipped.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Added configurable width to the shared interstitial layout for Vercel
project creation.
  * Updated the Vercel “new project” flow to use the interstitial UI.

* **Bug Fixes**
* Prevented child borders/shadows from being clipped in expandable
configuration sections.

* **Refactor**
* Removed legacy Vercel/window layout components and updated routing to
rely on the interstitial flow.
* Switched advanced and internal-only configuration sections to render
inside panel content.

* **Documentation**
* Refreshed Vercel integration route guidance in the migration checklist
and inline route comments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-22 00:08:00 +10:00
Joshen Lim 76f44bfa71 Update Dev toolbar to support filtering feature flags (#48137)
## Context

Only applies for local development - adds a way to filter feature flags
in the dev toolbar
<img width="1385" height="223" alt="image"
src="https://github.com/user-attachments/assets/323d29f6-209e-4fc3-a7d0-4160b62b5707"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added search and filtering for feature flags from PostHog and
ConfigCat.
  * Added a clear button for quickly resetting searches.
* Added an informative empty state when no feature flags match the
search.
* Search terms reset automatically when switching between flag
providers.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-21 17:14:04 +08:00
Joshen Lim c7803b8b9b Chore/add sessions database connections (#48094)
## Context

Initial work for Top for Postgres - adds a "Sessions" section under a
new Observability segment "Database Connections"
NOTE: All the copywriting and naming might change - not sure what's an
ideal title for this
We'll also be iteratively building on top of this UI, adding more
actionable signals instead of just information
Changes are featured flagged, off for public

- This would essentially replace the "View ongoing queries" in the SQL
Editor by providing a dedicated UI
  - It checks against `pg_stat_activity` as per the ongoing queries UI
- We'll also subsequently deprecate the "Ongoing queries" UI in the SQL
editor
- Defaults into a "live mode" where the data is refreshed every 3
seconds via long-polling
<img width="983" height="474" alt="image"
src="https://github.com/user-attachments/assets/16402fe4-0b53-4f9e-9342-cdda26e3778a"
/>
- Supports filtering by state  
<img width="374" height="282" alt="image"
src="https://github.com/user-attachments/assets/562f8fbe-2dc6-48e7-8ec0-de7ffb8348d1"
/>
- Users can also terminate queries through here
<img width="247" height="164" alt="image"
src="https://github.com/user-attachments/assets/23a639dc-8f96-473a-a823-605b0bab02ee"
/>





<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

# Release Notes

* **New Features**
* Added an Observability **Database Connections** page with a live
**Sessions** activity table (state/roles filtering, blocked-by details,
session duration, and per-session termination with confirmation).
* Included a **Live/Pause** toggle to control automatic refresh (~3
seconds).

* **Enhancements**
* Improved Reports selection filtering: supports optional option
quantities, better popover styling, sorted apply behavior, and shows
quantity inline.
* Query performance duration formatting now supports configurable
decimal precision.
  * Tooltips can now render richer content (string or React node).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-21 16:52:03 +08:00
Saxon Fletcher 2d745edfb4 Landing page agent focus (#47989) 2026-07-21 14:30:36 +10:00
Pedro RodriguesandClaude Opus 4.8 45ba40eff9 docs: add Kimi Code to MCP and AI coding agent plugin setup (#48099)
Adds Kimi Code to the MCP server setup and AI coding agent plugins docs:

### MCP Server config

<img width="755" height="703" alt="image"
src="https://github.com/user-attachments/assets/b350aca0-ff0d-442b-b6f3-b3b4355d8fcd"
/>

### AI coding agent plugins

<img width="753" height="475" alt="image"
src="https://github.com/user-attachments/assets/100d5893-4627-4f48-9ab6-16e0c6457467"
/>



Closes AI-933

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added **Kimi Code** as a selectable plugin client in the plugins
panel.
* Added **Kimi-specific installation/setup instructions**, including
guidance on placing `mcp.json`, confirming the trust prompt, and using
`/plugins` plus `/mcp` and `/mcp-config`.
* Extended the **MCP URL builder** to generate Kimi Code HTTP-based
server configuration.
* Included **Kimi** in the **IDE** client group with a dedicated **Kimi
icon** for UI display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:37:02 +01:00
Danny White 3d07613c2b fix(ui): restore text-contrast token (#48017)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix

## What is the current behavior?

`text-contrast` / `text-foreground-contrast` resolve to
`--primary-foreground`, which is always the darker of surface /
foreground lightness (text for the green primary fill).

In light mode that is near-black, so contrast text on inverted fills is
wrong: on true black (`bg-black`) it disappears; on dark fills like
`bg-red-900` it shows as a black icon instead of white. Visible
regression on the design-system colour usage page: the `text-contrast`
swatch only shows "Postgres" on hover.

Regression from the colour system rewrite (#47288), which aliased
`--foreground-contrast` → `--primary-foreground`.

## What is the new behavior?

`--foreground-contrast` is defined again as a surface-based inverse of
`--foreground` (light in light mode, dark in dark mode). Tailwind
utilities `text-contrast` and `text-foreground-contrast` map to it.

`--primary-foreground` is unchanged and still used for text on the
primary fill.

## Additional context

### Callsites to test (light mode especially)

| Where to look | What to check |
|---|---|
| [Design system → Colour
usage](https://design-system-git-fix-text-contrast-token-supabase.vercel.app/design-system/docs/color-usage)
| Under **Text**, the `text-contrast` swatch shows "Postgres" without
hovering |
| [Studio staging → Auth
Users](https://studio-staging-git-fix-text-contrast-token-supabase.vercel.app/project/_/auth/users)
→ open any user | Boolean fields (e.g. confirmed): check/X on the black
circle should be **white** (not missing) |
| [Studio staging → Support
new](https://studio-staging-git-fix-text-contrast-token-supabase.vercel.app/support/new)
→ upload a file | Red remove (`X`) badge should be a **white** X (prod
currently shows black) |
| [www →
Contribute](https://zone-www-dot-com-git-fix-text-contrast-token-supabase.vercel.app/contribute)
→ apply at least one filter | Filter count badge: **white** number on
black |
| [Studio staging → Support
link](https://studio-staging-git-fix-text-contrast-token-supabase.vercel.app/support/link)
success state (after linking a ticket) | Check on the brand badge should
use contrast text (light on brand in light mode) |

`Announcement` (`text-foreground-contrast` dismiss icon) is not
currently mounted in any app — covered by the design-system / token
check above.
2026-07-20 10:59:34 -04:00
Etienne Stalmans 05d5da0340 chore: add ssl_enforcement_required for jit (#48032)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

chore / bug fix

## What is the current behavior?

The new `ssl_enforcement_required` state is not handled

## What is the new behavior?

Displays the correct message




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved temporary database access messaging when SSL enforcement is
required.
* Added a direct action to open database settings and enable SSL
enforcement before activating temporary access.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 13:46:44 +02:00
Ivan Vasilov 24ce0ba5f8 chore: migrate repo to pnpm v11 (#48033)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Chore / dependency tooling update.

## What is the current behavior?

The repo is pinned to pnpm 10.24.0. Closes
https://linear.app/supabase/issue/FE-3673/migrate-the-repo-to-use-pnpm-v11.

## What is the new behavior?

The repo is pinned to pnpm 11.13.1, pnpm v11 workspace settings are
migrated to `allowBuilds`, and the Studio Dockerfile installs pnpm
11.13.1.

## Additional context

Validated with `CI=true mise exec node@22 -- pnpm install
--frozen-lockfile`, `mise exec node@22 -- pnpm run typecheck`, and `mise
exec node@22 -- pnpm run lint`; full Prettier check still fails on
existing generated docs/router files outside this migration.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated tooling requirements (pnpm **11.13.1**, Node **>=22.13**) and
aligned container build tooling accordingly.
* Adjusted package manager behavior (scoped registry override, update
notifications disabled) and workspace build/engine validation settings.

* **Maintenance**
* Updated `clean` scripts across apps/packages to remove only
build/cache artifacts (no longer delete installed dependencies).
* Reduced Turbo `clean` task output to **errors-only** for cleaner logs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 12:57:42 +02:00
Jordan McQueenandJoshen Lim fa1e4c4bbf feat(studio): add ClickHouse replication destination (#46870)
Adds ClickHouse as a replication destination type in Studio.

- New ClickHouse option in the destination type selector, gated behind
the
`etlEnableClickHousePrivateAlpha` organization feature flag (off by
default).
- ClickHouse settings form: URL, user, password (optional), database,
and
  - Client-side URL validation requires HTTPS and rejects URLs targeting
    internal addresses (loopback, RFC 1918, link-local, CGNAT, IPv6
    loopback/link-local/ULA, and IPv4-mapped/NAT64 forms). Server-side
    validation remains authoritative.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## New Features
- Added **ClickHouse** as a replication destination option (private
alpha), including support in destination selection/panel, replication
diagram rendering, and destination icons.
- Introduced a ClickHouse destination form with fields for URL, user,
optional password (masked toggle), database, and engine selection.
- Added ClickHouse destination config handling for create/update flows,
with normalization and engine support.

## Tests
- Expanded unit tests to cover ClickHouse validation and destination
config building/normalization, including HTTPS-only and blocking
localhost/internal targets.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-20 12:09:13 +08:00
Danny White 6f19dfe18c fix(ui): bake explicit tabindex into interactive primitives (#47984)
## What kind of change does this PR introduce?

A11y fix for keyboard focus (esp. Safari), plus a lint rule to keep it
from regressing.

## What is the current behavior?

`Button` already defaults an explicit `tabIndex={0}` (#40458). Other
interactive primitives (Checkbox, bare triggers, etc.) still skip Tab
focus in Safari unless macOS Keyboard navigation is on. Raw `<button>`
call sites have no guardrail.

## What is the new behavior?

- Same explicit `tabIndex` default baked into Checkbox, Accordion
Trigger, Collapsible Trigger, Dropdown Menu / Popover / Dialog / Sheet /
Alert Dialog triggers, Table Head Sort, Command reset, sidebar actions,
and shadcn Button
- `supabase/require-explicit-tabindex` ESLint rule, ratcheted in Studio
(82 existing violations)
- Design-system accessibility docs list which primitives bake this in

Resolves [DEPR-621](https://linear.app/supabase/issue/DEPR-621)

## Additional context

### To test

Use **Safari** with macOS Keyboard navigation **off** (the default).
Chrome once for a sanity pass.

**Storage → Files bucket (list view) — Checkbox**

1. Open an empty folder (or one with only folders). Header “select all”
Checkbox is disabled and skipped by Tab — expected (`columnFiles.length
=== 0`).
2. Upload a file (e.g. an image). Header Checkbox enables.
3. Tab to it and toggle with Space. Row Checkboxes should also be
Tab-reachable.

**Storage → Analytics bucket → bucket details — Accordion Trigger**

On an Analytics bucket with no tables yet, Tab to the “Create your first
table via PyIceberg” Accordion Triggers and open/close with Enter/Space.

**Elsewhere (light smoke)**

- Bare Dropdown / Popover / Collapsible triggers still Tab + activate
- `*Trigger asChild><Button>` (Sheets, Dialogs, menus) still one Tab
stop; open/close fine
- Disabled controls stay out of the Tab order

### Later

Chip-away of the 82 raw Studio buttons (and remove exceptions from
rule). Prefer migrating those to `Button` from `ui` later.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Accessibility Improvements**
* Improved keyboard focus behavior across common interactive controls
(buttons, dialog/popover/dropdown/sheet triggers,
accordions/collapsibles, checkboxes, and sidebar actions).
* Disabled controls now default to `tabIndex={-1}`, while enabled
controls default to `tabIndex={0}`.
* Added explicit `tabIndex` handling for command reset and table sort
header controls.
* **New Features**
* Added a shared `getExplicitTabIndex` utility used by UI components to
standardize focus behavior.
* **Documentation**
* Updated accessibility guidance to clarify which components include
built-in focus/tabIndex handling and which require manual setup.
* **Developer Experience**
* Added an ESLint rule to enforce explicit `tabIndex` on raw button-like
elements, with corresponding baseline updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-18 00:18:45 +10:00
Danny White 50e9fedb20 feat(studio): finesse logs date picker range colours (#48019)
## What kind of change does this PR introduce?

UI polish / bug fix for the shared Calendar range selection and Logs
date picker.

## What is the current behavior?

- Selected date ranges use opaque `brand-400` / `brand-500` fills that
read too loud in light mode, with black text that is hard to read on
darker endpoints.
- Start/end days are squared off on the connecting edge without
intentional outer rounding.
- Outside days in a selected range are dimmed with `opacity-50`, which
can tint the range wash incorrectly when a range starts in the prior
month.
- The large-range warning in `LogsDatePicker` is a full-bleed yellow
banner that feels too heavy for the popover.
- Time inputs show a clock icon that adds visual noise.

## What is the new behavior?

- Range middle uses a softer `brand-200` wash; start/end stay on
stronger brand fills with readable foreground text.
- Start days round on the left (`rounded-l-md`), end days on the right
(`rounded-r-md`); day hover keeps `rounded-md`.
- Selected outside days and “today” no longer fight the range wash
colours.
- Large-range warning is quiet inline `text-warning` copy that wraps to
the calendar column width.
- Clock icon removed from `TimeSplitInput`.

| Before | After |
| --- | --- |
| <img width="1096" height="1076" alt="CleanShot 2026-07-16 at 17 59
21@2x"
src="https://github.com/user-attachments/assets/eac38022-ed92-4dbe-9932-55f7bf0af934"
/> | <img width="988" height="1064" alt="CleanShot 2026-07-16 at 17 59
34@2x"
src="https://github.com/user-attachments/assets/3dce30dd-9fd8-4da4-82b3-5663250a4ddc"
/> |

## Additional context

Shared `Calendar` changes apply anywhere range mode is used, not only
logs.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Style**
- Refined the date-picker popover layout for start/end controls with
better fit and max-width handling.
- Updated calendar day and range visuals (selection, outside states,
rounding, and hover behavior) to reduce “ghost” styling and improve
consistency.
  - Restyled the large-range warning to improve spacing and alignment.
- Simplified the time-splitting input UI by removing the leading clock
icon.
- Adjusted the “Copy range” button feedback color for copied/pasted
states.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-18 00:17:52 +10:00
Riccardo Busetti f19cb09b43 feat(pipelines): Update product docs and UI copy (#47997) 2026-07-17 11:43:04 +02:00
3c6ef31959 feat: add User Filter to the unified logs (#47879)
Offshoot from https://github.com/supabase/supabase/pull/47743.

[Linear
issue](https://linear.app/supabase/issue/FE-3939/add-user-logs-filter-to-the-logs-page)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a `user` filter to Unified Logs with a user picker (email or
ID).
* Added “View user logs” actions from the Users table to jump to Unified
Logs.
* **Bug Fixes**
* Updated Unified Logs searching so default log-type restrictions no
longer block user-attributed results.
* **UI Updates**
* Unified Logs filter bar and reset behavior now include clearing the
user filter.
* Improved empty-state messaging when the selected user filter isn’t
supported.
  * Refreshed highlighted styling in command list items.
* **Tests**
* Expanded coverage for user filter configuration and query edge cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: kemal.earth <606977+kemaldotearth@users.noreply.github.com>
Co-authored-by: kemal <hello@kemal.earth>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-17 17:21:55 +08:00
Joshen Lim 04a11b715a Fix some colors (#47996)
## Context

In the table editor when hovering over a row that has fixed columns, the
wordings could appear like they're overlapping
<img width="339" height="95" alt="image"
src="https://github.com/user-attachments/assets/9de8252c-08fc-4dec-a2f2-21461e47691e"
/>

This is due to the `bg-surface-200` class that gets applied to rows on
hover which use alpha values, hence why it's happening. Opting to use
`bg-200` instead which doesn't have alpha values.

Also small fix for the copy button in `CodeBlock` as well which is
running into the same issue - opting to use a set of colors that doesn't
have alpha values instead.
<img width="127" height="115" alt="image"
src="https://github.com/user-attachments/assets/4d773474-49e0-4c3b-bea1-042ff3102f9c"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Updated table header, row hover, and selected-row background colors
for a more consistent appearance.
* Enhanced the code block copy button’s dark-mode and hover background
styling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 17:59:50 +08:00
Ali WaseemandJoshen Lim ae957414b4 fix(studio): make unified logs sidebar banner dismissible (#47977)
## Summary
- Adds a close button to the "Introducing unified logs" sidebar banner,
storing the dismissal in localStorage so it stays hidden.

## Test plan
- [ ] Open Logs Explorer, confirm the X dismisses the banner and it
stays gone after reload.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added an `X` close button to the unified logs preview banner.
* Remember banner dismissal using local storage, so it stays hidden
after closing.
* Updated banner visibility rules to account for unified-logs preview
enablement and default opt-in state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-16 03:29:00 +00:00
Danny White 2279c4e69e fix(studio,www): repair Join us on Discord buttons (#47711)
## What kind of change does this PR introduce?

Bug fix

## What is the current behavior?

The "Join us on Discord" buttons are broken in two places:

- **Studio support sidebar** (`HelpPanel`): on light mode the button
background is not white, so the intended white button with purple icon
and text is broken.
- **www `/support` page** (shared `secondary` button variant): the text
disappears on hover, and the Discord icon is never rendered (always
invisible). Both issues occur on light and dark mode.

## What is the new behavior?

- **Studio support sidebar**: force a white background on all colour
schemes via `bg-white hover:bg-white/90`, matching the existing pattern
in `DiscordCTACard`. The purple icon and text now render correctly on
light mode.
- **Shared `secondary` button variant** (`packages/ui`):
- The icon container used `text-border-muted`, which blended into the
`bg-foreground` button, so the icon was invisible. Changed to
`text-background` to match the button's text colour.
- The hover state used `text-border-stronger`, which had no contrast
against the background, so text disappeared on hover. Changed to
`text-background/80`.
- Removed the ineffective `fill="var(--background-default)"` from
`IconDiscord` on the `/support` page — the SVG path uses `currentColor`,
so the fill prop had no effect.

These `secondary` variant fixes apply globally, so other secondary
buttons benefit too.

| Before | After |
| --- | --- |
| <img width="868" height="642" alt="CleanShot 2026-07-07 at 15 39
42@2x"
src="https://github.com/user-attachments/assets/6897b6ba-311e-43c7-bb5a-7b70017a54cc"
/> | <img width="906" height="610" alt="CleanShot 2026-07-07 at 16 21
31@2x"
src="https://github.com/user-attachments/assets/16104cf0-8ed1-4857-8467-532c1f7fdb5f"
/> |
| <img width="636" height="620" alt="CleanShot 2026-07-07 at 15 24
53@2x"
src="https://github.com/user-attachments/assets/75f55f6c-eaa7-45ee-94fe-eac513126eff"
/> | <img width="656" height="404" alt="CleanShot 2026-07-07 at 16 24
23@2x"
src="https://github.com/user-attachments/assets/35649b23-fcdd-42fd-8140-e4aaf394667e"
/> |

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **Style**
* Refreshed secondary button styling for a more consistent look,
including updated hover and loading text/icon colors.
* Improved the “Join us on Discord” button’s background and hover
appearance.
* Simplified the Discord card’s icon rendering to rely on the default
icon styling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 03:01:25 +10:00
Danny White df69219859 fix(ui): restore success and warning badge contrast (#47828)
## What kind of change does this PR introduce?

Bug fix

## What is the current behavior?

After the colour system migration, `Badge` success and warning variants
use semantic `text-brand` / `text-warning` (and soft `border-brand` /
`border-warning` tokens). In light mode those fills sit around mid–high
lightness, so the badges look flat and the text is hard to read.

Call sites that never migrated — e.g. Compute badges (`SMALL`) and table
constraint tokens (`PRIMARY`) — still use the darker scale tokens and
look fine.

## What is the new behavior?

Success and warning badges again use the darker scale tokens, matching
those working call sites:

- success: `text-brand-600` + `border-brand-500`
- warning: `text-warning-600` + `border-warning-500`

| Before | After |
| --- | --- |
| <img width="791" height="288" alt="Tables Database Chisel Toolshed
Supabase"
src="https://github.com/user-attachments/assets/99659555-bf78-42d7-af93-415cdc8e858c"
/> | <img width="791" height="288" alt="82859"
src="https://github.com/user-attachments/assets/368d4a8e-d7cf-4bf6-b896-89f29eca982d"
/> |

## To test

On the staging preview in **light mode**:

- Any `Badge variant="success"` — e.g. “New”, “Enabled”, “Healthy”,
branch badges
- Any `Badge variant="warning"` — e.g. beta / warning status badges
- Compare with Compute size badges and Database → Tables → Columns →
Constraints (`PRIMARY`) — contrast should now feel similar

Spot-check **dark mode** to confirm badges still look correct.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Updated warning and success badges with refined text and border colors
for improved visual consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 00:09:22 +10:00
Danny White 805aee289e fix(studio): color regressions after theme update (#47794)
## What kind of change does this PR introduce?

Bug fix + small shared component

## What is the current behavior?

After the recent colour system changes, several UI elements lost
contrast in light mode:

- `InfoIcon` with a background appeared as a flat grey circle (glyph
fill matched the background)
- Several buttons forced `text-white`, which no longer contrasts
correctly against the updated brand fills
- Selected / completed check badges were inconsistent between call sites

## What is the new behavior?

- `InfoIcon` uses `text-background` for the glyph fill so the "i" is
visible against the grey circle
- www primary buttons drop hardcoded `text-white` and use standard
`Button` colours
- New shared `SuccessCheck` in `ui` for selected state and completion
progress (green circle; white check in light mode, black check in dark
mode)
- Documented in the design system with selected + progress examples

Note on `InfoIcon`:
[#47933](https://github.com/supabase/supabase/pull/47933) landed a
related fix using `text-background-200` (`--card`). This PR keeps
`text-background` instead, to match `CheckIcon` / `EyeOffIcon` in the
same file and avoid the legacy alias.

| Before | After |
| --- | --- |
| <img width="688" height="268" alt="CleanShot 2026-07-10 at 11 30
25@2x"
src="https://github.com/user-attachments/assets/c0276b0c-1023-46c8-805c-35a22def1353"
/> | <img width="664" height="278" alt="CleanShot 2026-07-10 at 11 29
43@2x"
src="https://github.com/user-attachments/assets/3508cf37-1b48-4fb7-a939-83522feb44f1"
/> |
| <img width="468" height="550" alt="CleanShot 2026-07-10 at 11 31
04@2x"
src="https://github.com/user-attachments/assets/acd42273-15ce-4fb2-9d0c-5a43ac23073c"
/> | <img width="460" height="540" alt="CleanShot 2026-07-10 at 11 32
50@2x"
src="https://github.com/user-attachments/assets/f66fb4bc-81f7-4df1-95f5-63980c4e8537"
/> |

## To test

Use the staging preview link from this PR and check the following in
**light mode** (and spot-check dark mode):

**www**
- Visit `/404` — "Head back" button should have readable text (not
white-on-green)
- Visit `/company` — "Join the team" button in the Team section
- Visit a product page with a hero CTA (e.g. `/database`, `/realtime`) —
primary "Start for free" button

**studio**
- Database → Replication → deploy a read replica — footer `InfoIcon`
next to the pricing line should show a visible "i" inside the grey
circle
- `/redeem` — select an org; green `SuccessCheck` should match
light/dark contrast (white check / black check)
- Settings → API → service role key row — red "secret" tag text should
be readable

**design system**
- `/docs/components/success-check` — demo, selected-state, and progress
examples
2026-07-15 14:09:08 +00:00
Francesco Sansalvadore 13330e6328 fix(ui): expandable video preview image (#47964)
## What kind of change does this PR introduce?

Restore preview image on ExpandableVideo trigger component.

## What is the current behavior?
<img width="1441" height="698" alt="Screenshot 2026-07-15 at 14 08 58"
src="https://github.com/user-attachments/assets/bdb1c4be-71a9-4601-b5c9-ab4fc97c48d1"
/>

<img width="1273" height="701" alt="Screenshot 2026-07-15 at 14 09 05"
src="https://github.com/user-attachments/assets/b8026bcc-3d43-4faa-873b-1745b32c166c"
/>

## What is the new behavior?
<img width="1434" height="678" alt="Screenshot 2026-07-15 at 14 08 53"
src="https://github.com/user-attachments/assets/8a3e64d1-5fe7-4ab9-a71b-3de5808d28b9"
/>

<img width="1160" height="672" alt="Screenshot 2026-07-15 at 14 08 48"
src="https://github.com/user-attachments/assets/db598a47-ed8e-435b-b3ef-8ae9e76761a2"
/>

---

Also fixed a border-b issue on the PartnerCatalogDetail.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
  - Added thumbnail previews for partner catalog YouTube videos.
- Improved video preview presentation with clearer overlays and stronger
image blur.

- **Bug Fixes**
  - Updated image loading support for YouTube thumbnail URLs.
  - Refined sticky tab header spacing and alignment while scrolling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 14:53:32 +02:00
kemal.earth 93e1631f19 fix: class name for text on infoicon (#47933)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Class name was bodged on `InfoIcon`. It was
`text-background-surface-200`, think after recent update it should be
`text-background-200`.

| Before | After |
|--------|--------|
| <img width="371" height="67" alt="Screenshot 2026-07-14 at 16 46 42"
src="https://github.com/user-attachments/assets/813ef5c8-98d1-4889-99b3-8bd885a48139"
/> | <img width="366" height="64" alt="Screenshot 2026-07-14 at 16 47
53"
src="https://github.com/user-attachments/assets/e76c120a-70c8-451a-a7a9-48814978cfd3"
/> |


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Updated the Info icon’s background-visible styling to use the correct
background color for improved visual consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 13:51:52 +01:00
Mert YEREKAPAN 320604d0e7 feat(studio): ship both upgrade CTA placements, remove A/B experiment (#47881)
## What

Concludes the `upgradeCtaPlacement` experiment
([#45858](https://github.com/supabase/supabase/pull/45858)) by shipping
**both** placements permanently and removing the A/B scaffolding.

The experiment tested two upgrade-CTA placements against a control:
- **`user_dropdown`** — an "Upgrade to Pro" button in the account/user
dropdown
- **`org_projects_list`** — a plan-usage card in the org project list

Both moved paid conversion in the same direction over control with no
activation downside, and they live on separate surfaces, so we're
keeping both rather than picking one.

## Changes

- **Remove the experiment machinery.** Deleted `useUpgradeCtaExperiment`
(PostHog `upgradeCtaPlacement` flag read, `control` arm, variant
selection, per-org localStorage seeding, exposure tracking) and replaced
it with a small `useShowUpgradeCta` hook that gates purely on **free
plan + hosted platform**. Both placements now render for every eligible
free-plan org.
- **Telemetry cleanup.** Removed the
`upgrade_cta_placement_experiment_exposed` event (pure experiment
scaffolding). Kept `upgrade_cta_clicked` (with its `placement` property)
so we can still measure the CTAs going forward; de-experimented its
wording.
- **Dead code.** Removed the unused `prependCard` prop plumbing added to
`ProjectList` / `EmptyStates` (no caller ever passed it — the org card
renders via the `<aside>`).
- De-experimented the remaining doc comments in `PlanUsageCard`.

Gating is unchanged in spirit: paid orgs and self-hosted never see the
CTA. `useShowUpgradeCta` waits until the org plan is known before
returning true, so the CTA fades in for free users and never flashes for
paid users.

## Testing

- `pnpm --filter common typecheck` and `pnpm --filter studio typecheck`
pass.
- eslint + prettier clean on the changed files.
- Manually checked


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Upgrade/usage CTAs now appear only when the organization is confirmed
to be on a free plan, avoiding premature rendering before plan data is
available.
- Upgrade CTA visibility is now consistently driven across supported
project and organization surfaces (including the user dropdown) for
org-scoped routes.

- **Bug Fixes**
- Removed obsolete “prepend” placeholders from the project list loading
and grid views to keep card layouts consistent.

- **Documentation**
- Clarified upgrade CTA telemetry wording and adjusted the frontend
telemetry contract.

- **Tests**
- Added coverage for upgrade-CTA visibility behavior across key
scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 12:17:07 +00:00
d23f86021a feat(www): Partner Catalog update (#46757)
## Info architecture change around "Partners"

The www "integrations" now become more partner-driven.
`/partners/integrations` -> now Partner Catalog under
`/partners/catalog` (old links redirect to new paths)

Moved them close together in the nav dropdown and in the footer
<img width="494" height="336" alt="Screenshot 2026-07-09 at 11 06 41"
src="https://github.com/user-attachments/assets/a875fef0-0ab8-47ca-8756-d658b27c4892"
/>
<img width="1149" height="665" alt="Screenshot 2026-07-09 at 11 09 48"
src="https://github.com/user-attachments/assets/9631bb72-fe25-4fb4-b1af-9f14a37d02e7"
/>

## /partners 

This page remains untouched in this PR, updates to layout, content and
intake form are delegated to #47874

## /partners/catalog

Listed in the
[catalog](https://zone-www-dot-com-git-feat-www-partners-pages-supabase.vercel.app/partners/catalog)
are now partners. Some partners match with a listing.

<img width="1207" height="866" alt="Screenshot 2026-07-09 at 11 14 17"
src="https://github.com/user-attachments/assets/b65216be-976f-4ef5-91f8-1ad49da87b45"
/>

## /partners/catalog/[partner]

Each partner can have one or more "listings" which are either 
- simple guides
- foreign data wrappers
- dashboard integrations

Integrations available in the dashboard now all have a prominent
"Install integration" cta to open it in the dashboard [integrations
page](https://supabase.com/dashboard/project/_/integrations).

<img width="1269" height="776" alt="Screenshot 2026-07-09 at 11 16 51"
src="https://github.com/user-attachments/assets/3c7bb715-ffce-4d0a-905f-9a660c3b1f5a"
/>

## Docs

Update docs →
[Preview](https://docs-git-feat-www-partners-pages-supabase.vercel.app/docs/guides/integrations)
- remove "Supabase marketplace"
- use "Dashboard Integrations and Partner Catalog
- update integrations in sidenav to link to updated /partners/catalog/**
listings

<img width="1520" height="696" alt="Screenshot 2026-07-15 at 12 54 47"
src="https://github.com/user-attachments/assets/9f5a2794-4536-4299-97df-9732d3d75b4c"
/>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Partner Catalog experience with search, category filters,
official-partner toggle, responsive filtering (sidebar + bottom sheet),
grid/list views, and featured partners.
* Added Partner Catalog detail pages with tabbed listings, MDX-rendered
content, image gallery with zoom overlay, and “add/install” actions.
* **Improvements**
* Updated “Become a Partner” layout and form support for prefilled
values and checkbox-group fields (including validation).
* Updated navigation/footer/docs and partner tile links to use Partner
Catalog routes; expanded redirects from legacy integrations paths.
  * Added public agent-skills discovery manifest.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
Co-authored-by: Alex Hall <alex.hall@supabase.io>
Co-authored-by: Miranda Limonczenko <miranda.limonczenko@supabase.io>
2026-07-15 11:10:51 +00:00
Joshen Lim 66691ad9ce Joshen/fe 3384 prevent ai assistant chat panel from closing after query (#47951)
## Context

2 problems that this PR addresses - but these are in general due to the
mobile UI behaviour
- Sidebars (e.g Help Panel, Advisor Panel, etc) closes whenever there's
a route change
- This is happening because of `StudioMobileSheetNav`'s
`handleOpenChange` interfering with the sidebar visible state
- Am opting to not render `StudioMobileSheetNav` at all unless on mobile
- On mobile, if you're on the Advisor Panel, clicking the "Menu" button
closes the mobile sheet
- Clicking on the Menu button seems to be triggering `MobileSheetNav`'s
`onOpenChange`
- My suspicion is because of state asymmetry between two independent
stores (MobileSheetContext and SidebarManagerState - these 2 are a bit
too complex imo)
- Am opting to skip calling `onOpenChange` in `StudioMobileSheetNav` if
the click target is within the Floating toolbar

## To test
- [x] Desktop: Have the assistant panel open and change routes, panel
should stay open
- [x] Mobile: Open the assistant panel, then switch to the menu, panel
should stay open

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved mobile navigation interactions so the navigation sheet
remains open while toolbar actions are being selected.
* Mobile navigation now displays only on smaller screens, preventing it
from appearing at medium and larger breakpoints.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 17:19:02 +08:00
Riccardo Busetti c9eb33abc7 feat(pipelines): Add new cost estimation dialog (#47915) 2026-07-15 06:20:59 +00:00
claude[bot]andClaude 03e6ef7f84 docs(telemetry): correct @page docs for branch-delete and sql autosave-disable events (#47922)
<!-- ccr-slack-attribution -->
_Requested by **Pam Chia** · [Slack
thread](https://supabase.slack.com/archives/C076KTY11DF/p1783905235047469)_

## What kind of change does this PR introduce?

Docs update (JSDoc comments only in the telemetry catalog — no runtime
code, event names, or property types change).

## What is the current behavior?

In `packages/common/telemetry-constants.ts`:

- **Before:** The catalog only documented branch deletion as happening
from the branches page. `branch_delete_button_clicked` listed a single
`@page` of `/dashboard/project/{ref}/branches`, even though the button
also fires from the merge page and from project Settings > General.
- The `sql_editor_autosave_disable_clicked` event's `@page` read
`/project/{ref}/sql/{id}`, missing the `/dashboard` prefix used by every
sibling SQL-editor event.

## What is the new behavior?

- **After:** `branch_delete_button_clicked` now documents all three
surfaces where the button fires — the branches page, the merge page, and
project Settings > General (`/dashboard/project/{ref}/branches,
/dashboard/project/{ref}/merge or
/dashboard/project/{ref}/settings/general`).
- `sql_editor_autosave_disable_clicked` now uses
`/dashboard/project/{ref}/sql/{id}`, consistent with the other
SQL-editor events.

## Additional context

**How:** Both changes are `@page` JSDoc edits in
`packages/common/telemetry-constants.ts`, touching the JSDoc blocks for
`BranchDeleteButtonClickedEvent` and
`SqlEditorAutosaveDisableClickedEvent`. The multi-page format mirrors
the comma/"or" style already used by other multi-page events in the same
file. The Settings > General call site was added in #47677
(`apps/studio/components/interfaces/Settings/General/DeleteBranchPanel.tsx`);
the merge-page and branches-page call sites are in
`apps/studio/pages/project/[ref]/merge.tsx` and
`apps/studio/pages/project/[ref]/branches/index.tsx`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_012mb6VWEpgrDYhgi7eyRpco

---
_Generated by [Claude
Code](https://claude.ai/code/session_012mb6VWEpgrDYhgi7eyRpco)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-14 21:51:13 +08:00
Jordi EnricandClaude Opus 4.8 4096267623 feat(api-keys): migrate last-used indicator to ClickHouse endpoint (#47458)
## Problem

The "last used" indicator for the legacy `anon` / `service_role` API
keys (Project API keys settings) was disabled because it ran a BigQuery
`edge_logs` query. It is now re-enabled against the ClickHouse-backed
`api_keys.last_used.otel` analytics endpoint.

## Current behavior

- The `anon` / `service_role` "last used" indicator is off (the
BigQuery-backed query was disabled).

## New behavior

- New `useApiKeysLastUsedQuery` hook calls the `api_keys.last_used.otel`
endpoint (timestamp params only, no SQL sent), plus its query key and
the generated platform API type.
- `DisplayApiSettings` reads last-used from this hook instead of posting
BigQuery `edge_logs` SQL. The pure `getLastUsedAPIKeys` shaper is kept
and unit-tested. Still gated by the `showApiKeysLastUsed` flag.
- Removed the disabled secret-keys (`sb_secret_`) BigQuery last-used
path, which has no ClickHouse endpoint to migrate to: drops the dead
`useLastSeen` query, the `APIKeyRow` "Last Used" column, and the unused
`showLastSeen` prop.
- Reworded the delete-confirmation copy to be accurate for both secret
and publishable keys.

## Additional context

- Backed by the platform endpoint in supabase/platform#34892 (merged and
deployed).
- Scope: `anon` / `service_role` legacy keys. Secret/publishable and JWT
signing-key "last used" are follow-ups, pending the endpoint returning
those key types.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Updated API key settings to show “last used” activity for the past 24
hours using a dedicated data source and time window.
  * Added clearer messaging when recent API key activity fails to load.
  * Removed the “Last Used” column from API key management tables.
* **Bug Fixes**
* Improved mapping so “last used” values correctly match the intended
key and role.
* Updated API key deletion confirmation to explain required backend
changes and resulting unauthorized behavior.
* **Tests**
* Added unit tests to validate “last used” computation and edge-case
filtering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 14:35:32 +02:00
Andrew ValleteauandClaude Fable 5 768ea1001b fix(studio): scope table editor introspection CTEs to target table OID (#47894)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix (performance), plus a regression-guard test suite and docs.

## What is the current behavior?

Studio's introspection queries in `@supabase/pg-meta` do `O(catalog)`
work for per-table requests. On databases with very large catalogs
(hundreds of thousands of relations/constraints — real deployments reach
this) they take tens of seconds per dashboard interaction, trip
`statement_timeout`, and create heavy CPU/memory pressure when several
tabs open concurrently. Two instances of the same bug class:

**1. Table Editor query (`getTableEditorSql`)** — fetches metadata for
ONE table by OID, but five catalog scans are unscoped and only filtered
at the top-level join:

- `primary_keys` CTE — scans all of `pg_index` (`where i.indisprimary`)
- `index_cols` CTE — scans all unique indexes
- `relationships` CTE — scans every FK in `pg_constraint` (and is
scanned twice by the two subplans)
- `uniques` subquery (inside `columns`) — scans all single-column unique
constraints
- `check_constraints` subquery (inside `columns`) — scans all
single-column check constraints

The planner cannot push the outer join qual into grouped / `distinct on`
subqueries, so each is computed over the full catalog and thrown away.
`tables-paginated.ts` was previously rewritten to avoid exactly this
pattern; the single-table query never got the same treatment.

**2. Entity definitions (`getTableDefinitionSql` /
`getEntityDefinitionsSql`)** — the vendored `pg_get_tabledef` plpgsql
function scans the entire `information_schema.columns` view once **per
column** (plus `information_schema.tables` once per call) just to decide
whether a name needs double-quoting — a pure string property of a name
it already holds — and its per-index partial-index lookup casts
`relnamespace::regnamespace::text` across every `pg_class` row. On a
12K-table catalog this makes a single entity's DDL cost ~3.7s and a
default 100-entity definitions page ~6 minutes.

## What is the new behavior?

**Fix 1 — scope the Table Editor CTEs to the requested OID** (`id` is
validated non-null and interpolated via `literal()`, same as the
existing `base_table_info` filter):

- `primary_keys` / `index_cols`: `and i.indrelid = <id>`
- `relationships`: `and (c.conrelid = <id> or c.confrelid = <id>)`
- `uniques` / `check_constraints`: `and conrelid = <id>`

Semantics are unchanged: the top-level select already filtered every CTE
to the target table, so rows for other tables were computed and
discarded. The `pg_index`/`pg_constraint` lookups become index scans
returning a handful of rows. One residual scan is structural: PostgreSQL
has no index on `pg_constraint.confrelid`, so the incoming-FK half of
`relationships` is a single filtered seq scan of `pg_constraint` — still
one cheap pass instead of materializing every FK row twice.

**Fix 2 — remove the O(catalog) scans inside `pg_get_tabledef`**: the
information_schema uppercase checks are replaced with direct regex tests
on the name in hand (preserving the original's `quote_ident` behavior
for schemas that need quoting), and the partial-index lookup is scoped
by the already-resolved table OID. Original statements are kept as
comments, matching the vendored file's convention.

**Regression guard** — so this bug class stays out:

- `test/db/stress-catalog.ts` builds a synthetic catalog (default 2,000
tables with PKs, unique + check constraints, FK chains and an FK hub;
`PG_META_STRESS_TABLES` scales it to incident size).
- `test/db/plan-guard.ts` provides `EXPLAIN (ANALYZE, FORMAT
JSON)`-based budget assertions: a query's plan may only seq-scan a
scaling catalog if its budget entry carries a written structural
justification (e.g. no index on `pg_constraint.confrelid`; no index on
`pg_class.relnamespace` for per-schema listings), plus a per-query time
bound (the only guard available for opaque plpgsql internals like
`pg_get_tabledef`).
- `test/sql/studio/catalog-plan-guard.test.ts` applies budgets to the
hot-path studio queries: table editor, constraints, FK listing, entity
types, tables-paginated, columns, indexes, table/entity definitions,
views. Reverting either fix makes the suite fail immediately with the
offending scans listed.
- `test/sql/studio/table-editor.test.ts` (new — none existed) asserts
the Table Editor query's semantics: primary keys, unique indexes, both
FK directions, `is_unique`, check definitions, column comments.
- A new package `README.md` documents the plan-guard budget entry as a
requirement for any new introspection query.

### Validation (synthetic 12,000-table catalog, PostgreSQL 17.6)

- **Output equivalence, fix 1:** for 12 relation types (regular,
composite PK, partitioned parent + partition, view, materialized view,
constraint-free table, FK hub/chain/tail, and a fixture with
enums/domains/generated/identity columns and duplicate check
constraints), the `entity` jsonb from the old and new query is
byte-identical.
- **Output equivalence, fix 2:** byte-identical DDL across 13 fixture
combinations (serial/identity/generated/array columns, case-sensitive
and keyword names, mixed-case schemas, partitions, unlogged +
reloptions, partial/expression indexes, external PK/FK/comments/trigger
variants).
- **Performance, fix 1:** Table Editor query `EXPLAIN ANALYZE` ~1,630ms
→ ~30ms (~50×); the gap grows with catalog size since the old query is
O(catalog) per call.
- **Performance, fix 2:** single entity definition 3,672ms → 63ms; a
100-entity definitions page ~6min → 0.87s. The plan-guard bound for
`getEntityDefinitionsSql` tightens accordingly from 15s/25 entities to
3s/100 entities (330ms measured at default test scale).

Verified locally: `catalog-plan-guard` (12 tests), `table-editor`,
`tables-paginated` (16 tests) pass; `typecheck` clean.

### Rollout

Per review, the new behavior ships **dark** behind the
`pgMetaScopedIntrospection` ConfigCat flag (default off = legacy SQL,
kept as full duplicated templates in pg-meta and verified byte-identical
to the pre-PR queries). Studio reads the flag in the query hooks and
threads it through (flag state is part of the React Query keys). The
rollout is staged in the ConfigCat dashboard via user-email targeting
(like every other ConfigCat flag): target the reporting user's email
first, then a percentage rollout, then 100%. Server-side AI callers of
`getEntityDefinitionsSql` stay on the legacy path. Once fully rolled
out, delete the legacy templates + flag in a cleanup PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Closes: PGMETA-122

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Improved table editor SQL to correctly scope primary keys, indexes,
uniques, checks, and relationships to the selected table.
- Optimized table definition SQL to reduce unnecessary catalog scanning
for uppercase-name detection and partial-index detection.

- **Tests**
- Added SQL generator tests for table editor metadata (keys, indexes,
relationships, comments, and constraints).
- Added catalog query plan guard coverage with a stress catalog and
EXPLAIN-based scoping/performance budgets.

- **Documentation**
- Expanded documentation on catalog query plan safeguards and how to
keep new introspection queries properly scoped.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:16:11 +02:00
Jordi Enric b84aafd1a6 fix(ui-patterns): fix chart y-axis label clipping (#47890)
## Summary
- Chart y-axis tick labels were clipped (e.g. edge function overview
execution time charts) because `chart-line.tsx`/`chart-bar.tsx`
hardcoded a `-40` left margin regardless of the actual
`YAxisProps.width` passed in.
- Margin now scales with the configured axis width.

## Test plan
- [ ] Visually check edge function overview performance/usage charts
render full tick labels (e.g. "195ms" instead of "ms")

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Improved chart layout and alignment across line and bar charts.
- Adjusted Y-axis spacing so labels display more consistently when axes
are shown or hidden.
- Removed unnecessary fixed spacing from Edge Function performance, CPU,
and memory charts.
- Tightened spacing around chart timestamp rows for a more compact
presentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-14 10:05:07 +02:00
Joshen Lim c793352036 Add some keyboard shortcuts for the Assistant (#47872)
## Context

Part of some minor improvements to the AI Assistant - this one's about
adding some keyboard shortcuts

## Changes involved
- Added keyboard shortcut for "New chat"
<img width="212" height="96" alt="image"
src="https://github.com/user-attachments/assets/e9c3bd63-adbc-4b05-8c52-1baed67e365a"
/>
- Also added a small animation for the "How can I assist you?" text for
visual indication when moving between chats that might not have a
conversation yet
- Added keyboard shortcut for "Permission settings"
<img width="236" height="86" alt="image"
src="https://github.com/user-attachments/assets/337da009-5979-4910-9292-73cc4d7f7cce"
/>
- Show keyboard shortcut for "Close Assistant"  
<img width="165" height="88" alt="image"
src="https://github.com/user-attachments/assets/b45a4f5a-8e12-45f1-8fdb-a18c0deedb02"
/>
- Fix `ExpandingTextArea` height calculation logic issue
- If you open and close the Assistant panel a number of times, the
height of the input field isn't consistent, so this fixes that


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Added keyboard shortcuts for starting a new AI Assistant chat and
opening permission settings.
- Header actions now display shortcut hints and support keyboard access.

- **Improvements**
- Enhanced accessibility with labels for chat edit controls (save,
cancel, edit, delete).
  - Chat onboarding now remounts when switching active chats.
  - Improved chat popover alignment.
- Escape now blurs the message input; textarea resizing is more reliable
during content/layout changes.

- **Bug Fixes**
- Updated onboarding loading behavior based on the lints loading state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-14 13:45:38 +08:00
Nik RichersandNik Richers 6418820b0b docs: convert self-hosting overview to ContentListings and restructure the page (#47469)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

This PR converts link sections in the self-hosting overview page to the
`ContentListings` component, puts conceptual guidance before deployment
options, and adds badge support for the Docker card (minor).

Relates to DOCS-1137

## Current behavior

`self-hosting.mdx` uses hand-authored `<GlassPanel>` / `<Link>` JSX for
two sections:
- **Get started**: Docker card with a JSX title containing a `<Badge>`
element (was previously deferred for this reason).
- **Community-driven projects**: Two cards with trivial `<span>`-wrapped
string titles.

Get started and Community cards appear at the top of the page, before
the conceptual overview. The Support and community section uses
hand-authored bullet lists for GitHub, Discord, and Reddit links.

## New behavior

- The self-hosting overview page now uses data-driven `ContentListings`
instead of hand-written cards and bullet lists.
- Conceptual content (how self-hosting differs, your responsibilities,
telemetry) comes first; deployment options and community resources
follow.
- Section intro text lives in listing data rather than inline MDX.
- Brand icons added to all listing cards (Docker, Kubernetes, Traefik,
GitHub, Discord, Reddit).
- Minor: Added support for badges to content listings, such as
"Official" in the Docker tile

Data lives in `self-hosting.data.ts` (5 groups, 8 links) and is
registered in `content-listings/index.ts`.

## Additional context

### Icon usage rights

New brand icons (Kubernetes, Traefik, Reddit) are sourced from [Simple
Icons](https://simpleicons.org) (CC0 1.0). Existing icons (Docker,
GitHub, Discord) reuse assets already in `apps/docs/public/img/icons/`.
Use is non-commercial documentation only — consistent with existing docs
icon usage and trademark fair-use for identifying linked third-party
services.

### To do:

- [ ] Check with @aantti if he's on board with switching the page to
content listings we can lint for and the content restructure to match
other overview pages

## Verification

| Gate | Result |
|------|--------|
| `pnpm vitest run lib/content-listings.test.ts` | ✅ 12/12 passed |
| `pnpm build:guides-markdown` | ✅ 744 files generated |
| `pnpm lint:mdx` (self-hosting.mdx) | ✅ No warnings on changed file |

### Proof: restructured self-hosting page with ContentListings and icons

| [Before (production)](https://supabase.com/docs/guides/self-hosting) |
[After (PR
preview)](https://docs-git-nikrichers-docs-1137-self-hosting-supabase.vercel.app/docs/guides/self-hosting)
|
|---|---|
|
![self-hosting-before](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47469/self-hosting-before-dafdcdcf.png)
|
![self-hosting-after](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47469/self-hosting-after-53d1e059.png)
|

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Updated the self-hosting guide to use dynamic content listings for
“Get started,” community resources, support options, and sharing
experiences.
* Added richer listing cards with optional badges and improved icon
handling.
* Expanded self-hosting resource groups to surface more relevant links
in docs navigation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
2026-07-13 16:35:46 -07:00
Joshen Lim 1d29b4c5b4 Clean up RLS Tester artifacts (#47866)
## Context

As per PR title - we're pausing the development of the RLS Tester
feature preview while we re-evaluate its direction. Have also updated
the GH discussion
[here](https://github.com/orgs/supabase/discussions/45233) RE this! 🙏

Removes the RLS Tester UI + Sandbox functionality

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Removed Features**
* Removed the RLS Tester feature preview, banner, and database policy
testing workflow.
* The related SQL testing, role selection, policy summaries, sandbox
management, and result views are no longer available.
* **Bug Fixes**
* Improved accessibility on the database policies page by adding a label
to the clear-filter button.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 17:01:05 +08:00
Riccardo BusettiandAna 8f82861627 feat(replication): Add new form for early access of replication destination (#47046)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added pre-release pages for Supabase Pipelines’ new destinations,
including early-access signup, thank-you confirmation, and related
resources.
  * Added destination options for ClickHouse, Snowflake, and DuckLake.
* **Bug Fixes**
  * Improved form validation for grouped required checkboxes.
  * Added clearer checkbox labels and descriptions.
* Forms now explain which required option groups still need a selection.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ana <30495040+ana1337x@users.noreply.github.com>
2026-07-11 00:32:14 +02:00