Stack 3/4 · previous: #50687 · next: #50689
## Problem
`DataTableInfinite` could only open one row at a time. Multi-select
meant clicking a separate checkbox column, with no support for ranges or
modifier keys.
## Solution
This PR only adds shared primitives. Behavior stays the same until a
consumer passes `onSelectRow` (wired up in the next PR).
- `selectTableRow` (`rowSelection.utils.ts`): a pure reducer for plain,
Cmd/Ctrl-toggle, Shift-range, and additive-range selection over the
current display order, with a fixed anchor.
- `useTableRowSelection`: holds the selection state and resets it when
its `scope` (project/filters) changes.
- `DataTableProvider` gets an optional `onSelectRow`. When it's set,
`DataTableInfinite` rows use it and reflect `row.getIsSelected()`. Rows
also get `aria-selected`, Space activates them like Enter, and
shift-click no longer selects text.
## Review instructions
1. Read `rowSelection.utils.test.ts`: it covers the selection rules.
2. Open Unified Logs. Row clicks should behave the same as on master.
## Checklist
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added richer data-table row selection, including multi-select, range
selection, toggling, and keyboard support.
- Added visual and accessibility feedback for selected rows, including
pointer cursor and `aria-selected`.
- Preserved selections across paging and live updates while resetting
them when filters or projects change.
- Added support for external row-selection callbacks.
- **Tests**
- Added comprehensive coverage for selection behavior and state
persistence.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
<img width="1086" height="810" alt="image"
src="https://github.com/user-attachments/assets/8a9f0c64-145e-4475-a3df-67bd815e2200"
/>
Stack 2/4 · previous: #50686 · next: #50688
## Problem
The detail panel only showed an Overview tab for log types that have an
inspection query. Every other type opened straight to Raw JSON. The
panel also had no header saying which log was open.
## Solution
- Adds `LogDetail`, which owns the inspection query, loading and error
states, and the Raw JSON view. Errors now use `AlertError`.
- Adds `LogOverview`, which maps each log type to its overview renderer.
Types without one fall back to the new `LogFields`, a generic tree of
expandable key/value rows built on `LogFieldRow`.
- `ServiceFlowPanel` now shows a header (level dot + event message)
above Overview / Raw JSON tabs for every log.
- Moves `getLogDataForMetadataVisibility` to `ServiceFlowPanel.utils.ts`
and adds `LogLevelDot`.
## Review instructions
1. Select a Realtime (or any other non-inspected) log. The Overview tab
should list its fields, with nested objects that expand.
2. Select a Postgres log. The overview should look as before, and Raw
JSON should still show the enriched log.
3. Switch between logs and confirm the tabs reset their scroll.
## Checklist
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added structured log overviews for Postgres, PostgREST, Auth, Storage,
and Edge Functions, with a Raw JSON view for log details.
- Added expandable log fields with filtering and copy actions, plus
visual indicators for log severity.
- **Bug Fixes**
- Improved display of scalar, nested, date, and empty log values.
- **Privacy**
- Raw log data respects metadata visibility settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
<img width="1353" height="1046" alt="image"
src="https://github.com/user-attachments/assets/22c69de8-59ff-4318-9044-c222b01b6154"
/>
Stack 1/4 · next: #50687
## Problem
In the Unified Logs detail panel, each field row had a small kebab
button. Fields that couldn't be filtered fell back to a separate copy
button, so the actions weren't consistent. Filter labels also repeated
the column id ("Add as filter for method").
## Solution
- Adds `LogFieldRow`: the whole key/value row opens the actions menu on
click or Enter. Rows you can filter show filter + copy, and every other
row shows copy only.
- `DataTableSheetRowAction` always renders the dropdown now. `table` is
optional, copy is always available, labels read "Add filter", and the
menu aligns to the row.
- `DetailRow` is rebuilt on `LogFieldRow`. The section styling is
refreshed: bordered collapsibles, no zebra striping, and
`heading-default` section titles. The `topDivider` prop is removed.
## Review instructions
1. Open Unified Logs and select a Postgres or PostgREST log.
2. Click a filterable row (such as method or status). You should see
"Add filter" and "Copy …" in one menu.
3. Tab to a row that can't be filtered and press Enter. You should see a
copy-only menu.
## Checklist
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added consistent copy and filter actions to log detail rows.
* Added keyboard-accessible row actions, including “Add filter” for
filterable values.
* **UI Improvements**
* Updated log detail sections with clearer borders, headings, hover
states, spacing, and typography.
* Simplified detail row presentation and improved value wrapping and
readability.
* **Bug Fixes**
* Improved handling of empty and filterable log values in detail rows.
* **Tests**
* Added coverage for copying values and applying filters from detail
rows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## Problem
Studio copy ties disk IO burst behavior to compute size thresholds and
says the IO budget "resets".
Burst eligibility isn't a single size cutoff
EBS burst credits refill continuously while disk usage runs below
baseline
Docs already use this framing (#50016)
Fixes PROD-665
## Solution
Three copy changes:
- `UnavailableChartBlock.tsx`: the burst balance chart placeholder no
longer names a size. It now describes sustained IO with no burst credit
pool
- `database-charts.ts`: the Disk IO Burst Balance tooltip describes the
EBS burst credit pool without referencing instance size
- `ResourceExhaustionWarningBanner.constants.ts`: the warning and
critical banners say the budget refills whenever disk usage runs below
baseline, instead of "resets"
## Review instructions
1. Read the diff. Copy changes only.
2. Optional: on a project with burstable disk IO, open Reports >
Database and hover the Disk IO Burst Balance chart title to see the new
tooltip.
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which references
[WORD_LIST](https://github.com/supabase/supabase/blob/master/apps/docs/WORD_LIST.md)
and the docs
[CONTRIBUTING](https://github.com/supabase/supabase/blob/master/apps/docs/CONTRIBUTING.md)
guide
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Documentation
* Updated disk I/O chart messaging to explain that some compute types
sustain disk throughput without a burst credit pool to track.
* Clarified that disk I/O burst budgets refill when demand is at or
below baseline, and that throughput remains at baseline until the budget
refills.
* Updated the burst-balance chart tooltip to describe how compute uses
the EBS burst credit pool.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The schema visualizer bound `schema-visualizer.find-table` (`O` then
`T`) twice — once via `useShortcut` and again through the `<Shortcut>`
wrapper around `FindTableSelector`, which registers the hotkey itself —
so every mount logged a conflict warning and fired both handlers.
Removed the redundant standalone hook; the wrapper renders under the
same `shortcutsEnabled` gate, so behavior is unchanged.
Fixes FE-4454
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Behavior Changes**
* The schema visualizer no longer registers the standalone keyboard
shortcut handler for Find Table. Find Table remains available from the
toolbar.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Context
Allows users to "reset" the value for connection pool size in pooler
configuration under [database
settings](http://supabase.com/dashboard/project/_/database/settings)
<img width="500" alt="image"
src="https://github.com/user-attachments/assets/4eb98088-1898-423c-8ef6-655fd0573601"
/>
Refer to the [Linear
ticket](https://linear.app/supabase/issue/FE-4425/support-setting-null-for-pool-size-in-pooler-config)
for more details about why this change is needed - its a bit of an
explanation 😅🙏
## To test
- [ ] Verify that you can save a pool size, and that the GET
`/config/pgbouncer` network request returns `default_pool_size` property
in its response
- [ ] Verify that you can save while leaving the pool size input field
empty, and that the GET `/config/pgbouncer` network request thereafter
doesn't return `default_pool_size` in its response
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Preserved the intended database connection pool setting when no
default pool size is specified, rather than automatically applying a
compute-size-based value.
* Explicitly entered pool sizes continue to be saved unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Clarifies on the database product page that a Supabase project can be
used as a standalone Postgres database, and mirrors the change in the
page's markdown version (`/database.md`).
Ref: GROWTH-1191
## Changes
- **Hero and page metadata**: adds "Use it on its own, or with the rest
of the Supabase platform."
- **Features section**: intro reframed around the database. The "Just
Postgres" card heading adds "standalone".
- **`content/md/database.md`**: same sentence in the tagline. New short
"Use it as a standalone database" section covering connecting, pooling,
pricing, and Free plan pausing. Client libraries marked optional. Pooler
naming updated to Supavisor. Links added for the connection guide and
`pricing.md`.
## Notes
- Pricing figures in the markdown mirror `packages/shared-data/plans.ts`
and are static here.
- The pausing statement matches
`docs/guides/platform/free-project-pausing`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Clarified that Supabase projects include dedicated, standalone
Postgres databases.
- Explained that databases can be used independently or alongside the
Supabase platform.
- Added guidance on connections, pooling, pricing, pausing, and optional
client libraries.
- Identified Supavisor as the pooling service and added relevant
connection and pricing links.
- **Content**
- Updated database page messaging to highlight built-in security,
realtime subscriptions, auto-generated APIs, portability, and no vendor
lock-in.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Adds the Polymet case study (`apps/www/_customers/polymet.mdx`): how
Polymet, an AI product designer, runs a real backend for tens of
thousands of user projects a month on Supabase with a three-person team
and no dedicated backend hire.
- Adds light/dark logo assets provided by Polymet.
- Content is the final draft reconciled with the customer's (Yus Hilmi,
Founder/CEO) approved review edits.
Ready for design/eng review. Tracked on
[MARKET-2264](https://linear.app/supabase/issue/MARKET-2264/case-study-polymet).
## Test plan
- [ ] Case study renders correctly at `/customers/polymet`
- [ ] Logo displays correctly in both light and dark mode
- [ ] Frontmatter fields (industry, region, company_size,
supabase_products) render correctly in any related listing/filter UI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added a customer story about how Polymet uses Supabase for its users’
projects, including its experience and future plans.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## What
The custom SMTP password field showed a "Reveal" and "Copy" button next
to text saying "this password cannot be viewed once saved" —
contradictory, since those buttons implied there was something to reveal
or copy. In reality the backend never returns the saved password, so the
field was always blank and those buttons acted on an empty string.
## Why
Reported in FE-3765: users found it confusing whether saving other
fields would blank out their password, and the Reveal/Copy buttons
appeared broken.
## Fix
- Removed the non-functional Reveal/Copy buttons from the password
input.
- When a password is already saved, the field now shows a
`••••••••••••••••` placeholder and copy reading "Stored password is
hidden. Enter a new password to replace it." — matching the existing
`STORED_SECRET_PLACEHOLDER` pattern already used in the Replication
destination forms (BigQuery, ClickHouse, Snowflake, etc).
- No behavior change: leaving the field blank on save still preserves
the existing password (unchanged logic).
## Testing
- Manually verified in the running app.
- Added a component test (`SmtpForm.test.tsx`) covering both the
"password already saved" and "fresh setup" states.
- `tsc --noEmit`, `eslint`, and `prettier --check` all pass with no new
errors/warnings.
Fixes
[FE-3765](https://linear.app/supabase/issue/FE-3765/custom-smtp-password-field-ux-issues)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Updates**
* Configured SMTP passwords are masked, with a notice that entering a
new password will replace the stored one.
* For new SMTP setups, the password field prompts for the SMTP server
password and does not show the stored-password notice.
* The SMTP password field no longer provides controls to reveal or copy
the password.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Project cards and the project table showed the raw cloud provider
(`AWS`, `AWS_K8S`) alongside the region, which is an internal
implementation detail. Both now show the region only — matching the
table's existing "Region" column header.
Fixes FE-4441
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Updates**
* Project cards now display the project’s region directly.
* Project tables show only the region in the region column, with “N/A”
when unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Assistant chats from High Compliance projects now flow to Braintrust
like any other project. The constraint that required suppressing them no
longer applies, see AI-1241 for the details.
`isTracingAllowed` now takes only the project region to maintain EU
exclusion. Traces also carry an `isHighComplianceProject` metadata
field, so the project's status at the time of the trace is recorded
rather than looked up later against a setting customers can toggle.
To verify, see [this sample
trace](https://www.braintrust.dev/app/supabase.io/p/Assistant/logs?r=afabbdcc-aa89-446e-aa52-78aaa90d44a4&v=Production&s=afabbdcc-aa89-446e-aa52-78aaa90d44a4&tvt=trace)
from a High Compliance project on staging which indicates that tracing
is now enabled for these projects and that it carries metadata showing
the high compliance status.
| High Compliance project setting | `isHighComplianceProject` metadata |
|--------|--------|
| <img width="1554" height="454" alt="CleanShot 2026-09-22 at 5 14 58
PM@2x"
src="https://github.com/user-attachments/assets/23901c6e-0d79-44e8-a6dd-43cdedba1799"
/> | <img width="1674" height="990" alt="CleanShot 2026-09-22 at 5 17 40
PM@2x"
src="https://github.com/user-attachments/assets/fb2fba55-bcc1-4136-a432-b33a5c7f9ca2"
/> |
Closes AI-1241
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Changes**
* AI project compliance information is now represented by a unified
high-compliance project status.
* AI response tracing is now determined by project region: tracing
remains disabled for EU and unknown regions, while known non-EU regions
are eligible.
* AI feedback and SQL generation now use the updated compliance and
regional handling.
* **Tests**
* Updated coverage to reflect the revised compliance and tracing
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The API prevents users from deleting their last MFA when they also have
recovery codes. However the UI doesn't and they may see an error instead
of being guided.
## Solution
Delete the recovery codes first.
<img width="1080" height="850" alt="image"
src="https://github.com/user-attachments/assets/67d999e7-06ff-4c0a-a2cc-11b864cb32f4"
/>
## Review instructions
Provide a clear numbered procedure that the PR reviewer can walk
through.
1. With an account that have only one MFA and recovery codes generated
2. Delete the MFA => You should see the dialog as in above screenshot.
Check the presence of _Your recovery codes will be deleted too_
After deletion, you shouldn't see the Recovery codes section anymore.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Improved multi-factor authentication management when recovery codes
are available.
- Users are warned that recovery codes will be deleted before removing
their last authentication factor.
- Removing the final authentication factor handles recovery-code
deletion first.
- Cancelling deletion leaves the factor and recovery codes unchanged.
- Recovery-code handling applies only when enabled and relevant to
last-factor removal.
- Recovery-code management is available in all environments.
- Delete actions are disabled while recovery-code status is loading, and
an error message appears if recovery codes fail to load.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Studio expected aliased fields from the last-used API-key endpoint, but
the live endpoint returns OTEL attribute names. This kept legacy API-key
activity unavailable and prevented Studio from showing activity for new
JWT signing keys. Tracks FE-2462 and FE-4315.
## Fix
Normalize the endpoint response at the data boundary, keep the
`showApiKeysLastUsed` feature flag, and show activity from the past 24
hours for new JWT signing keys. Legacy HS256 signing keys remain blank
because the analytics response does not provide a stable signing-key
record ID for them. The request remains hosted-only, permission-gated,
and non-blocking, and the existing last-rotated column remains intact.
## How to test
- Make a request with a legacy anon or service-role API key, then open
Project Settings > API Keys and verify its last request appears.
- Make an Auth request signed by a new JWT signing key, then open JWT
Keys and verify the matching key shows a Last used timestamp.
- Verify a new key without activity shows No requests in the past 24
hours.
- Verify the legacy HS256 signing-key row leaves Last used blank.
- Expected result: legacy API keys and new JWT signing keys display
activity from the shared endpoint without changing self-hosted Studio.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a **Last used** column for JWT signing keys on supported
platforms.
* Displays usage timestamps, loading and error states, or when a key has
had no requests in the past 24 hours.
* Usage tracking now includes both API keys and JWT signing keys.
* **Bug Fixes**
* Improved handling of usage records for legacy and current keys.
* Usage details appear only on supported platforms and for users with
the required permissions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Summary
Fixes
[FE-3987](https://linear.app/supabase/issue/FE-3987/contact-support-pre-fills-the-wrong-supabase-project-id):
the "Contact support" button shown in the Table Editor's inline error
banner (e.g. "Failed to retrieve rows from table") didn't pass the
current project or organization to the support form. This caused the
support form to fall back to the user's first organization/project
instead of the one actually affected — especially noticeable when the
Management API request used to resolve the org also fails.
## Test plan
- [ ] Open a project in Studio, go to **Table Editor**, open a table.
- [ ] Trigger a failing table query — either block the `rest/v1/<table>`
request in DevTools, or apply a filter with a mismatched type (e.g. `id
= 'abc'` on an int column).
- [ ] On the inline red "Failed to retrieve rows from table" banner,
click **Contact support**.
- [ ] Confirm the support form pre-fills the **correct organization and
project** — the one the failing table actually belongs to.
- [ ] Repeat with a project belonging to an organization that is *not*
first in your org list, to confirm it's not coincidentally correct.
- [ ] Repeat while simulating a Management API failure (e.g. block
`api.supabase.com`/`*.supabase.co/platform/*`) to confirm the org still
resolves correctly via the `orgSlug` fallback instead of silently
defaulting to your first org.
- [ ] Sanity check other "Contact support" entry points (header Feedback
dropdown, Help sidebar) are unaffected — they use a separate,
already-correct code path.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved error handling when project details cannot be loaded,
preserving relevant project and organization context.
* Improved fallback behavior for identifying the correct organization
when project information is unavailable or unresolved.
* Support requests opened from error messages now include applicable
project and organization information.
* Error messages now consistently display available additional actions
alongside contact support options.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Problem
PR #50638 migrates API Gateway and Data API reports to OTEL, but the
shared Auth and Realtime metrics still select legacy BigQuery SQL and
the `logs.all` endpoint.
## Fix
Route all active hosted shared API reports through the existing OTEL
builders after feature flags load. Remove unused report variants and
their source-selection abstraction while preserving the legacy BigQuery
path for self-hosted Studio.
This PR is stacked on #50638.
## How to test
- Open the Auth observability report and confirm its seven shared metric
requests use `logs.all.otel` with a `/auth` request-path filter.
- Open the Realtime observability report and confirm its seven shared
metric requests use `logs.all.otel` with a `/realtime` request-path
filter.
- Open the Data API report and confirm its existing OTEL behavior
remains unchanged with a `/rest` request-path filter.
- Expected result: hosted reports wait for ConfigCat before querying,
while self-hosted Studio continues using the legacy BigQuery path.
- Run `./apps/studio/node_modules/.bin/vitest --run
apps/studio/components/interfaces/Reports/Reports.constants.otel.test.ts
--config apps/studio/vitest.config.ts`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Changes**
- Shared API reports now support filtering by Auth, Realtime, and
PostgREST traffic.
- Filters for Storage, GraphQL, Functions, and other previously
supported traffic types are no longer available.
- Report queries now consistently use edge log data, improving
consistency across request totals, routes, errors, response times, and
network traffic metrics.
- OpenTelemetry-backed reporting is now enabled consistently across
supported report types where available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Mike Podobnik is missing from the team list in
`apps/docs/public/humans.txt`.
## Solution
Add Mike Podobnik between Michelle Jubrey and Miranda Limonczenko,
preserving alphabetical placement and the existing plain-text format.
## Review instructions
1. Confirm the diff adds only `Mike Podobnik`.
2. Verify the name appears between Michelle Jubrey and Miranda
Limonczenko.
## Validation
- `git diff --check` passes.
- Verified a single insertion, no deletions, and correct alphabetical
placement between the adjacent entries.
- Build and application tests skipped for this static text-only
addition. The repository's Prettier check does not include `.txt` files.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md).
- Docs topic authoring checklist is not applicable: this change only
adds a name to a plain-text team list.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added Mike Podobnik to the team listing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## Problem
The Management API now has `/v2/projects/{ref}/notebooks`, gated by the
new `project_notebooks_read` / `project_notebooks_write` FGA
permissions. Studio pins `@supabase/shared-types` 0.1.95, which predates
them, so the scoped access token form can't grant them. Tokens created
with every permission selected still get `403 forbidden` on the notebook
endpoints.
## Solution
- Bump `@supabase/shared-types` to 0.1.96 (Studio and shared-data),
which publishes the notebook permissions.
- Add a **Notebooks** entry to the permission catalog (Project category,
next to SQL Snippets).
- Add minimum roles to `FGA_SCOPE_MINIMUM_ROLE`: read is `readonly`,
write is `developer`, matching the OpenFGA model.
The docs permission tables don't change yet. They're built from the
docs' checked-in v2 spec, which doesn't include the notebook endpoints,
so the row appears on the next spec sync.
## Review instructions
1. In the preview, go to **Account → Access Tokens** and create a scoped
token for a project. Check that **Notebooks** is listed under Project,
and set it to Read-write.
2. List notebooks with the new token:
```bash
curl -s -H "Authorization: Bearer $TOKEN"
"https://api.supabase.com/v2/projects/$REF/notebooks"
```
It should return `200` with `{ "links": ..., "data": [...] }`, not
`403`.
3. Optional: create a token with Notebooks set to None, repeat step 2,
and check it returns `403`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added project-level notebook permissions to access tokens.
- Access tokens can now grant read-only or developer-level access for
managing shared project notebooks.
- Project notebook permissions are displayed in the token creation
interface and supporting documentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## 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?
Update humans text - new joiner
Bug fix, feature, docs update, ...
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Feel free to include screenshots if it includes visual changes.
## Additional context
Add any other context or screenshots.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Added Carson Adam to the team member listing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- ccr-slack-attribution -->
_Requested by **Saxon Fletcher** · [Slack
thread](https://supabase.slack.com/archives/C051L8U2EJF/p1789995309253479?thread_ts=1789995309.253479&cid=C051L8U2EJF)_
Resolves AI-1246
## Problem
**Before:** The Assistant's `list_policies` tool fails in about 70% of
traces. It only "succeeds" when the org has AI opt-in disabled, because
then it returns the privacy stub and never makes a request. When opt-in
is enabled, it runs the pg-meta query server-side with no
`Authorization` header, so the request is unauthenticated and fails. The
Assistant then falls back to `execute_sql`.
**After:** `list_policies` sends the caller's `Authorization` header,
the same way `execute_sql` in `studio-tools.ts` already does, so it
returns the project's RLS policies.
## Solution
`getTools` already receives `authorization` but didn't pass it to
`getSchemaTools`. This PR passes it through. `list_policies` builds `{
Authorization }` from it, and `getDatabasePolicies` gets an optional
`headersInit` argument that it forwards to `executeSql`, the same
pattern `getDatabaseFunctions` uses. Existing client-side callers of
`getDatabasePolicies` don't change.
Files: `lib/ai/tools/index.ts`, `lib/ai/tools/schema-tools.ts`,
`data/database-policies/database-policies-query.ts`, plus tests in
`lib/ai/tools/schema-tools.test.ts` (new) and
`lib/ai/tools/index.test.ts`.
## Review instructions
1. Read `schema-tools.ts` and compare it with the `authHeaders` handling
in `studio-tools.ts` (`execute_sql`).
2. On the preview, use an org with AI opt-in set to at least "schema"
and ask the Assistant to list the RLS policies on `public`.
`list_policies` should return the policies without falling back to
`execute_sql`.
Local gates (all passed):
- `pnpm typecheck` in `apps/studio` (next typegen + `tsc --noEmit`)
- `npx eslint` on touched files: 0 errors. The 2 warnings are on lines
this PR doesn't change.
- `npx vitest run lib/ai/tools/schema-tools.test.ts
lib/ai/tools/index.test.ts lib/ai/tool-filter.test.ts`: 24/24 passed. I
also ran the new header test against the old `schema-tools.ts` and it
failed, as expected.
- `SORT_IMPORTS=false npx prettier --config prettier.config.mjs --check`
on touched files
Follow-up, not in this PR: `getRlsKnowledge` in `fallback-tools.ts`
(self-hosted path) also calls `getDatabasePolicies` without headers,
even though a `headers` object is already in scope there.
## AI disclosure
Claude Code (agent) wrote this PR from the Slack request. @SaxonF (Saxon
Fletcher) is the accountable human owner. A human needs to review it
before merge.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill (N/A, no docs changes)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_0171Mk7SiKYLDDoAQvbDYfeK
---
_Generated by [Claude
Code](https://claude.ai/code/session_0171Mk7SiKYLDDoAQvbDYfeK)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Somewhat urgent update to documentation based on new AWS behavior.
Will include additional details when we properly support custom DNS for
privatelink
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated the PrivateLink endpoint creation guide’s Option A steps and
numbering. The DNS record note now stands on its own, without
referencing a removed step.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
UI polish / design system: refreshed button styles, related token
tweaks, and a shared floating-button plate.
Resolves DEPR-652.
## What is the current behavior?
Default, primary, and secondary buttons use older fills, borders, and
hover treatments. Primary still leans on brand scale utilities. Default
fills don’t always read as raised chrome across surfaces, and floating
copy / expand / scroll controls can let busy content show through
translucent fills. Call sites hand-roll `rounded-* bg-background`
wrappers for that.
## What is the new behavior?
Refreshes primary, default, and secondary buttons with medium-weight
labels, subtle shadows and inset edges, and smoother transitions.
Light-mode default buttons use a raised fill with an accent hover state,
primary text is brighter, and inline keyboard shortcuts inherit the
button’s colour.
Adds `FloatingPlate`: an opaque `bg-popover` shell for floating default
buttons (and small clusters). Migrates Studio, Docs-related patterns,
www, and `ui-patterns` floaters onto it so busy content no longer shows
through translucent fills. Positioning, z-index, and hover/focus reveal
stay on the plate’s `className`. Use `rounded="full"` for pills.
Also:
- Moves primary onto semantic `--primary` / `--primary-hover` (with a
light-theme override) instead of brand utility fills
- Tokenises button shadows as `--button-shadow-drop` /
`--button-shadow-raised` / `--button-shadow-default` on the Button base
- Aligns hover direction: darken on light mode, lighten on dark mode for
both default and primary
- Default fill stays opaque `bg-card` in light (occlusion) and
translucent `bg-muted` in dark (adapts to the local surface)
- Documents fills and `FloatingPlate` on the design-system Button page
(with a live example)
- Scales shared radius tokens in Studio and www; medium+ Button sizes
use a proportionally softer radius
- Fixes www nav CTA centering (`lg:inline-flex` instead of `lg:block`)
- Query detail Expand/Collapse wires `aria-expanded` / `aria-controls`
| Before | After |
| --- | --- |
| <img width="1074" height="438" alt="CleanShot 2026-09-18 at 15 52
51@2x"
src="https://github.com/user-attachments/assets/ef43da21-b053-4b7e-9ac4-ab8b428228ab"
/> | <img width="1090" height="464" alt="CleanShot 2026-09-18 at 15 50
59@2x"
src="https://github.com/user-attachments/assets/2ddc55fc-4c8d-499c-a280-f3db3d99023c"
/> |
| <img width="1082" height="446" alt="CleanShot 2026-09-18 at 15 52
35@2x"
src="https://github.com/user-attachments/assets/3dd5452d-325a-4e4a-a79d-26c6c6950a31"
/> | <img width="1078" height="446" alt="CleanShot 2026-09-18 at 15 51
13@2x"
src="https://github.com/user-attachments/assets/93666385-3e6e-42e0-9891-9cd6bb935b67"
/> |
## To test
### Design system
- [Button
page](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button):
default / primary in light and dark; hover should darken on light,
lighten on dark
- Same page: [Floating over
content](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button#floating-over-content)
/ [Floating
plate](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button#floating-plate)
example; Copy over SQL should stay opaque
- Spot-check hover on a code preview Copy control
### Docs
[Docs deploy
preview](https://docs-git-chore-button-styles-supabase.vercel.app/docs):
- [Docs
homepage](https://docs-git-chore-button-styles-supabase.vercel.app/docs):
top-right **Sign up** / **Dashboard** primary; menu icon beside it
(default icon button)
- Shrink below `lg` and open the hamburger drawer: bottom **Sign in**
(default) + **Start your project** (primary) medium block buttons
- Tab once for **Skip to content** (FloatingPlate)
- [MCP
guide](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/ai-tools/mcp):
project picker
- [Apple
login](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/auth/social-login/auth-apple):
**Generate Secret Key** button in the Apple Secret Generator
- Optional opacity check: any guide code block Copy control (e.g. at the
bottom of [Import data into
Supabase](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/database/import-data))
### Studio
[Studio deploy
preview](https://studio-staging-git-chore-button-styles-supabase.vercel.app/):
- **Observability → Query Performance**: open a query detail →
Expand/Collapse pill + SQL Copy chip (dark: no bleed-through)
- **Observability → Query Insights**: select a query → Clear query pill
- **Table Editor → any table → Definition** → floating **Open in SQL
Editor**
- **Connect → Framework → Add files**: Copy on the code tabs
(FloatingPlate; light hover follow-up is DEPR-694)
- Tab once for **Skip to content**
### WWW
- [www deploy
preview](https://zone-www-dot-com-git-chore-button-styles-supabase.vercel.app/):
nav Sign in / Start your project vertical centering; hero medium CTAs
radius
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
<!-- ccr-slack-attribution -->
_Requested by **Saxon Fletcher** · [Slack
thread](https://supabase.slack.com/archives/C051L8U2EJF/p1790104861710199?thread_ts=1790104861.710199&cid=C051L8U2EJF)_
## Problem
**Before:** The Assistant's base model is `gpt-5.6-luna` at medium
reasoning effort.
**After:** The base model is `gpt-6-luna`, its direct successor, still
at medium effort. It costs half as much: $0.10/$0.50 per MTok against
$0.20/$1.20.
Resolves
[AI-1245](https://linear.app/supabase/issue/AI-1245/move-the-assistants-base-model-to-gpt-6-luna).
## Solution
This swaps `gpt-5.6-luna` for `gpt-6-luna` in
`apps/studio/lib/ai/model.utils.ts`: the model ID union, the
reasoning-support map, `ASSISTANT_MODELS`,
`DEFAULT_ASSISTANT_BASE_MODEL_ID`, and the OpenAI provider registry. The
old ID is removed, not kept next to the new one. A stored selection of
`gpt-5.6-luna` is no longer a known ID, so the client and `generate-v4`
both fall back to the new default. The eval cost table (AI-1242) and
eval experiments (AI-1243) are out of scope.
Source for the model ID and supported efforts (none/low/medium
default/high/xhigh/max): [OpenAI model docs: GPT-6
Luna](https://developers.openai.com/api/docs/models/gpt-6-luna).
`@ai-sdk/openai@4.0.41` types model IDs as a union plus `string & {}`,
so no SDK bump is needed.
## Review instructions
1. Check the diff in `model.utils.ts`. Say so if you'd rather keep
`gpt-5.6-luna` selectable as a fallback.
2. AI-1245 asks for the Assistant evals before shipping. Add the
`run-evals` label to run `braintrust-evals.yml` on this PR, or run `pnpm
--filter studio evals:run` locally. They have not been run yet because
they need OpenAI/Braintrust credentials.
3. Already run: studio `typecheck`, eslint + prettier on the changed
files, vitest for `lib/ai`, `pages/api/ai` and `state/ai-assistant` (264
passed), and `evals:preflight`.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] No docs topics changed
**AI disclosure:** Claude Code wrote this PR from start to finish. Saxon
Fletcher (@SaxonF) is the accountable human and must review it before
merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01W21zLTfzde6FFPyYGbGC6K
---
_Generated by [Claude
Code](https://claude.ai/code/session_01W21zLTfzde6FFPyYGbGC6K)_
Co-authored-by: Claude <noreply@anthropic.com>
## What kind of change does this PR introduce?
Feature and docs update.
## What is the current behavior?
The Dashboard lists Pipelines destinations under Database > Replication.
Read replicas have moved to Infrastructure, but the temporary notices
remain on the destinations page and new destination sheet.
Closes PIPE-1021.
## What is the new behavior?
The canonical Dashboard routes are Database > Pipelines, while legacy
Replication list and detail URLs permanently redirect to the equivalent
Pipelines routes. Navigation, command palette, shortcuts, pipeline
links, docs, and current marketing copy use Pipelines. Read-replica
notices and their obsolete dismissal state are removed.
| Before | After |
| --- | --- |
| <img width="1024" height="759" alt="Replication Database Agua Basket
Supabase"
src="https://github.com/user-attachments/assets/53f9f565-1ed1-43e9-a7d9-b66b2a47e948"
/> | <img width="1024" height="759" alt="2540"
src="https://github.com/user-attachments/assets/14ab2d61-d01c-483f-9d4f-0ac286dae159"
/> |
The Management API, pipeline behaviour, replication logs, and Postgres
replication terminology remain unchanged.
## To test
- Open `/project/<ref>/database/pipelines` and confirm the Database
navigation, page header, and pipeline breadcrumb say Pipelines.
- Open
`/project/<ref>/database/replication?source=bookmark#destinations` and a
legacy pipeline detail URL. Confirm each redirects to the matching
Pipelines URL while preserving parameters and fragments.
- From the Pipelines page, open Add destination. Confirm no read-replica
migration notice appears.
- Open the Pipelines guide and confirm its Dashboard steps lead to
Database > Pipelines.
## Before merge
- [ ] Get changelog entry reviewed
https://github.com/supabase/changelog/pull/262 and prepare to merge
simultaneously
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added dedicated **Database > Pipelines** pages for pipeline lists and
details.
- Added permanent redirects from legacy Replication URLs to their
corresponding Pipelines pages.
- Read replica management links now open **Settings > Infrastructure**.
- **Documentation**
- Updated Pipelines setup, monitoring, troubleshooting, and usage
guidance to reference the current dashboard locations.
- Updated Realtime guidance to use **Database > Publications**.
- **Updates**
- Renamed dashboard navigation, breadcrumbs, commands, and keyboard
shortcuts from **Replication** to **Pipelines**.
- Removed the “Read replicas have moved” notification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Closes
[DOCS-1289](https://linear.app/supabase/issue/DOCS-1289/get-the-linter-to-fix-what-it-flags-or-retirereplace-the-linter)
Stacked on #50600, which points contributors at the authoring skills.
Merge that one first.
## Problem
Contributors experienced friction with the linter. They felt nickle and
dimed for tiny nits and felt detracted from the work itself. PRs would
become noisy with tiny one-word suggestions.
Additionally, our homegrown linter is not very intelligent, causing
frequent overrides.
## Solution
This removes the linter entirely in favor of directing contributors to
use SKILLS instead.
The removal entails...
- **CI.** Delete the three `docs_lint` workflows: the PR check, the
external-PR comment companion, and the nightly `--fix` bot. Drop the
stale `zizmor.yml` ignore entry for the deleted workflow.
- **Tooling.** Delete `supa-mdx-lint.config.toml` and the 14 rule files.
Drop the `lint:mdx` script and the `@supabase/supa-mdx-lint` dependency
from docs, learn, and ui-library, and regenerate the lockfile.
- **Content.** Remove the 181 directives. A separate commit carries
Prettier's reformatting of the tables and blank lines those comments had
suppressed, so the deletion commit stays readable. No prose changes.
- **Style guide.** The word list states each rule directly instead of
describing what the linter flagged. Every term survives, including the
phrase groups that mirrored `Rule004ExcludeWords`.
- **Skills.** `write-the-docs`, `edit-the-docs`, and `review-the-docs`
drop `pnpm lint:mdx` from their self-review commands and check the word
list directly. `ask-the-docs`'s CI reference drops both workflows.
## Manual testing
1. Run `git grep -i supa-mdx-lint -- . ':!pnpm-lock.yaml'`. No matches.
2. Run `pnpm install --frozen-lockfile --lockfile-only`. It passes, so
the lockfile matches the three trimmed manifests.
3. Run `git diff master...HEAD --name-only --diff-filter=ACMR | grep -E
'\.(md|mdx)$' | xargs npx prettier --config prettier.config.mjs
--check`. All changed markdown passes.
4. Open the [reformatted filter
table](https://docs-git-docs-retire-mdx-linter-supabase.vercel.app/docs/guides/observability/logs#filter-events)
on the preview and compare it with
[production](https://supabase.com/docs/guides/observability/logs#filter-events).
The table renders the same.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Documentation guidance now uses manual prose and terminology review
with the shared word list.
* Clarified storage configuration and common Realtime channel mistakes.
* Improved table formatting, text wrapping, and selected reference
links.
* Updated documentation authoring and review guidance.
* **Chores**
* Retired automated MDX linting from workflows and local validation
commands.
* Removed lint-suppression markers throughout documentation without
changing instructions.
* Added targeted documentation review guidance for pull requests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
1. Recovery codes section is displayed even when users don't have any
MFA set up
2. Codes modals are janky while the operation (generate or regenerate)
is pending
## Solution
1. Fix the condition checked to display the section (at least one MFA
set up)
2. Fix loading states handling
## Review instructions
On an account without any MFA set up:
1. Check that the recovery codes section is not displayed on
2. Add a new MFA and check the modal for recovery codes appearance is
not janky
3. Delete the recovery codes (this button only exists on local and
staging envs)
4. Check that the warning for missing recovery codes is displayed
5. Generate the codes and check the modal appearance is not janky
6. Regenerate the codes and check the modal appearance is not janky
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which references
[WORD_LIST](https://github.com/supabase/supabase/blob/master/apps/docs/WORD_LIST.md)
and the docs
[CONTRIBUTING](https://github.com/supabase/supabase/blob/master/apps/docs/CONTRIBUTING.md)
guide
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Recovery-code dialogs now open only after code generation or
regeneration finishes.
* Generation and regeneration actions display a loading state while
processing.
* Screen readers are notified when recovery codes are being generated.
* Confirmation actions are disabled while recovery codes are being
generated.
* Recovery-code status and related controls are shown only when a TOTP
factor is configured.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Adding Alice Crosbie to humans.txt
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added Alice Crosbie to the team members list in the public team
information.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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?
Feature, bug fix.
Part 4 of 6 in a stack that splits the library redesign into reviewable
pieces.
## What is the current behavior?
`BlockItem` renders the Open in v0 button, and `BlockItem` sits inside
the Installation section — so the button appears partway down the page.
On guides that install a client first it appears twice, once for the
client and once for the block, and the MDX opts the extra one out with
`showOpenInV0={false}`.
So the page's markup already knows which registry item v0 should open.
Only the component using it is in the wrong place.
## What is the new behavior?
Velite reads that same signal at build time and records the item on the
document, so the page header renders one icon button beside the
framework selector, above the fold. `BlockItem` is left rendering only
the install command.
Guides with no installable item — the getting-started pages, the
TanStack DB generator, and the starters — get no button. Guides that
install a client first resolve to the block, not the client.
## Additional context
63 of 73 documents resolve to a registry item; the 10 that don't are
exactly the ones that should have no button.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Documentation pages now display an “Open in v0” button when supported.
* The button uses a compact, icon-only design alongside the framework
selector.
* **Improvements**
* The applicable v0 destination is determined automatically from
documentation content.
* The page-level action replaces individual block-level v0 buttons,
providing a more consistent experience.
* The button includes an accessible label and appears only for
documentation with a supported v0 destination.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>