Commit Graph
37804 Commits
Author SHA1 Message Date
Danny WhiteandJoshen Lim c9ed51c99e fix(studio): add return to Vercel escape hatch (#48311)
## 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 / UX improvement for the Vercel Deploy Button create-project
interstitial.

## What is the current behavior?

On the Vercel create-project step, the organization picker is locked
(correct — the integration is bound to that org) and Cancel is hidden.
If the org can't create a free project (member free-project limits),
users hit a dead end: Upgrade may not help, and there's no way out of
the popup.

Also includes a small capitalisation nit on the Vercel install page.

| Before |
| --- |
| <img width="800" height="629" alt="Create Vercel Project Supabase"
src="https://github.com/user-attachments/assets/2acdc7a3-eb99-43c6-9135-557370647da1"
/> |

## What is the new behavior?

- Replaces `hideCancelButton` with `cancelAction: 'studio' | 'vercel' |
'hidden'`
- Vercel create flow shows **Return to Vercel**, which redirects to the
install `next` URL (closing the popup cleanly)
- Free-project-limit admonition adds a Vercel-only hint pointing at that
button: “Or return to Vercel and restart with a different organization.”
- Main `/new` Cancel behaviour is unchanged
- Org picker stays disabled

## Additional context

Org switching mid-create is intentionally not allowed. That would orphan
the Vercel install. Returning to Vercel is the safe escape hatch so
users can restart Deploy Button with another org, or free a project slot
/ upgrade and try again.

## To test

As far as I can tell, this is impossible to test on prod. Shortly after
merge though, you could test the following:
- [ ] Happy path: create still works; Return to Vercel is secondary and
does not block submit
- [ ] Free-limit blocked org: Create disabled, Return to Vercel visible
and redirects to `next`
- [ ] Main `/new`: Cancel still goes to last org / organizations

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

- **New Features**
- Enhanced project creation flow for Vercel: when a valid return
destination is available, users can choose **“Return to Vercel”**.
- Added additional messaging in the free-project-limit warning to guide
users back to Vercel and restart with a different organization (when
applicable).
- **Bug Fixes**
- Improved cancel behavior and routing consistency by only enabling
Vercel return when the destination is valid.
- **Style**
- Updated the Vercel integration interstitial title capitalization for
consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-28 08:14:01 +10:00
Leandro Pereiraandgithub-actions[bot] 7838676902 fix: update realtime-warn-sending-broadcast-message (#48366)
Update to reflect actual funcionality and give more tips to fix the
issue.

## 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 troubleshoot guides.



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

- **Documentation**
- Clarified when missing daily partitions trigger the
`WarnSendingBroadcastMessage` warning.
- Updated guidance to explain that partitions are created only after a
client connects via WebSocket.
- Removed the tenant health check endpoint as a described
partition-creation trigger.
- Added troubleshooting steps for connection/authentication failures,
including checking realtime logs, using the Realtime Inspector, and
verifying JWT settings/remediation.
- Revised janitor timing and partition maintenance behavior, including
scenarios where clients cannot connect.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-27 15:03:43 -04:00
supabase-supabase-autofixer[bot]andsupabase-workflow-trigger[bot] b77f4f678c feat: update @supabase/*-js libraries to v2.110.9 (#48363)
This PR updates @supabase/*-js libraries to version 2.110.9.

**Source**: supabase-js-stable-release

**Changes**:
- Updated @supabase/supabase-js to 2.110.9
- Updated @supabase/auth-js to 2.110.9
- Updated @supabase/realtime-js to 2.110.9
- Updated @supabase/postgest-js to 2.110.9
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.110.9

## 2.110.9 (2026-07-27)

### 🩹 Fixes

- **auth:** downgrade stale refresh token console noise
([#2559](https://github.com/supabase/supabase-js/pull/2559))
- **realtime:** preserve presence refs
([#2566](https://github.com/supabase/supabase-js/pull/2566))
- **repo:** override sharp to >=0.35.0 to clear libvips advisory
([#2548](https://github.com/supabase/supabase-js/pull/2548))
- **repo:** populate symbols in sdk-compliance so capabilities are
verifiable ([#2547](https://github.com/supabase/supabase-js/pull/2547))
- **repo:** bump postcss, babel, next to clear audit advisories
([#2561](https://github.com/supabase/supabase-js/pull/2561))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
2026-07-27 18:41:03 +03:00
claude[bot]andClaude 4893c396db fix(studio): split cron_job_cleanup dialog-open from enable to stop double-counting (#48348)
<!-- ccr-slack-attribution -->
_Requested by **Pam Chia** · [Slack
thread](https://supabase.slack.com/archives/C076KTY11DF/p1785115156767339?thread_ts=1785115156.767339&cid=C076KTY11DF)_

## What kind of change does this PR introduce?

Bug fix (telemetry).

## What is the current behavior?

Clicking the header "Enable cleanup" button fires
`cron_job_cleanup_enable_button_clicked` when it merely OPENS the
confirmation dialog (`origin: 'header'`), and fires it AGAIN when the
dialog is confirmed (`origin: 'dialog'` + `retentionInterval`). So every
successful enable logs the event twice, and a naive
`count(cron_job_cleanup_enable_button_clicked)` roughly doubles the true
number of cleanups enabled. The dual-fire was introduced in #48200.

## What is the new behavior?

Opening the dialog fires a new `cron_job_cleanup_dialog_opened` event,
and `cron_job_cleanup_enable_button_clicked` fires only on confirm —
when cleanup is actually scheduled. Each event now maps 1:1 to a
distinct user action.

**How:**
- Added `cron_job_cleanup_dialog_opened` to the shared telemetry catalog
(`packages/common/telemetry-constants.ts`).
- Removed the now-redundant `origin` property from
`cron_job_cleanup_enable_button_clicked` (the two events encode what
`origin` used to); kept `retentionInterval`.
- Updated the emit sites in
`apps/studio/components/interfaces/Integrations/CronJobs/CronJobsTab.EnableCleanupButton.tsx`:
the header open now sends `cron_job_cleanup_dialog_opened`; the dialog
confirm sends `cron_job_cleanup_enable_button_clicked` with just
`retentionInterval`.

## Additional context

`origin` already technically separated the two paths
(`count(origin='dialog')` gave the true number), but splitting into two
named events removes the footgun of anyone aggregating the raw event.

Note for reviewers: I kept the existing event key
`cron_job_cleanup_enable_button_clicked` for the confirm path rather
than renaming it to something like `cron_job_cleanup_enabled` — happy to
rename if preferred, but keeping the key avoids churn on such a new
event.

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

## Summary by CodeRabbit

* **Analytics**
* Improved tracking for the cron job cleanup flow by distinguishing when
the cleanup confirmation dialog is opened from when cleanup is enabled.
* Updated event details to more accurately reflect the cleanup
scheduling and confirmation steps.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 23:29:36 +08:00
Pamela Chia 01541b95cb fix(studio): keep organization_slug in oauth signup redirect (#48352)
Email signups inside a partner OAuth flow lose `organization_slug` on
the post-confirmation redirect: the OAuth branch in `SignUpForm`
hand-builds the `/authorize` return URL from only `auth_id` and `token`,
and the component's nuqs hook never reads the param at all. The consent
screen uses `organization_slug` to preselect and lock the partner's
requested org, so affected multi-org users land on an empty picker and
the partner's requested org is silently dropped. The GitHub-OAuth signup
path goes through `buildPathWithParams` and preserves the param, which
is how this went unnoticed.

I validated the drop in production traffic before fixing: joining
sign-up pageviews to their post-signup `/authorize` return on the
`auth_id` URL param (30d), 28 of 36 resolvable flows came back without
the slug, and the 8 that kept it were the GitHub branch.

## To test

Needs a partner OAuth authorize link that includes an org, opened
signed-out: `/dashboard/authorize?auth_id=<id>&organization_slug=<slug>`
(note `auth_id` records expire quickly, so generate a fresh authorize
request from an OAuth app).

- [x] Sign up with email from that flow; after confirmation the redirect
lands on `/authorize` with `organization_slug` still in the URL
- [ ] Consent screen shows the requested org preselected and locked
- [x] Same flow without `organization_slug` behaves as before (no
trailing empty params in the redirect URL)

## Linear

- fixes GROWTH-1031




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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved sign-up redirects during authentication flows by preserving
invitation tokens and organization information.
  * Enhanced handling of sign-up links containing organization details.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 23:02:05 +08:00
claude[bot]andClaude a72259b3f0 feat(www): group careers page jobs by department (#48358)
<!-- ccr-slack-attribution -->
_Requested by **Dasha Nikolov, Ivan Vasilov** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1785158372513869?thread_ts=1785158372.513869&cid=C0161K73J1J)_

**Before:** the careers page lists open roles under one heading per
individual team (Auth, Data API, Functions, Realtime, Storage, ...).

**After:** roles are grouped under their top-level department heading
(Engineering, Design, ...), collapsing the per-team split.

## 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 / enhancement to the marketing site (`apps/www`) careers page.

## What is the current behavior?

Open positions on the careers page are grouped by individual team,
producing one `<h3>` heading per team (Auth, Data API, Functions,
Realtime, Storage, ...). This fragments the list into many small groups.

## What is the new behavior?

Roles are grouped under their top-level department heading (Engineering,
Design, ...), so related teams are collapsed under a single department
section.

**How:** added a `department: string` field to `JobItemProps` and group
on `job.department` (from the Ashby public job-board API, which returns
both `department` and `team` as top-level strings per posting) instead
of `job.team`. `groupJobsByTeam` is replaced by `groupJobsByDepartment`
(it had no other callers), `getServerSideProps` now calls it, and the
render loop was updated to key on and display the department heading.
All styling, keys, and job rendering are unchanged.

## Additional context

A Vercel preview deploy will show the result on the careers page.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 16:51:38 +02:00
ChloeGarciaMillerandandGildas Garcia da847254d5 fix: ESLint errors relating to accessibility (alt attribute and tableEditor components) (#48186)
## 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?

Improvements for screen readers:
- Added `alt` attributes to image components
- Added `aria-label` attributes and Tooltip to buttons

## What is the current behavior?

`aria-label`, `alt` attributes and Tooltip were missing

## What is the new behavior?

Buttons have now `aria-label` attributes and Tooltip.
Images have `alt` attributes

## Additional context

I’ve added `aria-label` attributes to the buttons in the Pagination.tsx
component, but these buttons don’t trigger any action. Shouldn’t we be
using non-interactive elements here?

No visual changes have been made.

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

* **Accessibility**
* Added a tooltip to the “date options” control when the value is
nullable.
* Improved screen-reader labeling by adding an `aria-label` to the
number editor input.
* Added explicit `aria-label` text to pagination footer buttons for
loading, error, and help/estimate states (and marked the error-state
button as disabled).
* **UI**
* Updated the pagination loading-state button to rely on the button’s
built-in loading behavior instead of a custom spinner icon.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-07-27 14:32:41 +02:00
Kunal Gupta f01ac83ebc Fix Studio contributor README links and Node version note (#47571)
## 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?

docs update

## Description

- Replace the broken checklist link in apps/studio/README.md with the
main contributing guide.
- Update the Studio setup note in apps/studio/README.md to match the
repo Node pin in .nvmrc.


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

## Summary by CodeRabbit

* **Documentation**
* Updated the contribution instructions to point to the main
contributing guide.
* Bumped the recommended Node.js version in the developer quickstart
from v20 to v22.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 19:19:49 +08:00
Riccardo Busetti 6f8fe470a6 ref(pipelines): Update pricing descriptions given new egress calculation (#48241) 2026-07-27 12:52:37 +02:00
Joshen Lim 6058ee7962 Add focus states for spans in overview cards (#48354)
## Context

Tiny one to address for a11y stuff for the spans in the metric cards for
database connections overview section

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

## Summary by CodeRabbit

* **Style**
* Improved hover and keyboard-focus styling for process ID details in
database observability metrics.
* Added a pointer cursor and smoother visual transitions to make
interactive details easier to identify.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 18:50:56 +08:00
Joshen Lim 22284f1786 Use table for roles tooltip instead (#48353)
## Context

Opting to use native `table` element instead for the roles tooltip in
`DatabaseConnections` to better handle varying role name lengths

### Before
<img width="314" height="226" alt="image"
src="https://github.com/user-attachments/assets/f8a5f7a2-be2f-4ad6-a1f0-7a7812800819"
/>

### After
<img width="332" height="191" alt="image"
src="https://github.com/user-attachments/assets/dcb30f5d-641c-4b42-b31d-bf6d76086791"
/>


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

* **Style**
* Improved the layout and readability of the “Connections by roles”
tooltip in database observability metrics.
* Role labels and connection counts are now presented in a clearer
tabular format.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 18:50:38 +08:00
Bobbie Soedirgo 60e6a89f9d fix: make high availability in project creation form public (#48338)
Move "High availability" from internal-only to public. Closes MUL-668.

## 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?

"High availability" is an internal-only config

<img width="724" height="1126" alt="Screenshot 2026-07-26 at 8 15 57 PM"
src="https://github.com/user-attachments/assets/83e1856b-9020-4b65-a019-27e3cc29bae9"
/>

## What is the new behavior?

"High availability" is a public user-facing config

<img width="724" height="1036" alt="Screenshot 2026-07-26 at 8 15 31 PM"
src="https://github.com/user-attachments/assets/4f369058-ce91-4bcf-bd3c-120277363b1a"
/>

Still hidden without the org entitlement, i.e. currently not available
anywhere on prod

<img width="724" height="931" alt="Screenshot 2026-07-26 at 8 18 58 PM"
src="https://github.com/user-attachments/assets/3e1deb76-210c-416b-b716-45ff6e3b0afd"
/>



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

## Summary by CodeRabbit

* **New Features**
* Added a High availability option directly to the project creation
form.
* The option is shown when available for the account and hidden when
unavailable.
* Enabling High availability automatically selects AWS as the cloud
provider.

* **Bug Fixes**
* Corrected validation for incompatible High availability and OrioleDB
selections.

* **Tests**
* Added coverage for High availability visibility, eligibility, and form
submission behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 18:11:35 +08:00
b9ab634cd0 fix(studio): stop 403'd integration queries from looping on remount (#48350)
Resolves FE-4014

A user with a project-scoped role opening any project integration
overview (e.g. Cron) hits an unbounded request loop — the page sits on a
skeleton forever while hammering the platform API until it gets rate
limited.

**Changed:**
- `useProjectOAuthIntegrationData` now passes `retryOnMount: false` to
its five queries, so a 403 settles as a terminal error instead of
refetching on every consumer mount

## Why

Project-scoped roles have no org-level permissions, so `GET
/platform/organizations/{slug}/oauth/apps` 403s. We don't retry 4xx, so
the query settles into `error` with no data — and an errored query with
no data is never fresh, so it refetches on *every* new observer mount.

That feeds a loop: refetch → `isLoading` true → `IntegrationPage` swaps
its whole subtree to a skeleton → `<Component />` unmounts → 403 lands →
`isLoading` false → remounts → mounts fresh observers → refetch.
Measured ~20 req/s (480 observer add/removes and 120 requests in a 6s
window) until the API 429s it, then it continues at the retry cadence
indefinitely.

The other four queries in that hook can 403 the same way for restricted
roles, and any one of them alone sustains the loop — hence the option on
all five.

Not fixed here: `IntegrationPage` tearing down its subtree whenever
`isLoading` flips
(`pages/project/[ref]/integrations/[id]/[pageId]/[childId]/index.tsx:58-94`)
is the amplifier that turns a wasted request into a loop, and will still
reset UI state on any background refetch. Worth a follow-up.

## To test

Needs an account with a project-scoped role in a shared org (not an org
owner/admin).

- Open `/project/{ref}/integrations` for that project, click into Cron
(or any integration) → overview should render, not sit on a skeleton
- Network tab: `organizations/{slug}/oauth/apps?type=authorized` should
fire once and 403, not repeat
- Console should show 1 error, not hundreds ending in a 429
- As an org owner, integration overviews should behave exactly as before


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

* **Bug Fixes**
* Prevented repeated refetching of integration data after handled
authorization/403 errors, avoiding refetch loops on remount.
* Improved consistency on integration landing screens by standardizing
how related integration queries are enabled and retried.
* **Enhancements**
* Added permission-aware loading/error handling for OAuth integration
data, showing OAuth results only when the selected organization grants
read access.
* **Chores**
* Updated permission-check typings to treat an explicitly empty project
reference as absent.
* **Tests**
* Extended integration settings tests with permission fixtures to cover
OAuth read access.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-27 17:58:32 +08:00
Pamela Chia 9113c2ba04 feat: markdown alternate tags + llms.txt cleanup (#48287)
The June/July marketing redesign (#47271, #47228) rebuilt the homepage
and product pages off the Pages Router, silently dropping their `<link
rel="alternate" type="text/markdown">` head tags, and llms-full.txt has
been accidentally embedding every blog/customer/event page via an
`MD_CONTENT` spread. I restored the tags behind a shared helper, added a
CI drift test so a future redesign can't drop them silently again, and
trimmed both llms files to the agreed docs-index shape.

**Changed:**

- **Markdown siblings advertised again**: homepage, the 5 product pages,
pricing, and blog emit absolute `.md` alternate URLs via a new
`mdAlternates(slug)` helper (the one documented consumer of the tag
parses it from `<head>` and fetches the `.md` sibling, so tags must
point at the sibling, never the page itself).
- **Drift test**: a vitest file walks `content/md/**` and asserts every
markdown-served slug's page wires the helper (or is covered by the Pages
Router `_app.tsx` mechanism, whose alternate-link wiring the test also
asserts directly so removing it fails CI too). Source-level assertions
by design: page modules can't be imported under www's vitest config.
Fails correctly when wiring is removed (verified by hiding a page and by
altering the `_app.tsx` tag).
- **Vector orphan fixed**: `content/md/vector.md` moved to
`modules/vector` matching the live route (the page previously had no
negotiation or tag, and `/modules/vector.md` 404'd); `/vector.md` now
308s to `/modules/vector.md` and the legacy `/llms/vector.txt` redirect
no longer chains.
- **llms.txt + llms-full.txt**: the `## Product Overview` sections are
gone from both, each keeps a `## Pricing` section. This deletes the
hand-maintained links array (a drift trap) and fixes the accidental
~470-page embed, shrinking llms-full.txt from ~9.8MB to ~4.9MB and
dropping the 4.1MB generated content module from that route's serverless
bundle.

**Note:** this PR is scoped to apps/www only. The docs side
(troubleshooting pages and the rest of the docs surface) is handled
separately through a consolidated manifest-gated mechanism; an earlier
troubleshooting-tag commit was reverted out of this branch to keep the
scopes clean.

<details>
<summary>Why alternate tags matter (background)</summary>

Agents ingest markdown far more efficiently than our rendered HTML: a
fraction of the tokens and no extraction step. Since #47770 removed
UA-based serving (UA sniffing broke a major AI app's fetcher and
poisoned CDN caches), markdown is served only on explicit request: a
`.md` suffix URL, an `Accept: text/markdown` header, or llms.txt. That's
the right serving model, but it makes the markdown twin invisible to any
agent that doesn't already know our URL convention, and the major AI
fetchers send browser/wildcard Accept headers, so bare URLs hand them
HTML.

The `<link rel="alternate" type="text/markdown">` head tag is the
standards-based advertisement of the sibling. It has a documented
consumer today: an agent CLI that parses the tag from `<head>` and then
fetches the `.md` sibling, which is also why the tag must point at a
real sibling URL and never at the page itself. Peer docs sites ship this
tag as table stakes. These www pages used to carry it until the
June/July marketing redesign silently dropped it; the drift test in this
PR turns that regression class into a CI failure.

</details>

## To test

Tested locally (www + docs dev servers):
- [x] `/llms.txt` renders `## Documentation` + single-link `## Pricing`,
no Product Overview
- [x] `/llms-full.txt` renders `# Supabase` → `## Pricing` → `##
Documentation`, no Product Overview, ~4.9MB
- [x] Full www suite: 6 files / 71 tests green; drift test fails
correctly when a page is removed or the `_app.tsx` wiring is altered
- [x] `generateMdContent.mjs` emits `modules/vector`, bare `vector` slug
gone

On the Vercel preview (browser-verified with Playwright):
- [x] Alternate tag present on `/`, `/auth`, `/database`, `/storage`,
`/edge-functions`, `/realtime`, `/pricing`, and a blog post: exactly one
tag each, href = preview origin + `.md` sibling
- [x] `/vector.md` → 308 → `/modules/vector.md`, renders as markdown (`#
Supabase Vector`)
- [x] `/llms.txt` shows single-link `## Pricing`, no Product Overview
- [x] Coverage sweep: all 482 `MD_PAGES` slugs + changelog index/entry
curled on the preview; 471 pages carry exactly one tag, all `.md`
siblings 200 as `text/markdown`. The 11 misses are legacy blog slugs
whose HTML 308-redirects away (stale `MD_PAGES` entries predating this
PR, no head to tag; follow-up tracked in Linear)

Post-merge prod:
- [ ] Full llms.txt link sweep (every linked URL 200s; previews can't
cover the docs-hosted links)

## Linear

- fixes GROWTH-1013


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

## Summary by CodeRabbit

* **New Features**
* Added Markdown alternate links across key product, pricing, blog, and
troubleshooting pages.
* Added Supabase Vector documentation covering features, use cases,
workflows, and technical details.
* Updated AI-focused documentation indexes with dedicated pricing
content.
  * Added redirects for updated Vector documentation URLs.

* **Tests**
* Added coverage to verify Markdown documentation links stay aligned
with available pages.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 17:06:16 +08:00
fadymak 19dfbd250a feat(auth): expose access token expiry under auth settings (#48236)
Exposes the access token expiry (`JWT_EXP`) under `Auth -> Sessions`
settings as opposed to the Legacy JWT settings previously used.

<img width="1632" height="1199" alt="Screenshot 2026-07-23 at 10 06 33"
src="https://github.com/user-attachments/assets/85356e57-da95-404c-852a-21cf9cab2b74"
/>
<img width="1198" height="1119" alt="Screenshot 2026-07-23 at 10 06 19"
src="https://github.com/user-attachments/assets/bfa64b3b-1902-45eb-83ed-ca8bc12673af"
/>
<img width="1237" height="513" alt="Screenshot 2026-07-23 at 10 03 44"
src="https://github.com/user-attachments/assets/85779e9b-30f2-48c5-9faa-4c650d450227"
/>


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

* **New Features**
* Added an **Access Tokens** section to configure JWT expiration with
dedicated Save/Cancel controls and success/error toasts.
* Enforced a maximum JWT expiration value (must be **less than 604800
seconds**).
* **Bug Fixes**
* Updated the Sessions auth page text to better clarify configuration
for access tokens, refresh tokens, and user sessions.
* **Documentation**
* Updated JWT expiration guidance to point to **Auth settings → Access
Tokens** (replacing legacy JWT secret references).
* **Chores**
* Expanded automated tests covering Access Tokens saving and validation.
* **Refactor**
* Removed JWT expiration editing from the legacy JWT Secrets area,
consolidating it under Access Tokens.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 10:13:10 +02:00
Alaister YoungandAlaister Young d25e10b9c2 fix(ui-patterns): fix admonition self-import + add case-sensitivity guard (#48344)
Fixes the TanStack Studio app failing to load locally, and adds a CI
guard so the same class of bug can't come back.

`packages/ui-patterns/src/admonition.tsx` is a back-compat shim
containing `export * from './Admonition'`. On a case-insensitive
filesystem (macOS, Windows) the resolver tries `./Admonition.tsx` before
the directory index — and that's the same file. The shim re-exported
itself and exported nothing, so every consumer of
`ui-patterns/admonition` blew up with `does not provide an export named
'Admonition'`, plus knock-on Vite dep-optimizer errors about missing
chunks.

It works on Linux, so typecheck, lint, build and tests all pass on CI.
This only reproduces on dev machines.

**Changed:**

- `admonition.tsx` now points at `./Admonition/index` explicitly, so the
specifier can't resolve back to itself

**Added:**

- `scripts/check-case-hazards.mjs` — dependency-free, two textual checks
so they fire on Linux CI:
- **Self-resolving imports**: for `dir/X.tsx`, flags any extension-less
relative specifier resolving to `dir/X` case-insensitively
- **Case-colliding paths**: tracked paths (files and directory prefixes)
equal when lowercased, which can't coexist in a case-insensitive
checkout
- `pnpm test:case-hazards`, plus a step in `typecheck.yml` after
`setup-node` but before `pnpm install` — no deps needed, fails fast

Scoped check 1 to genuine self-imports rather than all case-insensitive
file/directory ambiguity. The broader rule lights up ~45 legitimate
routing pairs (`_app.tsx` + `_app/`, `changelog.tsx` + `changelog/`) and
would get switched off within a week. This version has zero false
positives on master today.

## Follow-up (not in this PR)

The underlying duplication is still there: `src/admonition.tsx` and
`src/Admonition/` both exist, and the ~14 internal `'../Admonition'`
imports inside the package resolve through the shim on macOS but through
the directory on Linux. Two resolution paths for one module is exactly
what produced this.

Real fix is to collapse it. Current counts: **246** files import
`ui-patterns/admonition`, **0** import `ui-patterns/Admonition`. So
either rename the directory to lowercase and delete the shim (zero
import churn, but one lowercase dir among ~50 PascalCase siblings), or
codemod the 246 imports to PascalCase to match the package convention.
I'd lean to the codemod, on a day it won't conflict with in-flight
branches.

## To test

- `pnpm test:case-hazards` on master → passes, ~16.5k files checked
- Revert `admonition.tsx` to `export * from './Admonition'` and re-run →
fails with the offending file and the suggested fix
- Confirm the fixed form `'./Admonition/index'` is *not* flagged
- With the fix in place: `rm -rf apps/studio/node_modules/.vite`, then
`STUDIO_FRAMEWORK=tanstack pnpm dev:studio` → app loads, no
`Pre-transform error` and no missing-export error in the console


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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved detection of file-path casing issues that could cause
failures on case-insensitive systems.
* Corrected a module re-export to ensure the intended UI component is
exposed consistently.

* **Tests**
  * Added a dedicated case-sensitivity hazard check.
* Integrated the check into the type-check workflow for earlier issue
detection.

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

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-27 16:24:45 +10:00
Joshen Lim cbb076ddf1 Blocked by card to only highlight if any query is blocked longer than 10 sec (#48292)
## Context

As per PR title - we're currently showing a "danger" state for the
blocked by metric card as long as there's at least query that's blocked.
This may come off as too noisy in a real database scenario hence opting
to fine tune this behaviour a little

## Changes involved
We'll now only show the "danger" state for the blocked by metric card if
any of the blocked queries are blocked for longer than 10 seconds

<img width="356" height="256" alt="image"
src="https://github.com/user-attachments/assets/e7db5d7e-749a-4c4e-b519-9433a639b0a0"
/>

Otherwise will just be a default card

<img width="359" height="266" alt="image"
src="https://github.com/user-attachments/assets/f9aad85f-8d74-4f55-a3c5-a859d46bd8c1"
/>


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

- **New Features**
- Added clearer blocked-query monitoring, including the longest-blocked
process and duration.
  - Added interactive selection for the longest-blocked process.

- **Bug Fixes**
- Improved activity-duration tracking across active and
idle-in-transaction states.
- Blocked-query warnings now reflect duration thresholds rather than
query count alone.
  - Prevented negative duration values in blocked-query metrics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 13:02:55 +08:00
Hieu 4822687a64 fix: resolve mgmt api specs $refs manually to handle circular error (#48281)
## I have read the CONTRIBUTING.md file.
YES

## What kind of change does this PR introduce?
Bug fix.

## What is the current behavior?
`api_v2_openapi.json` has a circular reference (`APIErrorObject.issues`
→ `APIErrorObject`), which Redocly can't flatten with `--dereferenced`
("Detected circular reference which can't be converted to JSON"). This
breaks the [weekly docs update
workflow](https://github.com/supabase/supabase/actions/runs/29709444085/job/88251269807).

## What is the new behavior?
- Drop `--dereferenced` from `dereference.api.v1` (both v1 and v2, for
consistency)
- Add a `resolveRefs` helper in `Reference.script.ts` that manually
inlines `$refs`, leaving cycles as an unresolved `$ref` instead of
expanding infinitely
- This also fix the mgmt api update workflow so manual dispatch runs
against the selected branch, by changing checkout `ref` from hardcoded
`master` to `${{ github.ref }}`.

## Additional context
Also fixes `pnpm exec redocly` → `npx --package=@redocly/cli redocly` in
the same Makefile, an unrelated pnpm 11 recursive-exec bug hit while
debugging this workflow.

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

* **Chores**
* Updated API specification bundling and linting commands to use the
current Redocly CLI invocation style.
* Improved documentation processing behavior for dereferenced specs,
including guidance around circular references.
* Preserved existing generated specification outputs and validation
settings.
* **Chores**
* Updated the Mgmt API docs automation workflow formatting (YAML string
quoting and schedule/input values).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 10:35:42 +07:00
Joshen Lim fb7debec25 Add top blocker overview card (#48290)
## Context

Adds a "Top blocker" overview card for Database Connections
This should provide a better signal if there's any process that's
behaving as a bottleneck for multiple blocked queries
<img width="977" height="256" alt="image"
src="https://github.com/user-attachments/assets/3d5129a8-f0d7-40a6-808e-0d902889d997"
/>

^ We only highlight the card in red if the query is blocking more than 3
other queries to account - otherwise the signal might be too noisy

<img width="965" height="262" alt="image"
src="https://github.com/user-attachments/assets/f3fda77a-8d52-4e5d-8717-66a26f511a3c"
/>

## Other changes involved
- Am swapping the card positions around a little
- Longest running query card shows the PID as the primary information,
followed by the duration of the run



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

* **New Features**
* Added a **Top blocker** metric to the Database Connections Overview to
highlight the PID/account blocking the most other queries.
* Warning styling now appears when a query blocks more than **3** other
queries.
* Reorganized the metrics layout and ordering for improved visibility
(active, idle-in-transaction, blocked, top blocker, and longest
running).
* **Bug Fixes**
* Updated tooltip and guidance text for clearer explanations of blocked
and idle-in-transaction states.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 11:08:57 +08:00
2b27ed0ab1 fix(docs) Improve a11y for Admonitions with file refactor (#48112)
Closes FE-3914


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

YES

## Problem

On screenreader, I found that the Admonition was not behaving as it
should:
- There was no way on screenreader to tell what type of note I was
seeing
- I could not tell when a note began or ended.
- The screenreader also read aloud an 'image' icon without knowing what
it was.
- Notes with titles were an `h5`, breaking header hierarchy structures.

## Solution

This PR does several things to resolve the issue:
- Adds `aria-hidden` to all icons. Instead of duplicating code, I
refactored the icons into a Base Icon and moved Admonitions into its own
folder.
- ~Adds a text label for each of the notes. For example, "**Note:**".
This is a standard practice in other documentation. If there is a title,
it is added there. Otherwise, it's added to the description.~ Change
reverted from design feedback.
- ~Adds `role='note'` and `aria-label` to the Admonition. While
`<aside>` is recommended semantic HTML, the base UI element does not
allow for that change.~ This will be done in a follow-up for docs only.
- Refactors Admonition into a folder with files so that it is more
readable
- Removes `h5` by default with a new prop to declare a header

Additionally adjusts the icon so that it aligns with text better.

## Testing

1. Open documentation preview
2. Navigate to any guide and see its admonition. Compare to live. You
can also see the Design System:
https://design-system-git-a11y-docs-admonition-supabase.vercel.app/design-system/docs/fragments/admonition
3. See the icon position is in line with the text.
4. See the text label.
5. Use a screenreader like Voiceover on the admonition. Hear that it is
clearly defined.


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

## Summary by CodeRabbit

- **New Features**
- Added the Admonition UI pattern with support for `type`, `layout`,
`title`/`description`, optional actions, and configurable icons.
- Expanded Admonition’s public export surface with dedicated subpath
entry points and icon/type exports.
- **Bug Fixes**
- Standardized Admonition import path casing across related components.
- **Documentation**
- Updated design system examples to use `type="warning"` instead of
`variant="warning"`.
- **Tests**
- Added/updated the Admonition test coverage and removed the legacy test
file.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-07-24 15:51:19 -07:00
d46cc88f09 docs: add agent prompts to all 18 framework quickstarts (#47543)
## 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?

Docs enhancement: Agent-ready prompt blocks on all 18 framework
quickstart pages.

## What is the current behavior?

Framework quickstarts do not surface a copyable AI prompt. Readers have
to assemble context themselves when asking an AI coding assistant to
follow the guide.

## What is the new behavior?

- Partials at
`apps/docs/content/_partials/ai/quickstart_prompt_{framework}.mdx`
contain `<AiPrompt prompt={...} />` (Prettier multiline single-quoted JS
string with `\n` escapes).
- Each quickstart includes `<$Partial
path="ai/quickstart_prompt_{framework}.mdx" />`.
- Runtime: `AiPrompt` → `PromptPanel` (Copy AI Prompt, expandable).
- Markdown export: `apps/docs/internals/markdown-schema/AiPrompt.ts`
decodes Prettier single-quoted prompt expressions so exported markdown
includes an **AI Prompt** section without quote leak.
- Shared `$Partial` helpers live in `lib/partials.utils.ts`.
- Closes DOCS-1144.

### Example before/after

| | Production | Preview |
| --- | --- | --- |
| Next.js quickstart |
[production](https://supabase.com/docs/guides/getting-started/quickstarts/nextjs)
|
[preview](https://docs-git-nikrichers-docs-1144-add-ai-prompt-blo-5af4d8-supabase.vercel.app/docs/guides/getting-started/quickstarts/nextjs)
|

**Light**

| Before | After |
| --- | --- |
| ![before
light](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47543/quickstart-nextjs-before-light-d1076045.png)
| ![after
light](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47543/quickstart-nextjs-after-light-74996d6c.png)
|

**Dark**

| Before | After |
| --- | --- |
| ![before
dark](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47543/quickstart-nextjs-before-dark-faa391c3.png)
| ![after
dark](https://moijyfpvgnmgoxvwcikq.supabase.co/storage/v1/object/public/pr-proof/supabase/supabase/pr47543/quickstart-nextjs-after-dark-56d1578a.png)
|

### Test plan

- [x] Preview renders AI Prompt panel with copy
- [x] Spot-check Next.js, Flutter, Expo, Vue
- [x] `test-quickstart-prompts` structural
- [x] Markdown export includes **AI Prompt** without quote leak
- [x] Format CI green after prettier/single-quote decode fix

## Additional context

- Worktree:
`~/GitHub/supabase/supabase-worktrees/nikrichers/docs-1144-add-ai-prompt-blocks-to-all-18-framework-quickstarts`
- Skills: `generate-quickstart-prompts` / `test-quickstart-prompts`;
librarian update https://github.com/supabase/docs-agent-skills/pull/21
- `PromptPanel` replaced the older GlassPanel experiment for the
expandable copy UI

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
Co-authored-by: jeremenichelli <jeremenichelli@users.noreply.github.com>
2026-07-24 22:19:04 +00:00
Danny White 8e75147f0c docs: clarify apps/docs local env setup (#48208)
## Summary
- Fix docs setup step 2: secrets go in `.env.local` (not `.env`), and
staff should run `pnpm run dev:secrets:pull` from `apps/docs`
- Add a one-line pointer from the root `DEVELOPERS.md` to
`apps/docs/DEVELOPERS.md`

## Test plan
- [ ] Skim the two touched lines and confirm they match how
`dev:secrets:pull` / dotenv actually work

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

## Summary by CodeRabbit

* **Documentation**
* Clarified environment setup instructions for running the website and
documentation sites individually.
* Added docs-specific guidance for retrieving secrets and configuring
the local environment file.
* Updated community setup instructions with the required local
configuration setting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-25 03:36:32 +10:00
Miranda Limonczenko b5cae478bc fix(docs) Add smoke test for local development without credentials (#48218)
Closes DOCS-1210
Closes DOCS-1209

#48226 needs to merge first for CI failure

## 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?

Test coverage and several small bug fixes discovered during
implementation.

## What is the current behavior?

Nothing verified that `pnpm run dev:docs` keeps working without private
credentials.
We value this command working, especially for community contributors.

However, this issue can go undetected by employees at Supabase since
many of us have credentials in place. We do not want this to go a week
before finding and fixing like in the previous instance.

## What is the new behavior?

- **New Playwright test suite**:
`e2e/docs/local-smoke/no-credentials.spec.ts` boots the docs dev server
with zero GitHub App/Supabase secrets and checks 5 routes covering each
known failure point.
- **CI**: a new `local-dev-smoke` job in `docs-tests.yml` runs this
suite with no credentials configured.


## Additional bugs resolved

Setting up this test exposed other issues that are fixed in this PR:

- **Troubleshooting.utils.ts crash** — Unguarded Supabase call pattern,
crashing every troubleshooting article. Added the same guard as previous
fixes.
- **Missing manifest.json** — middleware.ts statically imports
public/markdown/manifest.json, which is gitignored and only generated by
a build step that's skipped in local dev. On a fresh checkout it doesn't
exist, so middleware fails to compile and takes down every page. Fixed
by committing a placeholder [] (real builds still regenerate the full
file).
- **Phantom @code-hike/mdx import** — apps/docs/app/layout.tsx imported
@code-hike/mdx/styles.css, but only apps/www actually declares that
dependency. Worked by accident whenever both apps were installed
together; broke in CI's docs-only install. Turned out to be dead code
(nothing in docs actually uses code-hike), so fixed by deleting the
unused imports rather than adding the dependency.


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

## Summary by CodeRabbit

* **New Features**
* Added a credential-free “local smoke” end-to-end test suite for key
documentation routes.

* **Bug Fixes**
* Improved troubleshooting behavior when required external service
credentials are missing.
* Updated federated “wrappers” documentation pages to gracefully show a
fallback message when external content can’t be fetched.

* **Tests**
* Added a dedicated local-smoke Playwright runner and enhanced CI
path-based triggering and reporting (failure-focused artifacts).

* **Chores**
* Refined docs workflow path filters and adjusted docs markdown
manifest/ignore rules for generated content.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 10:29:12 -07:00
kemal.earth 84e273cf0b fix(studio): alignment of compute pricing blocks on compute settings (#48289)
## 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?

Fixes alignment issues across viewports with the size blocks on compute
& disk page.





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

## Summary by CodeRabbit

* **New Features**
  * Added responsive container support for horizontal form layouts.
* Compute-size options now adapt more smoothly to available screen
space.
* Preserved existing loading states, error messages, pricing details,
locked options, and larger-compute guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 17:35:50 +01:00
Alaister YoungandAlaister Young 8d4d3b57e0 feat(studio): add tanstack variant to the studio docker image (#48091)
Makes the self-hosted Docker image buildable with the TanStack/Vite
build alongside the existing Next one. The Dockerfile's new
`STUDIO_FRAMEWORK` build arg (default: `next`) selects which framework
lands in the image — the same variable `scripts/dispatch.js` keys on
everywhere else, so `--build-arg STUDIO_FRAMEWORK=tanstack` is the
docker spelling of the existing switch. Both flavors assemble a
normalized `/srv` tree, so a single production stage serves either with
the same CMD (`node apps/studio/server.js`), port 3000, and healthcheck.

Unlike Next's self-contained standalone output, the Vite SSR bundle
externalizes studio's dependencies and resolves them from `node_modules`
at request time, so the tanstack runtime tree is a prod-only `pnpm
deploy` plus the built `dist/`. The boot smoke test runs a second time
against that pruned tree, so a runtime import that's missing from
`dependencies` fails the image build instead of 500ing the deployed
container — which is exactly how this PR caught four packages
misclassified as devDependencies (`braintrust` +
`@smithy/property-provider` via the AI routes, `libpg-query` via the
parse-query API route, `@radix-ui/react-use-escape-keydown` via the
Queues panel; split into its own commit).

**Changed:**
- `apps/studio/Dockerfile`: `ARG STUDIO_FRAMEWORK` selects `build-next`
/ `build-tanstack` stages via `FROM build-${STUDIO_FRAMEWORK}`; both
normalize into one production layout
- `apps/studio/package.json`: moved the four runtime-imported packages
from devDependencies to dependencies (versions unchanged)
- `apps/studio/vite.config.ts`: pinned `preview.host` to `127.0.0.1` —
the prerender step boots `vite preview` and crawls its resolved URL, and
the default `localhost` host lets the server bind the IPv6 loopback
while the crawler fetches `127.0.0.1`, which ECONNREFUSEDs the whole
build inside BuildKit containers
- `.github/workflows/studio-docker-build.yml`: builds the tanstack image
as a second step (reuses the first build's layer cache; job name
unchanged)

**Added:**
- `build:studio:docker:tanstack` root script

Note: the tanstack image is ~2.0GB vs ~1.2GB for Next (externalized
`node_modules`); shrinking it via file tracing is a follow-up. Nothing
self-hosters pull changes until a tanstack-built image is published —
this makes it buildable and CI-checked.

## To test

- `pnpm build:studio:docker` then run the image against a stack —
behavior unchanged (healthcheck `/api/platform/profile` 200, `/` 307s to
`/project/default`)
- `pnpm build:studio:docker:tanstack` then run that image with the same
env — same healthcheck, redirect, and data endpoints (projects, pg-meta)
respond 200; browser loads Project Overview / Table Editor with no
requests leaving the container
- Both verified locally against the CLI stack (`host.docker.internal`
env, container reports `healthy`)
- Vercel + e2e checks on this PR exercise the `preview.host` change on
their runners

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

- **New Features**
- Added TanStack-based Studio build support with a framework-selectable
Docker image.
  - Added a local build command for the TanStack Studio Docker image.
- **Build & Deployment**
- Updated the Studio Docker build workflow to also publish a
TanStack-tagged Studio image when relevant.
- **Bug Fixes**
- Improved `vite preview` behavior in containers by binding to IPv4
loopback.
  - Standardized the Studio container runtime port to `3000`.
- **Chores**
  - Updated Studio runtime packages to support the TanStack build.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-24 15:32:05 +00:00
Tyler Hillery 74a57861b3 chore(studio): remove region limitation for vector buckets (#48248)
## 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?

Remove the region limitation on vector buckets

## What is the current behavior?

Currently vector buckets are limited to a subset of Supabase regions

## What is the new behavior?

All supabase regions now have access to vector buckets

## Additional context




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

## Summary by CodeRabbit

* **New Features**
* Vector buckets are now available based solely on platform enablement,
without region-based restrictions.

* **Bug Fixes**
* Removed the region limitation message and related region availability
checks from the Storage Vectors page.
* Updated vector bucket upgrade behavior to reflect platform
availability more consistently.

* **Tests**
* Updated coverage to reflect the simplified platform-based availability
behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 07:54:07 -07:00
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
Gildas Garcia 2a17985a1c fix: Skip to main content link should be visible when focused (#48303)
## Problem

#47694 introduced a _Skip to main content_ link allowing keyboard users
to jump to the main section without having to tab through all the
navigation elements.

However, this link is completely invisible which means sighted users
will not see what is actually focused.

## Solution

The best practice for such links is to make them visible on focus. For
instance on https://tetralogical.com:
<img width="1556" height="305" alt="image"
src="https://github.com/user-attachments/assets/e36f6d73-98b0-46ca-b464-72540a482b5f"
/>

Here's what it looks like on Studio:
<img width="1835" height="335" alt="image"
src="https://github.com/user-attachments/assets/71623306-587a-48aa-b955-43d3368f6073"
/>

## How to test

- Make sure your browser allows to tab to links
(https://www.articulatesupport.com/article/How-to-Enable-Tab-Key-Navigation-on-a-Mac)
- Open
https://studio-staging-git-gildasgarcia-fe-3805-add-ski-cf6824-supabase.vercel.app
and sign in
- Once the Studio is loaded, verify the button isn't be visible
- Press _Tab_: the button should be visible.
- Press _Enter_, then press _Tab: the organizations search input should
be focused
2026-07-24 16:04:36 +02:00
Danny WhiteandJoshen Lim 69570a357d fix(studio): route vercel deploy-button params to create despite marketplace source (#48258)
## What kind of change does this PR introduce?

Bug fix for the Vercel Deploy Button → Studio handoff.

## What is the current behavior?

Vercel sometimes opens our install popup with `source=marketplace` while
still sending Deploy Button params (`currentProjectId`, `external-id`).
We trust `source` alone, so users are routed to choose-project (connect)
instead of create — which is why create never gets reached in the Deploy
Button flow.

## What is the new behavior?

- When both Deploy Button signals (`currentProjectId` + `externalId`)
are present, route to create even if Vercel sent `source=marketplace` /
`external`
- Hide Skip (and related empty-state copy) on choose-project when those
signals are present, so Deploy Button users can't continue without
linking

## Additional context

Stacked on #48230.

Test plan:
- [ ] Unit tests for `resolveVercelInstallSource` /
`hasVercelDeployButtonSignals` pass
- [ ] Deploy Button flow with mislabeled `source=marketplace` + both
params → lands on create after org install/continue
- [ ] Genuine marketplace install (no `currentProjectId`/`external-id`)
→ still lands on choose-project with Skip available
- [ ] If choose-project is opened with both Deploy Button params, Skip
is hidden

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

- **New Features**
- Improved Vercel installation handling for Deploy Button workflows,
ensuring the correct setup path is selected.
- Added clearer project-connection guidance when no projects are
available (including conditional skip copy).

- **Bug Fixes**
- Prevented Deploy Button installations from incorrectly offering a skip
option.
- Preserved the skip-and-connect-later guidance for other Vercel
installation flows.
- Improved recognition of Deploy Button installations even when the
reported Vercel source differs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-25 00:00:37 +10:00
Etienne Stalmans 2f0a582198 chore: remove triplit link (#48286)
## 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?

Blog update

## What is the current behavior?

Triplit link goes to triplit.dev which is no longer registered/active

## What is the new behavior?

No more triplit.dev link


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

## Summary by CodeRabbit

* **Documentation**
* Updated the blog post’s opening paragraph by removing the hyperlink
from the “Triplit” text.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 14:50:52 +01: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
Crispy 8c092185ae feat: paused project restore window copy and backup downloads (#48279)
Shows the restore deadline as a date on the paused-project screens, and
offers backup downloads while a paused project is still restorable
(previously only after the restore window ended).

Depends on a backend change — keep as draft until that is live.

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

* **New Features**
* Extended the paused-project restore window from 90 days to up to 1
year.
* Added clearer, downloadable options for database backups and storage
objects while a project is paused.
* Paused-project screens now show an “available until” date when
applicable (and updated resume guidance).
* **Documentation**
* Updated platform and troubleshooting guides to reflect the new 1-year
restore window and post-window recovery limitations.
* **Bug Fixes**
* Standardized restore-window wording across the pause confirmation and
paused-state UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 19:45:34 +07: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
Jeremias Menichelli 075caf314e chore: refactor database advisors and database wrapper federated content (#48199) 2026-07-24 12:26:33 +02:00
ChloeGarciaMillerand cea246d195 Fix: improve accessibility for icon buttons (Table Editor menu) (#47639)
## 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 (accessibility improvement)

## What is the current behavior?

Icon-only buttons do not have explicit accessible names for screen
readers or tooltips.

## What is the new behavior?

All icon-only buttons now have explicit accessible names using visually
hidden text (sr-only), ensuring proper screen reader support.

## Additional context

Tooltip text is preserved or added for visual users.
No visual changes were introduced.


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

* **Accessibility Improvements**
* Updated table editor action controls with clearer, context-aware
`aria-label`s (e.g., “Add new column”, “More options for …”, “New
table”).
* **UI Refinements**
* Added hover tooltips to key table editor actions, including
add-column, more-options dropdown triggers, and create-new-table button,
improving discoverability and guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 10:47:14 +02: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
Joshen Lim 223a10d1bb Add query filter for Database Connections (#48242)
## Context

Adds a way to filter against the query string in Database Connections
<img width="682" height="161" alt="image"
src="https://github.com/user-attachments/assets/1ba6d678-553a-4a1a-9da9-412532c626df"
/>


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

* **New Features**
  * Added a free-text search filter for database activity sessions.
* Search works alongside existing state, role, and application filters.
  * Filter option counts now reflect the current search results.

* **Bug Fixes**
* Improved filter reset behavior to reliably clear search along with all
other selections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 16:42:57 +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
Joshen Lim a1df468edd Add keyboard shortcut to live mode (#48280)
## Context

As per PR title - there's already a keyboard shortcut mapping for the
live mode toggle that was originally present in `UnifiedLogs`, so this
reuses that.

Opting for a more explicit tooltip copy as well as "Live" doesn't really
explain what it does
<img width="257" height="82" alt="image"
src="https://github.com/user-attachments/assets/2159eef3-6291-4fdc-93ca-da706c8688f0"
/>
<img width="195" height="101" alt="image"
src="https://github.com/user-attachments/assets/0d5d211c-af66-406d-9cff-7de7b15f0892"
/>


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

## Summary by CodeRabbit

* **New Features**
* Added keyboard shortcut support for toggling live updates in database
connections.
  * Added shortcut guidance to the Live/Pause control.
* Resuming live updates now refreshes activity immediately and updates
the displayed timestamp.

* **Bug Fixes**
* Improved live-refresh controls and messaging to clearly reflect the
refresh cadence.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 15:18:21 +08: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
shaziya ddd0f3e8d8 feat(www): update Grafana Cloud blog post authors (#48284)
## 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?

Content update — updates the author byline on an existing blog post
(`apps/www`).

## What is the current behavior?

The "Observability for every Supabase project with Grafana Cloud" post
lists a single author (`raminder_singh`).

## What is the new behavior?

Updates the byline to the three authors credited in the source doc: Alex
Hall, Matt Linkous, and Raminder Singh.

- Adds a new `authors.json` entry for `alex_hall` (GitHub `alexhall`,
Engineering)
- `matt_linkous` and `raminder_singh` already existed
- Updates the post frontmatter: `author: alex_hall, matt_linkous,
raminder_singh`

## Additional context

- Source doc:
[Notion](https://app.notion.com/p/supabase/Blog-Post-Grafana-Cloud-Partner-drop-3455004b775f8108935feefecd87623f)
- Follow-up to #47716 (the original post, already merged)
- Pre-flight: Prettier passes; `authors.json` is valid JSON

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

## Summary by CodeRabbit

* **Documentation**
* Updated the Grafana Cloud observability blog post to credit all
contributing authors.
* Added an author profile for Alex Hall, including their role and
profile details.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 06:27:49 +01:00
Alaister YoungandAlaister Young 4b24cf028a chore(claude): improve CLAUDE.md files and skill triggering (#48261)
Improves the repo's agent guidance: distills the always-required
`studio-best-practices` skill into `apps/studio/CLAUDE.md`, tunes every
skill description for reliable triggering, and mechanically enforces the
generated-files rule. Grounded in Anthropic's official CLAUDE.md
guidance (see justifications below).

## The main change: Studio CLAUDE.md gets a Code style section

**Why:** `studio-best-practices` was a skill that instructed agents to
*always* load it before any Studio code work. Anthropic's guidance draws
the line as: sometimes-relevant guidance → skill (loaded on demand);
always-relevant guidance → CLAUDE.md. A skill that must always load has
failed the test for being a skill — it costs a tool-call round trip and,
worse, silently does nothing in sessions that forget to load it. Since
`apps/studio/CLAUDE.md` is lazy-loaded only when an agent touches Studio
files, inlining is properly scoped: non-Studio sessions never pay for
it.

**Why not verbatim:** the skill was 175 lines, mostly ❌/✅ worked
examples teaching practices models already know. Inlining it whole would
push the file past the ~200-line point where Anthropic warns rules start
getting lost. Instead each section was distilled to the rule it exists
to enforce — e.g. the loading/error/success section kept its code block
because the *shape* (early returns at top level, flat `&&` chains
inline) is the prescription, and prose loses it.

**The framing that makes the generic rules earn their place:** models
default to matching surrounding code, and not all existing Studio code
follows these practices. The section opens with "older Studio code
predates some of these conventions — follow them rather than mirroring
nearby legacy patterns," which converts otherwise-redundant React advice
into an explicit instruction to break from local precedent. One rule was
added that the old skill lacked: `useEffect` is for external-system sync
only (~364 Studio files contain effects, many in patterns we don't want
copied).

**Changed:**
- `apps/studio/CLAUDE.md` — new Code style section (84 lines total,
within budget); skills table no longer mandates a pre-load
- `.claude/CLAUDE.md` — dropped `pnpm install` from commands (guessable;
Anthropic's test: "would removing this cause mistakes?")

**Removed:**
- `.claude/skills/studio-best-practices/` — fully absorbed; its
cross-references to other skills were already covered by the skills
routing table

## Skill description tuning

Descriptions are the only signal an agent sees before deciding to load a
skill, and the observed failure mode is under-triggering on tasks that
don't name the skill. Nine descriptions reworded: front-loaded matchable
keywords, added incidental-trigger cases (e.g. a new feature that adds
copy is a `copywriting` moment), and disambiguated overlaps (`vitest` is
now the API reference deferring to `studio-testing` for strategy). The
`safe-sql-execution` rewrite was additionally validated with
skill-creator's trigger-eval loop against 20 realistic queries: held-out
test accuracy 54% → 71%, with zero false triggers across all iterations.
(`vitest` shows under `.agents/` because `.claude/skills/vitest`
symlinks there.)

## Generated-files enforcement

**Added:** `permissions.deny` rules in `.claude/settings.json` for the
six generated-file globs the root CLAUDE.md already lists. CLAUDE.md
prose is advisory; permission rules are mechanical and also gate
sandboxed Bash writes. (Verified live: the rule blocked an unintended
regeneration of `database-types.ts` during testing.)

## To test

- CI: prettier + typos checks pass (docs-only + settings change, no app
code)
- In a fresh Claude Code session in the repo: ask it to edit
`apps/studio/routeTree.gen.ts` — should be denied by the new permission
rule
- Ask it to do any Studio UI task — it should pick up the Code style
rules from `apps/studio/CLAUDE.md` without loading a best-practices
skill

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

## Summary by CodeRabbit

* **Documentation**
* Updated development guidance for testing, copywriting, SQL safety,
telemetry, queries, error handling, and toolbar reviews.
* Restructured Vitest references into clearer tables and improved
formatting across several guides.
* Added Studio code-style conventions and clarified when task-specific
guidance should be applied.
  * Removed outdated Studio best-practices guidance.

* **Chores**
  * Added safeguards preventing edits to generated and protected files.
  * Simplified the documented development command sequence.

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

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-24 11:58:49 +08:00
Joshen LimandDanny White 7f42765070 Joshen/fe 3983 no way to create a new project in vercel integration when (#48230)
## Context

For the Vercel integration flow (e.g "Deploy with Vercel" button on GH)
If an organization has no projects, there currently isn't a way to
create a project and connect it in the same session - users can only hit
"Skip".

This addresses that by directing users to the /deploy-button/new-project
route in this scenario

<img width="505" height="539" alt="image"
src="https://github.com/user-attachments/assets/6cc85030-42c7-4e58-b4b3-cb8ac0f5da9e"
/>

## Other changes involved
- Also separates `ProjectLinker` into smaller components - preference
for avoiding declaration of components within a component

## To test

I'm not sure if this can be tested on staging to be honest, but
otherwise we can give it a go on production after the changes are
through, as this doesn't change any existing logic to the usual "Connect
project" flow

I did try clicking the "Deploy with Vercel" button on a repo, and just
changing the URL to the staging URL at the Supabase step - seems to work

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

## Summary

* **UI Improvements**
* Streamlined the Vercel/GitHub project-linking step while keeping the
same create/connect/skip flow, including the searchable project picker,
branding/status indicators, and the feature-flagged “create new project”
option.
* On the Vercel choose-project step, the default selection now reflects
the current project context.

* **Bug Fixes / Tests**
* Improved Vercel install routing query handling to preserve
deploy-button configuration when present, with updated automated test
coverage.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-07-24 11:22:57 +08:00
Joshen LimandDanny White d0e781a960 Allow users to continue with org if integration installed (#48231)
## Context

For the Vercel integration, if the source is marketplace, currently
selecting an organization that already has the integration installed
prevents the user from proceeding.
<img width="267" height="172" alt="image"
src="https://github.com/user-attachments/assets/ba3aafa0-f753-4797-89cd-a7f1e16bbdb2"
/>


Whereas users should just be able to proceed and select a project from
within the organization
<img width="435" height="226" alt="image"
src="https://github.com/user-attachments/assets/e659bc20-6980-4ef2-af5c-8612af99668b"
/>


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

* **New Features**
* Enhanced the Vercel integration installation flow with dynamic primary
button text (“Continue” vs “Install integration”) based on installation
status.
* **Bug Fixes**
* Updated the install button so it no longer disables when the selected
organization already has the Vercel marketplace integration installed.
  * Removed the “already installed” warning from the main render path.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-07-24 10:49:21 +08: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
Claude e0e88eb708 fix(studio): coerce api-keys query result to an array 2026-07-23 22:23:08 +00: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
shaziya b6e574e5cd fix(www): stop on-demand mdx events from winning the events marquee (#48264)
## 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 — the [events index](https://supabase.com/events) was featuring
the TRAE webinar in its marquee days after the event happened, instead
of the next genuinely upcoming event (the Dublin meetup), and counting
it toward the "Webinar" filter chip alongside actually-upcoming
webinars.

## What is the current behavior?

`getMdxEvents()` in `lib/events.ts` only excludes past events by
comparing dates against the start of today in UTC. It doesn't check
`onDemand` at all. The TRAE event's timestamp
(`2026-07-22T19:00:00.000-07:00`) converts to `2026-07-23T02:00:00Z`,
which is still "today or later" by that UTC cutoff — so even though the
event already happened and flipped to `onDemand: true`, it kept getting
returned as an "upcoming" event. Since the events marquee
(`featuredEvent`) just picks the earliest-dated event from that pool,
TRAE kept winning over the actually-upcoming Dublin meetup, and it kept
counting toward the "Webinar" filter chip.

## What is the new behavior?

`getMdxEvents()` now excludes any event with `onDemand: true` outright,
regardless of how its date converts across timezones — on-demand events
belong solely in the on-demand bucket (`getOnDemandMdxEvents`), not the
upcoming/marquee pool. Verified locally: the "Webinar" filter chip count
on `/events` drops to 0 with this in place (previously counted TRAE),
while the TRAE event's card in the on-demand list still correctly shows
its "Webinar" tag and "Supabase Live" line, matching the other on-demand
webinars (Perplexity, Datadog) — only its bucket assignment changed, not
its labeling.

## Additional context

Couldn't verify the marquee itself locally since the Luma events API
returns a 500 in local dev (missing credentials, pre-existing/unrelated
to this change). Confirmed independently via the production Luma API
that the Dublin meetup (`2026-07-28T17:00:00Z`) is genuinely the next
chronological event, so it will naturally take over the marquee once
this ships — no hardcoding needed.

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

## Summary by CodeRabbit

* **Bug Fixes**
  * On-demand events are no longer shown in the upcoming events list.
* Upcoming events continue to be filtered by their relevant date, while
on-demand event listings remain unchanged.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 20:19:55 +01:00
Miranda LimonczenkoandClaude Sonnet 5 39276f80d0 fix(docs ci): stop docs-e2e from polling the broken GitHub Deployments API (#48226)
## Summary
- `vercel/wait-for-deployment-action` in
[docs-e2e.yml](.github/workflows/docs-e2e.yml) polls GitHub's
Deployments API for a `Preview – docs` deployment, but Vercel's GitHub
App has not written a GitHub Deployment object repo-wide since
2026-02-17 (broken app auth). The step times out after 900s on every PR
that touches `apps/docs`, even though the preview build itself succeeds
(`Vercel – docs` commit status is green).
- Replace the wait step with a custom poll of the `Vercel – docs` commit
status (which Vercel keeps posting correctly), then resolve the actual
preview URL via Vercel's own deployments API (`GET
/v13/deployments/{id}`) using the deployment ID embedded in the commit
status's `target_url`, reusing the existing `VERCEL_TOKEN` /
`VERCEL_TEAM_ID` secrets.
- Drops the now-unused `deployments: read` permission.

## Context
Reported in Slack:
https://supabase.slack.com/archives/C023E4L60R3/p1784721725606599?thread_ts=1784658589.182079&cid=C023E4L60R3
(surfaced by [#48178](https://github.com/supabase/supabase/pull/48178)
failing on this step — [run
29916797889](https://github.com/supabase/supabase/actions/runs/29916797889?pr=48178)).
Agreed workaround from that thread: swap the wait step to poll the
`Vercel – docs` commit status instead of the Deployments API.

## Test plan
- [ ] Confirm this workflow run (triggered by this PR since it edits
`apps/docs/**`... actually this PR only touches the workflow file, so
verify via `workflow_dispatch` or a follow-up PR touching
`apps/docs/**`) passes the "Wait for Vercel docs preview" step and
resolves a working `deployment-url`
- [ ] Confirm downstream Playwright E2E run against the resolved preview
URL succeeds
- [ ] Confirm the step still fails cleanly (clear error, no silent hang)
if the Vercel deployment itself fails

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

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

* **Bug Fixes**
* Improved documentation preview deployment handling in end-to-end
tests.
* Replaced the preview wait logic with more reliable polling for the
relevant commit status, including clear success/failure/error and
timeout behavior.
  * Resolve the correct documentation preview URL before tests proceed.
* **Chores**
* Tightened permissions for the documentation E2E workflow to use only
the required access scopes.
* Streamlined job setup steps so Node/Pnpm preparation runs earlier in
the workflow.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 11:33:38 -07:00