mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
2cd9b42e803277edefaa02e8aa5e4cdc27c19bb2
6389
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2cd9b42e80 |
fix(studio): add a keyboard shortcut for the Compute sidebar item (#50361)
The Compute entry in the project sidebar was the only product route without a `shortcutId`, so it had neither a `G`-chord nor the hover keybind tooltip every sibling gets. Bound it to `G` then `C` (previously unused) and added a test asserting every product route carries a shortcut. Fixes FE-4389 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a keyboard shortcut for quick navigation to Compute: press **G**, then **C**. - Compute navigation now includes a discoverable shortcut for consistent access from the navigation interface. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8bbd1d3048 |
fix(studio): fall back to unified preset for an unrecognized query-performance preset (#50348)
## Summary
- `useIndexInvalidation()` resolves the `preset` URL param through
`QUERY_PERFORMANCE_PRESET_MAP` with no fallback.
- A value that isn't one of the four known
`QUERY_PERFORMANCE_REPORT_TYPES` (stale bookmark, hand-edited URL, a
renamed/removed preset) resolves to `undefined`.
- That `undefined` preset flows into `generateQueryPerformanceSql()`,
which indexes `queryPerfQueries.queries[preset]` with it, producing
`undefined` for `baseSQL` — and the very next line reads
`baseSQL.queryType`, crashing the whole page via `globalErrorBoundary`.
- Fix: fall back to the `unified` preset when the URL value doesn't map
to a known preset, mirroring the `parseAsString.withDefault('unified')`
intent already expressed a few lines above for the case where the param
is entirely absent.
## Evidence (Sentry, past week)
- [SUPABASE-APP-K9Z](https://supabase.sentry.io/issues/7721026586/) —
`TypeError: Cannot read properties of undefined (reading 'queryType')`
on `/dashboard/project/[ref]/observability/query-performance`.
## Test plan
- [ ] Existing `useQueryPerformanceQuery.test.ts` suite still passes
- [ ] Manually confirmed
`QUERY_PERFORMANCE_PRESET_MAP[QUERY_PERFORMANCE_REPORT_TYPES.UNIFIED]`
resolves to `'unified'`, a valid key in
`PRESET_CONFIG[Presets.QUERY_PERFORMANCE].queries`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM
---
_Generated by [Claude
Code](https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
|
||
|
|
62fe0fca4a |
fix(studio): guard branches and read-replicas queries against non-array 200 bodies (#50347)
## Summary - `getBranches()` (`apps/studio/data/branches/branches-query.ts`) and `getReadReplicas()` (`apps/studio/data/read-replicas/replicas-query.ts`) cast the raw API response body to an array with no runtime check. - When the endpoint returns a defined-but-non-array 200 body, the `?? []` fallback in each consumer doesn't catch it (the value isn't nullish), and the first `.find`/`.filter` call throws, crashing the whole page via `globalErrorBoundary`. - This is the same known class of bug already fixed elsewhere in the codebase (e.g. `apps/studio/data/lint/lint-query.ts`, and the `api-keys`/`oauthApps`/`secrets` fetchers) — applies the same `Array.isArray(data) ? data : EMPTY_ARR` guard. ## Evidence (Sentry, past week) - [SUPABASE-APP-KA2](https://supabase.sentry.io/issues/7722780387/) — `(m??[]).find is not a function` in `ActivityStats.tsx` (`branchesData.find`), full-page crash on `/dashboard/project/[ref]`. - [SUPABASE-APP-KAE](https://supabase.sentry.io/issues/7729679561/) — `u.filter is not a function` in `AWSPrivateLinkForm.tsx` (`databases.filter`), full-page crash on `/project/[ref]/settings/integrations`. ## Test plan - [ ] Existing query hook tests still pass - [ ] Manually verified `Array.isArray` guard mirrors the established `lint-query.ts` pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM --- _Generated by [Claude Code](https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Ali Waseem <waseema393@gmail.com> |
||
|
|
d439ba57f4 |
feat(studio): mask HTML attributes in session replay (#48818)
## 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? Hardening ahead of any decision to enable session replay, plus a dependency bump. Follow-up to #48515. ### What's inside - ~50 lines of logic: the callback, the `url()` pattern, and the theme and SVG-reference gates ([session-replay.ts](https://github.com/supabase/supabase/pull/48818/changes#diff-b7e4f10387ee7a116dd1673f70a55c0ba066687ff2d228bc2320eba75a349fac)) - ~170 lines of allowlist, one attribute name per line, skimmable ([same file](https://github.com/supabase/supabase/pull/48818/changes#diff-b7e4f10387ee7a116dd1673f70a55c0ba066687ff2d228bc2320eba75a349fac)) - ~150 lines of comments saying why each group is allowlisted, since a wrong entry is a privacy or a fidelity bug ([same file](https://github.com/supabase/supabase/pull/48818/changes#diff-b7e4f10387ee7a116dd1673f70a55c0ba066687ff2d228bc2320eba75a349fac)) - ~430 lines of tests, one case per policy decision ([session-replay.test.ts](https://github.com/supabase/supabase/pull/48818/changes#diff-f9feb872ad0136cf87c7e9fb2af72eb3f4019464c06f0b7dd050ffb85373ccb8)) - 1 line of dependency bump, plus its lockfile ([package.json](https://github.com/supabase/supabase/pull/48818/changes#diff-50d7c39a9430d37971aa76858165ab4f7921c4cc4340b28e9b673ce6982e63cf)) ## What is the current behavior? Session replay is disabled in every environment, and no recordings exist. This is about what a recording *would* contain if it were ever switched on. Attributes are the one channel replay masking cannot reach. `maskTextFn` only sees DOM text nodes, so a component interpolating customer data into a `placeholder`, `title` or `aria-label` would be captured verbatim. Before `posthog-js` 1.413.0 there was no hook for it at all, and the only mitigation was blocking the element, which drops it from the capture entirely. Two places in Studio where that would apply: - `CreateOrUpdateCustomProviderSheet.tsx:506-507` interpolates the project's API host into both `value` and `placeholder`. The `value` is masked. The `placeholder` is not. - `FileExplorerHeader.tsx:185` renders `Search in ${currentFolderName}...`, a customer storage folder name. The list is not complete. Any component echoing context into a tooltip reproduces it, and the author has no reason to be thinking about replay. Linear [GROWTH-1094](https://linear.app/supabase/issue/GROWTH-1094). Blocks [GROWTH-1073](https://linear.app/supabase/issue/GROWTH-1073). ## What is the new behavior? `maskAttributeFn` with a default-deny policy: an allowlist of the attributes replay needs to render, everything else masked. ### Policy edge cases - **rrweb's `rr_*` layout attributes have to be allowlisted explicitly.** posthog-js only applies its own exemption for those when `maskAllElementAttributes` does the masking. A callback does not get the exemption. - **HTML `id` is masked. SVG `id` passes.** `AreaChart.tsx:119` emits `<linearGradient id="colorUv">` and references it as `fill="url(#colorUv)"`, so masking it breaks the gradient. But Studio also binds customer-named values to `id` (`bucket.id` is a storage bucket name). Split on `element.namespaceURI`. - **SVG reference attributes pass only fragment-only targets.** recharts clips every series with `clip-path="url(#clipPath-<id>)"`, so `clip-path`, `mask`, `filter`, `marker-*`, `fill` and `stroke` have to survive. They accept external URLs too, so the policy checks the target rather than allowlisting the attribute name. - **The `url()` pattern consumes escaped delimiters and ignores case.** A target containing a quote serializes as `\"` and one containing a bracket as `\)`, so a naive `[^")]*` stops at the backslash and leaves the tail of the URL recorded. `URL(...)` is the same function as `url(...)`. A token the pattern cannot parse falls through to a masking fallback rather than passing. - **`url()` targets inside `style` are masked, keeping the declarations.** The feedback widget puts `toPng(document.body)`, a base64 PNG of the whole dashboard, into a `background-image`, and the storage preview panes put signed object URLs there. No other masking path covers those, because they are not text nodes, a canvas, a network request or an `img src`. The config also pins `maskAllElementAttributes: false`. Left unset it resolves from the PostHog UI, and `true` discards `maskAttributeFn` entirely. The `posthog-js` floor rises to `^1.416.1`, the first version carrying both attribute masking and the "coarse option wins" precedence. This does not enable recording anywhere. ## Additional context ### Verification Ran on the studio-staging preview against a live session: 817 seconds, 190 clicks, 82 keypresses. Staging has no server-side masking config, so everything masked came from this code. | Check | Result | |---|---| | Storage folder search placeholder | Asterisked. Pre-fix it read `Search in <folder>...` | | Custom auth provider sheet | Fully masked, including the callback URL field | | Canary folder name in event properties | 0 hits, with 51 events in the session as the control | | Console capture | `console_log_count: 0` despite the project having `capture_console_log_opt_in: true` | | Telemetry regression | None: `$pageview` x34, `$pageleave` x5, `$groupidentify` x4, `$identify` x1 | Recording was scoped to that one preview by an origin restriction plus a URL trigger. Both were reverted afterwards along with the project toggle. The policy has 175 unit tests. Separately, the config was bundled with esbuild and applied to a DOM reproducing Studio's serialized output (the AreaChart gradient, a recharts `clip-path`, a lucide icon, an inline `background-image`), and the chart, gradient fill and icon come out pixel-identical. ### Known fidelity costs - `img src` is masked, so images don't render in replay. Storage object URLs are signed customer content. - `ProviderIcon` renders its mark as `maskImage: url(<src>)` and `normalizeIconPath` accepts absolute URLs, so provider icons don't render either. ### Out of scope rrweb records `<style>` element text without calling either masking function, because its text-node serializer skips masking when the parent is `STYLE`. This PR does not reach that channel. Fixed separately in #50270 / [GROWTH-1229](https://linear.app/supabase/issue/GROWTH-1229). `captureJsonLd` also defaults on as of PostHog's 2026-08-30 defaults, which is a capture channel masking doesn't reach. Studio renders no `ld+json`, so it's inert there, and pinning it off was left out to keep this PR to its scope. ### The allowlist is the weak part The policy is default-deny over attribute *names*, so its surface is every attribute any shipped library emits, and that set grows with each dependency. A miss is also invisible to these tests, which assert what the function returns rather than whether some selector elsewhere still matches. Both failure directions are reachable that way: an attribute carrying customer data, and an attribute a stylesheet needs. [GROWTH-1232](https://linear.app/supabase/issue/GROWTH-1232) tracks the mechanism change: scope by namespace instead of by name, since 50 of the 159 entries exist only to serve SVG rendering, plus a conformance test that derives the expected set from the codebase so a new dependency fails CI rather than degrading a replay. Deliberately not done here, since rewriting the mechanism of a privacy control buys maintainability rather than correctness. |
||
|
|
32f17f994d |
fix(studio): key query chart series by position, not column name (#50270)
## 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. Hardening ahead of any decision to enable session replay. ### What's inside - ~47 lines of logic: positional series keys, the X-key collision guard, and the rewiring of rows, cumulative results and axis width ([QueryResultChart.tsx](https://github.com/supabase/supabase/pull/50270/changes#diff-dae994728613498678bcc06a3ea5176b36708e06b531cfc7eddae3e588fff528)) - ~123 lines of tests, one case per chart type, cumulative setting and edge case ([QueryResultChart.test.tsx](https://github.com/supabase/supabase/pull/50270/changes#diff-6e1c92ad725bac0324db4d079f3d0cd061b8f6e2aecdc21bcdc5969c90dc3c59)) ## What is the current behavior? Session replay is disabled in every environment, and no recordings exist. This is about what a recording *would* contain if it were ever switched on: charting a query result would put the customer's own column names into it. `ChartContainer` writes every chart config key into a `<style>` element as `--color-<key>`. rrweb records `<style>` text verbatim: ```js u = "STYLE" === parentTagName || void 0 h = "SCRIPT" === parentTagName || void 0 !u && !h && o && r && (o = maskTextFn ? maskTextFn(o, parent) : o.replace(/\S/g, "*")) ``` The `!u` guard means `maskTextFn` never sees stylesheet text. It is a text node, so `maskAttributeFn` does not see it either. CSS written into the DOM is a channel no masking hook reaches. `QueryResultChart` keyed its config by the column names picked for the Y axis, which come from the customer's own SQL results. With recording enabled, a query charting a column named `customer_email` would produce `--color-customer_email` in the captured DOM. Linear [GROWTH-1229](https://linear.app/supabase/issue/GROWTH-1229). #48818 masks the attribute channel. This channel is text, so that PR does not reach it. ## What is the new behavior? Y series are keyed by position (`series_0`, `series_1`), so no customer string reaches the config keys. The column name still goes through as `config[key].label`, which `chart.tsx` renders into the tooltip and legend as text. Text nodes outside `<style>` are masked by `maskReplayText`, so the name is safe there and the chart stays readable. The X column keeps its own name. Only config keys reach the `<style>` and the X column is never one, so renaming it would buy nothing, and it would cost the `timestamp` handling: `ChartBar` and `ChartLine` branch on `xKey === 'timestamp'` to format tooltip dates and render the date-range footer. Keeping the original name needs one guard, since an X column literally named `series_0` would share a row key with the first Y series. `xKeyFor` appends underscores until the two are distinct. ## Additional context ### Testing Eleven tests. They assert the rendered `<style>` contains `--color-series_0` and does not contain the column name, across both chart types and both cumulative settings, plus the two-series case, the `timestamp` column and the collision guard. Three are verified to catch the defect they cover: the style-key assertion fails against the unfixed component, the `timestamp` assertion fails when the X key is pinned to a constant, and the `xKeyFor` cases fail when the guard's body is removed. `vitest run components/interfaces/Explorer` passes: 170 tests across 16 files. The tooltip and legend path isn't asserted, because recharts doesn't render either one at the 0x0 size jsdom gives the container. That the label is what renders there comes from reading `chart.tsx`. It is unverified at runtime. ### Remaining exposure Every other `ChartContainer` caller passes literal keys (`--color-error`, `--color-ok_count`), and `UnifiedLogs` filters a static config by a fixed level set, so this was the only caller feeding it customer strings. `chart-bar.tsx:119-124` and `chart-line.tsx` still fall back to building a config from whatever `dataKeys` they're given, so a future caller can reintroduce this without touching `QueryResultChart`. A general guard would have to live in `ChartContainer` or in the replay config. CSSOM writes (`insertRule`, `replace`, `replaceSync`, adopted stylesheets) also emit CSS outside both masking hooks. This PR does not close that path. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved query result charts to preserve the source column name used for the X-axis. - Prevented X-axis names from conflicting with generated series identifiers. - Ensured bar and line charts consistently bind data to the correct X-axis and series. - Preserved timestamp-based chart behavior, including the date-range footer. - Chart series styling now uses stable positional identifiers, ensuring colors remain correctly assigned across configured series. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4aa34f556a |
feat(studio): mcp secrets interstitial polish (#50351)
## 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? - We made the Next step copy a bit more generic so it doesn't read like it's pointing you back to Inspector UI. - Added CTA on key stored screen to send you to Edge Function Secrets directly. - Tidies up footer area to always be centrally aligned across all states. ### 1. Enable the feature flag ### 2. Preview states via URL Mock mode is enabled automatically in local/staging. Navigate to `/mcp/secrets` with a `state` query param: http://localhost:8082/mcp/secrets?state=<state> States that need no other params: | `state` value | What it shows | | ----------------- | --------------------------------------- | | `loading` | Loading skeleton | | `expired` | Link expired | | `cancelled` | Request cancelled | | `paused` | Storing keys paused | | `wrong-account` | Signed in as the wrong account | | `error` | Generic failure | States that need a real project —ame=<KEY_NAME>`: | `state` value | What it sh | | -------------------- | ---------------------- | | `form` | The "st | | `stored` | Success | | `stored-timeout` | Successopped waiting | | `already-stored` | Key was already stored, nothing to do | Example: http://localhost:8082/mcp/secretsJECT_REF&name=OPENAI_API_KEY ### 3. What to check - [ ] `stored` / `already-stored`tions secrets"** button linking to `/project/<ref>/functions/secrets - [ ] States without a project re `paused`, `error`) don't show that button - [ ] Footer text is centered on - [ ] `wrong-account` → **Switch its footer is centered - [ ] The provider-dashboard link` state, use a `name` like`OPENAI_API_KEY` or `RESEND_API_Khint) is centered too <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a project-specific link to Edge Functions secrets from the MCP setup screen when a project is available. * Added a separator to distinguish the secrets link from the remaining setup guidance. * **Improvements** * Updated completion guidance to tell users to return to their agent and confirm the setup is finished. * Standardized interstitial footer content with centered guidance and consistent provider dashboard instructions. * **Tests** * Added coverage for displaying the project-specific secrets link and hiding it when no project is associated. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com> |
||
|
|
c9e035910d |
Add HA toggle to enabled features (#50344)
## Context As per PR title - flags the HA toggle in project creation form behind a flag in enabled-features Behaviour should be status quo for both staging and prod <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a high-availability option to the project creation flow for eligible accounts when the feature is enabled. * The option is available through controlled feature configuration. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5104754018 |
Fix types master (#50345)
## Context Just needed to adjust the API types import - the name likely changed somewhere `AnalyticsResponse` -> `AnalyticsResponse_Output` Verified the typecheck locally <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Updated analytics test typing to align with the current analytics response schema. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
35f2eeefcf |
fix(observability): replace egress chart with usage link FE-4310 (#49850)
## Problem The Network Traffic egress chart is derived from request logs and can substantially undercount billed traffic. Showing it beside diagnostic ingress data left customers with an untrustworthy egress number. ## Fix Remove the log-derived egress chart, retain ingress, and add a Billable egress callout that links to the selected organization’s Usage page. The callout is shown only on hosted Studio, where organization billing data is available. ## How to test - Open API, Storage, Auth, or PostgREST observability. - Confirm Network Traffic shows only the ingress chart. - Confirm the Billable egress callout links to the organization Usage page’s egress section. - Expected result: diagnostic traffic and billable usage are no longer presented as competing egress totals. - Automated checks: git diff --check and final code review passed. Focused lint could not run because missing dependencies require registry access, and DNS for registry.npmjs.org is unavailable. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Updates** * Clarified Network Traffic report tooltips to explain that ingress is measured from request logs. * Platform deployment reports now display ingress data only; egress charts are no longer shown. * Added a notice linking to the Usage page for billable egress details. * Applied the updated Network Traffic explanation consistently across API overview, storage, and shared report views. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d2ed60da27 |
fix(auth): migrate overview errors to clickhouse (#50174)
## Problem
Auth overview error tables call the legacy logs endpoint through
fetchLogs defaults, even with the ClickHouse migration enabled.
Success-rate cards also show zero when there are no requests and
misleading relative changes between small rates.
## Fix
Select matching BigQuery or ClickHouse queries with otelLegacyLogs,
separate caches by engine, and normalize numeric results.
Show No data for success rates without requests and omit comparisons
when either period has no requests. Show success-rate changes in
percentage points: 0% to 0.2% displays +0.2 pp. Omit undefined relative
changes from a zero baseline for activity and sign-up counts. Show
explicit errors for failed log requests, including error payloads
returned with HTTP 200, instead of empty tables.
## Validation
- Auth overview error tables compared against staging with matching
data.
- 84 focused tests passed across four suites, including 25 direct
formatter tests.
- 12 MSW integration tests exercise both endpoint/SQL pairs, HTTP and
embedded API failures, and rendered No data, genuine 0%, and +0.2 pp
states.
- Unit tests cover missing periods, zero requests, percentage-point and
relative changes, SQL structure, and numeric result parsing.
- Formatting and diff checks passed; code review found no actionable
issues.
- Full local lint/typecheck are limited by shared checkout dependencies.
Browser comparison confirmed the deployed rate display uses percentage
points and shows No data without a comparison for absent server
requests; populated error rows match staging. The final formatter
extraction (
|
||
|
|
38e8f12b1b |
fix(studio): gate homepage health advisor (#50328)
## Problem Health Advisor results appear on the project homepage whenever the main `healthAdvisor` flag is enabled, so the homepage cannot be rolled out separately. The existing gates also contain redundant boolean and platform checks. ## Fix Require both `healthAdvisor` and `healthAdvisorInHomepage` before fetching or displaying health advisories on the homepage. Simplify all Health Advisor gates to use the boolean ConfigCat flag directly, including the cleanup requested in the review of #50326. ## How to test - Enable only `healthAdvisor` and verify Health Advisor remains available outside the homepage while health results do not appear or load on the homepage. - Enable both flags and verify health results appear on the homepage. - Disable `healthAdvisor` and verify Health Advisor remains unavailable everywhere. - Existing targeted tests pass: 5 tests across Advisor menu and panel integration suites. - Prettier and whitespace checks pass. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Health Advisor is now available in non-platform environments when enabled. * Navigation, filtering, lint checks, and project pages consistently follow the Health Advisor feature setting. * Self-hosted environments can use the Health Advisor category. * **Bug Fixes** * Homepage Health Advisor visibility now follows both the Health Advisor and homepage-specific settings. * Updated empty states and health lint results to match the configured availability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
22d7bc0cfd |
feat(studio-evals): custom search_docs tool for the eval harness (no token / no PAT) (#50092)
- Eval harness's only live tool, `search_docs`, no longer needs the in-process MCP client or its dummy token — it now calls the public docs GraphQL API (`https://supabase.com/docs/api/graphql`) directly. Low risk as this is an eval-harness change only. Production assistant path (`mcp-tools.ts`) untouched. **Update:** per [@mattrossman's review](https://github.com/supabase/supabase/pull/50092#discussion_r3980396341), the eval tool's description embeds the Content API's own GraphQL schema (fetched via a `{ schema }` query and minified with `gqlmin`), mirroring how `@supabase/mcp-server-supabase`'s `docs-tools.ts`/`loadSchema` populates production's `search_docs` description. Without it, the model had no schema to work from and issued malformed queries, which caused the 218 `search_docs` errors and the -25pp Docs Faithfulness regression in the first eval run on this PR. Schema loading is required: `createSearchDocsTool()` rejects if the schema fetch fails, so preflight and the gated eval job fail loudly instead of producing untrustworthy fallback results. `createSearchDocsTool` is async because the `ai` package's `tool()` only accepts a plain string `description`, unlike the MCP SDK's async description support; both callers (`getMockTools`, `evals/preflight.ts`) await it. `gqlmin` is a direct `apps/studio` dependency and was already transitive via `@supabase/mcp-server-supabase`. ### Verification - `pnpm -C apps/studio exec -- tsc --noEmit` reaches the compiler; it reports only the pre-existing unrelated `packages/ui-patterns/src/McpUrlBuilder/components/InstructionBlocks.tsx` `StaticImageData` error. - `pnpm -C apps/studio exec -- vitest run lib/ai/tools/mock-tools.test.ts lib/ai/tools/mcp-tools.test.ts` — 21/21 passed. - `pnpm exec tsx evals/preflight.ts` — live docs API schema fetch and search_docs call passed. - `NEXT_PUBLIC_CONTENT_API_URL=http://127.0.0.1:1/graphql pnpm -C apps/studio exec -- tsx evals/preflight.ts` — failed fast as expected, proving schema/API failures gate evals. - Fresh `run-evals` pass: Docs Faithfulness 55.7% (0pp), with no systemic `search_docs` regression. Risk: eval-harness-only; schema/API outage now fails the eval job before scoring rather than allowing fallback descriptions. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added documentation search powered by the public Supabase documentation GraphQL API. * Documentation search results now include live schema information and clearer error handling for failed or invalid requests. * **Bug Fixes** * Improved evaluation tooling reliability by removing unnecessary connection-abort behavior. * Updated validation to detect missing search tools and malformed documentation responses. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
6f15081892 |
Scoped PAT: show dependencies between permissions (#50271)
## Problem Some permissions require others to actually have an effect, for instance: - `api_gateway_keys_secret_read` requires `api_gateway_keys_read` or `api_gateway_keys_write` - `data_api_config_secret_read` requires `data_api_config_read` or `data_api_config_write` This is not obvious from a user perspective. ## Solution We decided to make these requirements explicit by: - Adding a line in the permission item stating the dependency - Disabling the permission if its dependency isn't met - Resetting the permission if it was selected but the dependencies aren't met anymore ## How to test - On [staging](https://studio-staging-git-gildasgarcia-fe-4380-dashboa-b2a227-supabase.vercel.app/dashboard/account/tokens) - Create a new token - Check that _API Key Secrets_ is greyed out and disabled - Select _API Key_ read or read-write - _API Key Secrets_ shouldn't be greyed out and disabled - Select a value for _API Key Secrets_ - Set _API Key_ to none - Check that _API Key Secrets_ is greyed out, disabled and reset to none too <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added dependency-aware permissions for scoped access tokens. - Permission descriptions now show required dependencies and permission levels. - Dependent permissions automatically reset to “None” when requirements are not met. - Permission controls and unavailable selections reflect dependency requirements. - **Accessibility** - Screen readers now receive an announcement when a permission is reset to “None” due to unmet dependencies. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
519a3a5644 |
fix(studio): gate health advisor behind feature flag (#50326)
## Problem Health Advisor runs checks and displays health alerts without a dedicated rollout flag. ## Fix Gate Health Advisor behind the ConfigCat `healthAdvisor` flag, defaulting to off when missing or loading. This covers the navigation and shortcut, command menu, direct page access, homepage alerts, Advisor panel filters and details, and health-check requests. Cached health results and saved Health filters no longer surface health content when disabled. Existing platform-only restrictions remain. The `healthAdvisor` flag will be created separately in ConfigCat. ## How to test - With `healthAdvisor` off, verify Health Advisor is absent from navigation, command search, homepage alerts, and Advisor panel categories. Opening `/project/<ref>/advisors/health` shows an unavailable message. No health-check POST requests should run. - With the flag on for an active platform project, verify these surfaces return and health checks load. - Disable the flag after loading health results and selecting the Health filter or an alert. Verify cached health alerts disappear and the panel remains usable. - Existing menu tests pass. No new feature flag tests are included. Formatting and whitespace checks passed. - Local lint could not start because the available dependency installation is missing `@eslint/compat`. Full TypeScript validation failed with missing dependencies and incompatible workspace types in the reused local dependency installation; it did not provide a clean validation result. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Health Advisor availability is now controlled by a feature flag on the platform. * When enabled, health advisories appear in advisor menus, filters, project checks, and empty-state messaging. * When unavailable, the Health Advisor page clearly indicates that it isn’t available for the project. * **Bug Fixes** * Health advisory data is no longer requested when the feature is disabled, preventing unavailable health results and errors from appearing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9f7944a853 | fix(warehouse): add support for both db host and db host addr in catalog (#50261) | ||
|
|
fb22534439 |
fix: share sentry crash policy and enable www reporting (#50232)
## Problem The website initializes Sentry only on the server and edge runtimes, leaving browser crashes unreported. Its crash-reporting setup also needs the same consent and third-party filtering policy that docs and Studio otherwise maintain separately. ## Fix Add www browser initialization and tagged crash capture for both Next.js routers, with accessible fallback focus. Move the shared consent/platform and third-party filtering into common/sentry, reuse it from all three apps, and remove the duplicated docs/www helpers and tests. Preserve each app's initialization and Studio's additional noise filtering, sampling, and sanitization. Include the source-map upload token in www's build cache inputs, and trigger the shared/www and Studio test workflows when the shared policy changes. ## How to test - Run `pnpm --filter www test ../../packages/common/sentry.test.ts lib/sentry-capture.test.tsx`: all 22 shared-policy and real-SDK capture tests passed locally. - Run `pnpm --filter studio exec vitest run lib/sentry-client-options.test.ts`: all 42 Studio options and policy-parity tests passed locally. - The www capture tests exercise the actual initializer and both router handlers with an in-memory transport, verify crash tags and fallback focus, and enforce consent. Removing initialization, capture calls, boundary tags, or consent gating was verified to fail these tests. - On a www preview with its DSN configured, accept telemetry consent and trigger temporary render errors in both routers. Verify they reach the www Sentry project with the boundary tag and readable stack traces. Formatting passes. Full local app typechecks encounter existing dependency/generated-file drift, with no diagnostics in changed files. Three unchanged TanStack mock call-count tests fail locally and reproduce against the pre-refactor implementation. Live Sentry ingestion and source-map uploads remain deployment checks. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Accessibility** - Error pages now automatically move focus to a clearly labeled error message, helping screen-reader and keyboard users understand when a page fails. - **Reliability** - Browser error reporting now captures application crashes more consistently across supported page types and navigation transitions. - Reporting respects consent and platform availability while filtering unrelated third-party failures. - **Testing** - Expanded automated coverage for error capture, reporting rules, consent handling, and accessible error-page behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4dd8a95f0b |
feat(studio): polish Warehouse connection methods (#50246)
## What kind of change does this PR introduce? Feature polish and a connection behaviour change. ## What is the current behaviour? The Warehouse Connect sheet presents FlightSQL and DuckDB configuration together. Enabling Warehouse also enables DuckDB catalogue access automatically, even when the user only needs FlightSQL. ## What is the new behaviour? The Connect sheet now starts with a query engine selector: - FlightSQL shows the endpoint, connection string, user, password action, and command-line example. - DuckDB shows a persistent catalogue access switch. When enabled, credentials and the attach script appear as the same numbered "Follow these steps" flow used by other connection methods. - Switching back to FlightSQL removes the DuckDB instructions. > [!NOTE] > This is an incremental change towards [this UI](https://linear.app/supabase/project/warehouse-core-mvp-b85711dc2eff/activity#project-update-4e3183e1), where the Integrations page is the control plane and Connect sheet is simply for read-only connect values. https://github.com/supabase/supabase/pull/50247 and https://github.com/supabase/supabase/pull/50195 are subsequent PRs that get us there. > [!IMPORTANT] > Enabling Warehouse no longer enables DuckDB catalogue access automatically. DuckDB users must enable it explicitly from the connection details. FlightSQL is unaffected. This keeps global Warehouse provisioning separate from optional credentials for one query engine. It also prevents successful Warehouse setup from being followed by a secondary catalogue mutation that can fail independently. | Before | After | | --- | --- | | <img width="1280" height="1323" alt="10752" src="https://github.com/user-attachments/assets/83b1069b-a262-4068-a5e3-b7f49860fdb2" /> | <img width="1280" height="1323" alt="Regular AWS Teamer Supabase" src="https://github.com/user-attachments/assets/86ff1fe4-6513-44a8-88e1-1c7985f4910e" /> | | <img width="1280" height="1323" alt="10752" src="https://github.com/user-attachments/assets/83b1069b-a262-4068-a5e3-b7f49860fdb2" /> | <img width="1280" height="1323" alt="31254" src="https://github.com/user-attachments/assets/733f074d-a52a-44a6-8898-a8f3c2b68294" /> | | _Unable to replicate._ | <img width="1280" height="1323" alt="Regular AWS Teamer Supabase" src="https://github.com/user-attachments/assets/c7d4ee59-b3f0-48b0-a6d7-2202ef5c2609" /> | ## To test 1. Open `/project/{ref}?showConnect=true&connectTab=warehouse` on a project. Enable Warehouse on 1+ table. 2. Confirm FlightSQL is selected initially and its connection fields are visible. 3. Select DuckDB and confirm the catalogue switch is always visible. 4. Enable catalogue access and confirm the environment variables and SQL appear below in two numbered steps. 5. Switch back to FlightSQL and confirm the DuckDB steps disappear. 6. Set up Warehouse on a project where it is not yet enabled and confirm DuckDB catalogue access is not enabled automatically. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a query-engine selector for FlightSQL and DuckDB connection setups. * Added guided DuckDB setup steps, copy-to-clipboard support, and reveal/hide controls for secrets. * Added a catalog access toggle with confirmation feedback. * Catalog details load only when DuckDB is selected. * **Updates** * Streamlined warehouse connection layouts with consistent spacing. * Catalog access is now controlled separately from the initial warehouse setup. * Excluded sensitive setup details from copied prompts and added copy-status announcements. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
ffc76c1e36 |
feat(studio): give replication destinations a brand mark (#50251)
## What kind of change does this PR introduce? Studio UI polish. This is the first PR in the Pipelines review stack and targets `master`. Resolves DEPR-674. ## What is the current behaviour? Replication destinations use generic line icons across the destination picker, pipelines list, and replication diagram. The existing shared ClickHouse and Snowflake assets also use older artwork. ## What is the new behaviour? Adds a reusable `DestinationLogo` treatment and uses it consistently across Replication surfaces. BigQuery, ClickHouse, DuckLake, and Snowflake now use their colour brand marks, while destinations without a dedicated asset retain their existing line icon in the same frame. The refreshed ClickHouse and Snowflake artwork replaces the canonical shared assets, so existing consumers such as the Wrappers catalogue receive the updated marks too. | Light | Dark | | --- | --- | | <img width="572" height="804" alt="CleanShot 2026-09-11 at 16 48 42@2x" src="https://github.com/user-attachments/assets/5c2eaef3-8714-4c0a-8bcc-7c8618abd677" /> | <img width="552" height="788" alt="CleanShot 2026-09-11 at 16 47 30@2x" src="https://github.com/user-attachments/assets/2aff8775-cdc1-4d6b-9f78-7b40d42e102a" /> | | Add Pipeline form | | --- | | <img width="1252" height="730" alt="CleanShot 2026-09-11 at 16 48 57@2x" src="https://github.com/user-attachments/assets/025a158c-57ee-495e-8356-00ed1717d09d" /> | ## To test 1. Open `/project/<ref>/database/replication` and start adding a pipeline. 2. Confirm the BigQuery, ClickHouse, DuckLake, and Snowflake marks appear consistently in the destination picker, pipelines list, and replication diagram. 3. Open the ClickHouse and Snowflake entries in the Wrappers catalogue and confirm they use the refreshed artwork. 4. Confirm Analytics Bucket retains its existing fallback icon within the same frame. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Visual Updates** * Destination logos now display dedicated brand marks for ClickHouse, DuckLake, Snowflake, and BigQuery. * Updated replication destination selectors, rows, and diagrams to use consistent destination logos. * Adjusted the destination type column width for improved layout. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
15a7b0ab18 |
docs(database): correct the dashboard_user and storage admin role descriptions (#50274)
Closes DOCS-1387 ## Problem The Postgres roles guide describes `dashboard_user` as "For running commands via the Supabase UI." That was the original intent, not current behavior. Dashboard queries run as `postgres` and carry a `-- source: dashboard` comment, which the [Postgres logs troubleshooting guide](https://supabase.com/docs/guides/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj) already documents. The two pages contradict each other. Two smaller problems in the same list: - `supabase_storage_admin` is described as an Auth middleware role, copied from the `supabase_auth_admin` entry above it. - Studio ships both stale strings in its own role tooltips. The docs list and `QUERY_PERFORMANCE_ROLE_DESCRIPTION` are near-verbatim copies of each other. ## Solution - Replace the `dashboard_user` description with what the Dashboard connects as instead, and point readers to the `-- source: dashboard` comment for finding Dashboard queries in the logs. - Attribute `supabase_storage_admin` to the Storage middleware. - Apply both corrections to the Query Performance and Query Insights role tooltips. ## Manual testing 1. Open the [roles guide on the deploy preview](https://docs-git-docs-dashboard-user-role-supabase.vercel.app/docs/guides/database/postgres/roles). 2. Scroll to `dashboard_user`. It states that the Dashboard doesn't connect as the role, and that Dashboard queries execute as `postgres` with a `-- source: dashboard` comment. 3. Select **find them in the Postgres logs**. The Postgres logs troubleshooting guide loads. 4. Scroll to `supabase_storage_admin`. It reads "Used by the Storage middleware," not "Auth middleware." 5. In Studio, open **Observability > Query Performance** and hover a `dashboard_user` or `supabase_storage_admin` value in the **Role** column. The tooltip shows the same two corrected descriptions. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Corrected the description of the `supabase_storage_admin` role to reference Storage middleware. - Clarified that the Dashboard does not connect using the `dashboard_user` role. - Documented that Dashboard queries run as `postgres` and can be identified in Postgres logs with a `source: dashboard` comment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ea203f70df |
fix(studio): use configured gp3 max-IOPS ceiling (#50269)
## Summary * GP3 IOPS calculation was hardcoded to 16,000 instead of reading from DISK_LIMITS config * AWS updated the real ceiling to 80,000, making the hardcoded constant stale * Users with large multi-TB GP3 disks were incorrectly blocked from provisioning above 16,000 IOPS ## Test plan - [X] Updated unit tests for `calculateMaxIopsAllowedForDiskSizeWithGp3` now assert correct behavior: scaling linearly (100 GB → 50,000 IOPS) and capping at new 80,000 ceiling (1000 GB → 80,000 IOPS) - [X] All 26 tests in DiskManagement.test.ts pass locally - [X] Manually verify Infrastructure Settings > Disk IOPS field no longer blocks GP3 disks above 16,000 IOPS up to 80,000 Closes [FE-4379](https://linear.app/supabase/issue/FE-4379/update-iops-limits-for-new-aws-disk-capacity) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Updated GP3 disk performance calculations to support up to 80,000 IOPS. - Disk sizes below the minimum threshold continue to receive the correct 3,000 IOPS floor. - Larger disks now scale linearly until reaching the updated maximum IOPS limit. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
66c6da82fe |
fix(studio): refine Explorer query surfaces and tab styling (#50249)
Explorer query surfaces now use `bg-card` in light mode and `bg-muted` in dark mode, including embedded notebook/chat queries and query tab toolbars. Notebook Run buttons match query tabs, with `ml-1` spacing on both. Fix doubled tab separators by applying the leading border only to the first tab. ### How to test 1. Open Explorer with multiple query, notebook, and chat tabs. Switch, reorder, and close tabs; confirm each separator stays one pixel wide. 2. In light and dark mode, inspect query tabs and embedded notebook/chat queries: backgrounds should be card in light mode and muted in dark mode, including their toolbars. 3. Compare notebook and query Run buttons: matching default styling and spacing. Run a read-only query such as `select 1` in both and check loading and results. 4. Check SQL Editor and Table Editor tab separators, since the tab component is shared. Validation: Prettier passed for all four changed files. Manual checks above have not been run. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Style** - Refined notebook and query run button styling, including spacing and tooltip placement. - Improved query editor panel backgrounds across light and dark themes. - Updated tab border rendering for more consistent visual alignment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2bd67ef91b |
Chore/team members rendering optimizations (#50255)
## Context Follow up to https://github.com/supabase/supabase/pull/50238 which addressed some rendering issues for organization team settings. The changes in 50238 improved the performance of searching members, but there's still a bit of client side latency. There shouldn't be any functional changes from the changes here, just refactoring - `MemberRow` wrapped in `memo` so unaffected rows skip re-rendering - Memoized a number of variables in `MembersView` so they only recompute when filtered members/user/role actually change, not on every render - In `MemberRow`, replaced per-role `.find()` chains with Map-based lookups and memoized the whole per-role derivation - Fixed a mutating in-place `.sort()` in `organization-roles-query.ts`'s select that was silently rewriting the shared RQ cache entry - Added `TeamSettingsDataContext` + reduce prop drilling for `MemberRow` + `MemberActions` - Removed an any cast on member.metadata?.origin in MemberRow, replaced with explicit Boolean(...) coercion Organization team settings page should work as per status quo including searching. The searching was the main issue so these are hoping to alleviate the performance issues. It's quite hard to test unless you've got an organization with a 150 + members though (< 100 you don't really see any issues). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Improvements** - Improved the Team Settings member list for more consistent role and project information. - Member role links now provide more direct navigation to associated projects. - Improved performance when displaying and sorting team members. - Added an accessible label to the member actions menu. - **Bug Fixes** - Prevented organization role data from being unexpectedly changed while it is sorted. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
476d4a5851 |
refactor(ui): drop redundant Button variant="default" props (#50161)
## What kind of change does this PR introduce? Mechanical cleanup on top of the Button default-variant change (#50160). ## What is the current behavior? Many callsites still pass `variant="default"` even though that is now the component default. ## What is the new behavior? Removes redundant static `variant="default"` from legacy `Button` and `ButtonTooltip` callsites. Keeps explicit defaults where they document the API: - `button-default.tsx` and `button-sizes.tsx` demos - `DocsButton`, which pins neutral styling at the wrapper boundary ## To test Studio: - [Auth → Rate Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits): dirty the form so Cancel appears; Cancel stays neutral, Save stays green - [Project Settings → API Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys): `DocsButton` in the header actions stays neutral Design system: - [Design system → Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button): `button-default` / `button-sizes` still show explicit default styling; Primary (green) is restricted to the Primary section (and `asChild`) WWW: - [www → Brand assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets): Download logo kit / Download button kit stay neutral |
||
|
|
82d7d347c4 |
fix(studio): eliminate per-row query duplication on org team page (#50238)
## Summary * Fixes extreme slowness (browser-crashing on filter) on `/org/[slug]/team` for orgs with 200+ members. * Root cause: `MemberRow`/`MemberActions` each independently subscribed to org-wide React Query data (roles, projects, permissions, feature flags) and rendered a hidden `UpdateRolesPanel` per row. Filtering caused hundreds of duplicate query observers to mount/unmount on every keystroke, each scheduling its own stale-timeout bookkeeping and blocking the main thread for multiple seconds. * Hoisted all org-wide data fetching (`useOrganizationRolesV2Query`, `useOrgProjectsInfiniteQuery`, `usePermissionsQuery`, `useSelectedOrganizationQuery`, `useIsFeatureEnabled`) to `MembersView` and passed the results down as props. * Replaced the per-row `useAsyncCheckPermissions` hook calls in `MemberActions` with the underlying pure `doPermissionsCheck` function memoized locally, removing their internal query subscriptions. * Simplified `useGetRolesManagementPermissions` to stop calling a query-fetching fallback hook that was unreachable given all current call sites already pass `permissions`/`orgSlug` directly. * Replaced 200 hidden per-row `UpdateRolesPanel` instances with a single shared instance owned by `MembersView`, opened via an `onManageAccess` callback. * Cached the regex built by `doPermissionsCheck`'s `toRegexpString` instead of rebuilding it on every permission check. Diagnosed from two Chrome performance traces of the team page while typing in the filter box (multi-second main-thread blocking tasks traced to React Query `QueryObserver` mount/unmount storms). ## Test plan - [X] `tsc --noEmit` clean (only one pre-existing, unrelated error in `packages/ui-patterns`) - [X] `eslint` clean on all changed files (only pre-existing warnings) - [X] `vitest run tests/components/Organization/TeamSettings` — 51 tests pass - [X] Manually verify filtering is smooth on an org with 200+ members <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Team Settings provides centralized member access and role management. * Members can update roles through the access-management panel. * **Improvements** * Permission checks now more accurately handle organization and project scopes, including wildcard patterns. * Member search is debounced for smoother filtering while typing. * Access-management actions use current organization members, roles, permissions, and feature settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
9b1dddde11 |
Scoped PAT: add api_gateway_keys_secret_read and data_api_config_secret_read permissions (#50134)
## What kind of change does this PR introduce? Surface the new scoped personal access token permissions published in `@supabase/shared-types` 0.1.95 (added by https://github.com/supabase/platform/pull/38060, now deployed). **Stacked on #50234**, which regenerates the Management API types so Studio's scope type includes the new ids. This PR targets that branch and will retarget to `master` when it merges. ## What's in here - Bump `@supabase/shared-types` to 0.1.95 (Studio and shared-data). - Catalog entries in `packages/shared-data/scoped-access-token-permissions.ts`: - **API Key Secrets** (`api_gateway_keys_secret_read`): gates `?reveal=true` on the API keys endpoints. Renamed from "JWT secret", which described the wrong thing. - **Data API JWT Secret** (`data_api_config_secret_read`): gates the `jwt_secret` field on the PostgREST config endpoint. - **Compute** (`workers_read` / `workers_write`): shared-types 0.1.95 also publishes the workers scopes, so they surface in the catalog now. Named to match Studio's product naming (#50208). - Minimum roles for the four new ids in `FGA_SCOPE_MINIMUM_ROLE`, transcribed from the OpenFGA model (secret reads: developer; workers read: readonly; workers write: developer). - Docs generator (`generateAccessControlPartials.mts`): - Drop the workers exclusion now that the scopes are live. - When an endpoint lists alternative permission sets (for example API keys read alone, or read plus secret read for reveal), a row's footnote now only considers the alternatives that include that row's own scope. Previously the API Key Secrets row would have said "Requires API Keys (Read), or API Keys (Read) and API Key Secrets (Read)". - Regenerated PAT guide tables. The committed Management API specs predate the secret scopes, so this also includes the same spec refresh the weekly docs bot performs (`chore(docs): refresh the Management API specs`, kept as its own commit). Besides the new rows it picks up two new upstream endpoints under Advisors and the branch rows. ## Verified - `pnpm --filter studio typecheck` clean on top of #50234. - Access token test suite passes, including the guard that the role table covers exactly the ids shared-types publishes. - Partial regeneration is idempotent, so the Docs Tests stale-table gate passes. ## Follow-ups (not in this PR) - `apps/docs/content/guides/getting-started/api-keys.mdx` says a fine-grained token needs `api_gateway_keys_read` for the `?reveal=true` example. It now also needs `api_gateway_keys_secret_read`. - `project:api_gateway_keys` still says "Read exposes API keys" in its risk reason, which overstates it now that secret values sit behind a separate scope. Rewording may mean revisiting its risk level. - The comment in `ComputeLayout.tsx` about shared-types not exposing `workers_read` is stale. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added permission support for API key secrets, Data API JWT secrets, and compute workers. * Added API endpoints to run project advisors and create branches. * Added support for additional log-drain destinations, including S3, Last9, and OTLP. * Added storage object versioning information to project configuration responses. * **Documentation** * Updated access-control documentation for new permissions, worker operations, advisor runs, and branch creation. * Clarified Data API configuration and secret descriptions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
737b8595f2 |
Update API types (#50234)
## Problem platform, v1 and v2 have been already completely migrated and introduced some changes. Some types have been renamed, some outputs and inputs updated. ## Solution - Update the API types - Fix the TS errors ## Update Taking this over to unblock #50134, which needs the new scoped token permission ids from the regenerated types. - Merged `master`. - Regenerated `api-v2.d.ts` from the production spec. The previous files came from a local API that exposed a webhook events endpoint production doesn't have yet. Production has since added standardized 400 error responses on the v2 organization endpoints. `api-v1.d.ts` and `platform.d.ts` already matched production. - Fixed `verify-production-types`. It formatted the regenerated files in a temp directory outside the repository, so Prettier fell back to its defaults and the comparison could never match the committed files. It now passes the repository config explicitly. `pnpm api:verify-types` passes on this branch. - Verified locally: `pnpm typecheck`, `pnpm api:verify-types`, Studio unit tests. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Preserved descriptions when saving, sharing, moving, or unsharing notebooks, reports, SQL snippets, and saved queries. * Improved handling of empty or null values across notebook descriptions, billing usage, pooler settings, and infrastructure fields. * Improved read-replica connection handling, including read-only connection strings. * Updated storage configuration and capability handling to match current settings. * **API and Compatibility** * Updated organization, project, storage, OAuth, billing, and infrastructure data handling to match current API responses. * OAuth app creation and updates now require scopes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
8ac64a4349 |
Add copy notebook as markdown action (#50200)
## Context Adds a "Copy as Markdown" CTA for notebooks <img width="265" height="198" alt="image" src="https://github.com/user-attachments/assets/5eccf36e-24ea-4d2f-b1cf-72d5353b70a2" /> Query cell titles will be rendered as h3 tags and labelled either Postgres or Logs - Clickhouse (with time range) The query content will then be rendered as triple backticks with `sql` e.g ` ```sql...``` ` Query results will be copied to markdown if the query has been run, will otherwise be omitted Also, if the query was updated (e.g content, source, etc) after it was run (as the result is hence stale), result will also be omitted e.g: | Notebook | Markdown | | --- | --- | | <img width="1291" height="630" alt="image" src="https://github.com/user-attachments/assets/c49f23e5-c70b-46dd-a298-6e1a90cd30d7" /> | <img width="731" height="536" alt="image" src="https://github.com/user-attachments/assets/4bbe3041-bd8e-42d3-86d2-1691e7a6bc7b" /> | | <img width="1220" height="832" alt="image" src="https://github.com/user-attachments/assets/67de523a-18f7-4f1b-b764-7f0f3152f9e7" /> | <img width="757" height="803" alt="image" src="https://github.com/user-attachments/assets/d217504b-bee6-4088-9049-87ff647b9bc7" /> | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Markdown export for notebook queries, results, errors, and time ranges. * Added error notifications when copying notebook content fails. * **Bug Fixes** * Prevented stale query results after relevant source or time-range changes. * Improved Markdown export for queries containing backticks. * Escaped backslashes, pipes, and line breaks in Markdown tables. * **Style** * Adjusted spacing for empty query-result messages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7c681da0d2 |
Explorer home to run query in query tab if input in chat form is a sql query (#50204)
### Context As per PR title - figured this might be a nice convenience. Submitting a SQL query in the chat form on the explorer home page will open the query in a query tab and run it <img width="854" height="632" alt="image" src="https://github.com/user-attachments/assets/57dc7538-74b5-4801-a7ed-83c1cfaf123f" /> <img width="872" height="519" alt="image" src="https://github.com/user-attachments/assets/597ce0eb-76d4-4f12-83db-20b628c03904" /> ### To test - [ ] Run a couple of SQL statements in the home tab - should open it in query tab and run it - [ ] Run a couple of non-SQL statements in the home tab, should default to opening in a chat tab <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - SQL statements submitted from the Explorer home screen now open in a query tab and run automatically. - Natural-language prompts continue to open in the chat experience. - Queries restored from drafts can automatically run once the editor is ready. - **Bug Fixes** - Improved recognition of SQL with leading whitespace, comments, and common statement formats while avoiding misclassification of conversational prompts. - Draft-based auto-run behavior now waits until the query editor is ready. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
103051a149 |
Add role impersonation check for CSV imports (#50213)
### Context Resolves [https://github.com/supabase/supabase/issues/28820](<https://github.com/supabase/supabase/issues/28820>) CSV imports via the table editor is currently missing the role impersonation check. Assuming you've got a table that has a column which references `auth.users` + default values to `auth.uid() + not nullable` (e.g `user_id`), if you try to manually add a row while impersonating a user and leaving the `user_id` input field NULL, the newly inserted row will default to the user ID of the impersonated user <img src="https://github.com/user-attachments/assets/f6eb7e24-50e4-42aa-b6e6-64c50e195be7 " alt="image" width="685" data-linear-height="255" /> However, because CSV imports are missing the role impersonation check, importing data with a CSV that has null values for `user_id` column will throw a NOT NULL postgres error. PR here adds the role impersonation check and resolves ^ this particular behaviour ### To test - [X] Create a table that references the `auth.users` table ``` create table public.empty ( id uuid primary key default gen_random_uuid(), user_id uuid not null references auth.users(id) on delete cascade default auth.uid(), note text ); ``` - [ ] Import data via CSV via the table editor using this CSV while impersonating a user [empty_test_import_no_user_id.csv](<https://github.com/user-attachments/files/32053194/empty_test_import_no_user_id.csv>) - [ ] Should pass without any errors, inserted rows should have `user_id` filled as the impersonated user's ID * Can also verify first on staging that doing this will throw a not null error ## Summary by CodeRabbit * **Bug Fixes** * Spreadsheet imports in the table editor now respect the currently selected role-impersonation state, ensuring imported rows are processed with the appropriate permissions. * Manually inserted or pasted rows now use the active role-impersonation settings, providing consistent permission handling across table editing workflows. |
||
|
|
e57aae3c83 |
feat(design-system): document disabled controls and add focusableWhenDisabled (#50068)
## What kind of change does this PR introduce? Docs update, with supporting `ui` and Studio changes. ## What is the current behaviour? Disabled buttons with tooltips use native `disabled`, which removes them from the tab order. Keyboard users cannot focus the control or read the tooltip explaining why an action is blocked. The design system also lacked guidance on keeping disabled actions discoverable and explaining why they are unavailable. ## What is the new behaviour? - Adds a **Disabled controls** section to the accessibility docs, with live examples for a focusable disabled button and visible page-level context - Adds `focusableWhenDisabled` to `Button`, keeping `disabled` as the semantic state while using `aria-disabled`, retaining keyboard focus, and guarding click handlers - Updates Studio's `ButtonTooltip` to make disabled buttons with tooltip text focusable automatically Also includes earlier design-system fixes on this branch: - Centralises `BASE_PATH` with a `/design-system` fallback so asset URLs work without a local `.env` file - Fixes sidebar hover and active tokens in design-system and ui-library, aligned with Studio's `InnerSideMenuItem` ## To test **Design system** 1. Open the [accessibility preview](https://design-system-git-fix-design-system-docs-and-nav-fixes-supabase.vercel.app/design-system/docs/accessibility) 2. Scroll to **Disabled controls** 3. Tab to the **disabled-focusable** example. Confirm the button remains focusable, looks disabled, and shows its tooltip on focus 4. Confirm the **disabled-unavailable-with-notice** example shows the admonition and focusable disabled button pattern **Studio (optional, requires a High Availability project)** 5. Go to Settings → General → **Pause project**. Tab to the button and confirm it remains focusable, looks disabled, and shows the HA tooltip on focus 6. Go to Database → Backups and find **Restore** on a scheduled backup row. Confirm the same behaviour |
||
|
|
3c3daf8f10 | fix(warehouse): avoid confusion in tests containing fake credentials, make it more obvious it's fake (#50207) | ||
|
|
d513d013c5 |
chore(studio): poll state to keep ui in sync (#50216)
Poll compute data to keep ui in sync - every 3s when state is transitioning - every 10s when idle ## To test - open compute - deploy compute instance via cli - check ui updates automatically while state changes (new -> active -> deleting -> removal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Compute data now refreshes automatically, with faster updates while instances are building or being deleted. * Added clearer manual refresh feedback in the compute interface. * **Improvements** * Improved compute table layout with fixed column sizing and truncated long instance names. * Region and resource columns remain responsive while maintaining consistent widths. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9a9228a9f8 |
Assistant panel maximize CTA to open in explorer only if explorer preview is enabled (#50203)
### Context As per PR title - currently the assistant panel's maximize CTA defaults to opening in explorer, which might be confusing for users who don't have the explorer feature preview enabled <img width="581" height="190" alt="image" src="https://github.com/user-attachments/assets/9a9b6129-164e-4e3e-a14e-66ecafe8e5ff" /> <img width="574" height="157" alt="image" src="https://github.com/user-attachments/assets/ffff0a49-3357-4e5f-8cc0-be2f94263128" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Updated the AI assistant’s maximize control with context-sensitive actions. * When Explorer preview is enabled, the control opens the active conversation in Explorer. * When Explorer preview is disabled, the control maximizes or minimizes the assistant panel. * Updated the control’s label, accessibility text, and keyboard shortcut to reflect the available action. * Maximized AI Assistant panels now use the full available width, while other sidebars retain responsive sizing. * **Bug Fixes** * Improved sidebar behavior on mobile and overlay layouts to prevent unwanted resizing or collapsing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0bf22ee6fc |
chore(studio): update product naming (#50208)
workers -> compute <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added the Compute experience for deploying, viewing, managing, and monitoring compute instances. - Added Compute navigation, instance detail pages, secrets, logs, deployment dialogs, generated snippets, and CLI commands. - Added filtering, status, availability, and data-loading support for compute instances. - **Updates** - Updated labels, icons, links, feature controls, unified logs, and secret-deletion messaging to use Compute terminology. - Compute routes now replace the previous Workers routes and pages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3635ab15ff |
Standardize icon for maximise in editor panel (#50210)
### Context Just a tiny UI nit to standardise the maximise icon in Editor Panel, matching that of the Assistant Panel <img width="443" height="138" alt="image" src="https://github.com/user-attachments/assets/b1827b86-03c0-4312-b7b2-c6e2f5761a96" /> <img width="438" height="147" alt="image" src="https://github.com/user-attachments/assets/fc33d4d5-931d-49bd-b46d-d39e45860c52" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Style** - Updated the maximize control icon for a clearer visual representation. - **Accessibility** - Updated the control label and tooltip to say “Open in SQL editor” for improved clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0bebe50a76 |
fix(studio): serialize SQL folder deletion IDs (#50223)
## Summary * serialize SQL folder IDs as the comma-delimited API query value * add regression coverage for the folder deletion request ## Testing * `pnpm --filter studio exec vitest run data/content/sql-folders-delete-mutation.test.ts` * `pnpm exec prettier --check apps/studio/data/content/sql-folders-delete-mutation.ts apps/studio/data/content/sql-folders-delete-mutation.test.ts` * `pnpm --filter studio exec eslint data/content/sql-folders-delete-mutation.ts data/content/sql-folders-delete-mutation.test.ts` * `pnpm --filter studio exec tsc --noEmit --pretty false` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed SQL snippet folder deletion requests so multiple selected folders are processed correctly. * Improved request handling by formatting folder identifiers consistently when submitting bulk deletions. * **Tests** * Added coverage to verify that deleting multiple SQL snippet folders sends the expected folder identifiers. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1966209483 |
chore(deps): upgrade vitest to v5 (#49994)
Upgrades Vitest from 4.1.4 to 5.0.0 across the monorepo, fixes the handful of things v5 turned into hard errors, and drops the `vi.clearAllMocks()` boilerplate that v5's `clearMocks` default makes redundant. **Changed:** - `vitest`, `@vitest/ui`, `@vitest/coverage-v8` 4.1.4 → 5.0.0 (catalog) - `vi.mock` calls that lived inside `beforeAll`/`beforeEach`/test bodies moved to module scope (v5 throws on nested calls). Affects the Studio and docs setup files and four Studio tests. - `detectBrowser` test restores `navigator` via `vi.unstubAllGlobals()` instead of assigning `global.navigator`, which now reaches jsdom's getter-only property. - `RowEditor.utils.test.ts` restores its `JSON.stringify` spy. It used to leak a throwing mock for the rest of the file, which v5's coverage provider now trips over. A later test in the same file had been asserting the leak's side effect (valid JSON reported as invalid) and now asserts the correct behavior. - `@testing-library/jest-dom` 6.6 → 7.0.1. Its vitest type augmentation resolves through a peer now, so it lands on each package's own `vitest` instead of whichever copy pnpm hoisted. Fixes `toBeInTheDocument` type errors in dev-tools after the reshuffle. - `@testing-library/react` 16.0.0 → 16.3.3 for the React 19 peer range. - `vite: catalog:` added to dev-tools, www, and common. Without it they resolved a newer vite than the catalog pin, which forked a second vitest instance in the lockfile. There's now one. - ai-commands custom matcher types use v5's `Matchers<R, T>` form. - 110 test files: `vi.clearAllMocks()` removed from `beforeEach`/`afterEach` hooks, along with hooks that only did that and the imports they left unused. Calls that also reset/restore mocks are untouched. Second commit, mechanical. **Added:** - `.vitest/` to the root gitignore (v5 writes JSON/JUnit/HTML reporter output there) **Removed:** - `vite-tsconfig-paths` catalog entry and deps. Vitest 5 resolves tsconfig paths itself. Release-age note: this sat in draft with a temporary `minimumReleaseAgeExclude` entry for `vitest` and `@vitest/*` while 5.0.0 was inside the workspace's 3-day `minimumReleaseAge` window. That window has closed, so the exclusion is gone and nothing bypasses the release-age gate. **Perf** (local, medians of 3 runs, same machine): | Suite | v4.1.4 | v5.0.0 | |---|---|---| | studio | 144.1s | 141.7s (-2%) | | studio `--coverage` | 156.9s | 146.4s (-7%) | | ui-patterns | 6.27s | 5.07s (-19%) | | ui `--coverage` | 3.35s | 2.14s (-36%) | | www | 0.89s | 0.47s (-47%) | Studio is dominated by jsdom environment setup per file, which v5 doesn't change. `vitest doctor` recommends keeping the current pool config: the vm pools and `isolate: false` all break tests. ## To test - `pnpm install --frozen-lockfile` succeeds with no `minimumReleaseAgeExclude` entry for vitest. - CI: Studio unit tests, ui, ui-patterns, www, docs, and typecheck/lint should all be green. The lint ratchet was checked locally: warning counts on touched Studio files are identical to master. - `pnpm test:studio` locally passes with coverage (588 files, 6240 tests). - Open a Studio test that uses `toBeInTheDocument` in your editor and confirm no type errors on jest-dom matchers, in Studio and in `packages/dev-tools`. - Known pre-existing failures unrelated to this PR: one dev-tools test (`getEventCountBadge` capped pill) fails on master too. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Tests - Improved test coverage for JSON validation and mobile navigation behavior. - Updated test setup, cleanup, environment configuration, and matcher support across application and shared package suites. - Removed obsolete coverage for alternate MCP transport selection. ## Chores - Streamlined TypeScript path resolution and Vitest reporter output handling. - Updated testing libraries and Vitest tooling across documentation, Studio, website, and shared packages. - Added Vitest reporter output to ignored files. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com> |
||
|
|
d9742d707f |
chore(studio): refine Explorer sidebar breadcrumbs (#50188)
Moves Explorer’s back navigation and create actions into a reusable sidebar breadcrumb header. Reduces product-menu headings globally to `text-sm` and keeps breadcrumb links free of padding, borders, and backgrounds. ### How to test 1. Open `/project/<ref>/explorer` and confirm the header shows Explorer and the SQL Editor switch action. 2. Open Notebooks and Chats. Confirm the header shows `Explorer > Notebooks/Chats` and the corresponding create action works. 3. Return using the Explorer breadcrumb with a click or Tab + Enter. Check that the label stays aligned and has no hover background. 4. Open another product, such as Database, and confirm its sidebar heading uses the smaller font size. 5. At a mobile viewport, open the menu and repeat the notebook/chat actions and back navigation without closing the sheet. Confirm the header stays current and disappears when returning to the main menu or opening another product. Validation: 18 focused tests, typecheck, formatting, and lint ratchet passed. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a shared Explorer sidebar header with breadcrumbs and contextual actions for creating notebooks and chats. - Added keyboard-accessible navigation between the Explorer overview and notebook or chat sections. - Added support for customized product menu headers across project layouts. - **Improvements** - Centralized Explorer navigation and actions in the shared sidebar layout. - Improved mobile menu updates when navigating between Explorer resources. - Refined Explorer home layout and drag-handle behavior across screen sizes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
c33d255eba |
chore(studio): refine assistant empty states (#50191)
<img width="1062" height="712" alt="image" src="https://github.com/user-attachments/assets/44c82e00-94b4-405a-b2ef-cbc08401c4db" /> <img width="1583" height="962" alt="image" src="https://github.com/user-attachments/assets/b19b9fd8-24b1-48d6-8b31-11fba9911b9a" /> ## What kind of change does this PR introduce? UI refinement. ## What is the current behavior? The assistant sidebar and Explorer chat use different empty states. ## What is the new behavior? Share a centered empty state with chat-focused prompts, use-case icons, and a “Use your own agent” footer. Simplify prompt cards and align Explorer Home styling. ## Additional context Studio typecheck, targeted ESLint, and Prettier pass. E2E selectors updated; browser verification pending. Local build stopped after showing no progress during compilation. I have read CONTRIBUTING.md. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Redesigned Explorer and AI Assistant onboarding with project-focused chat prompts. * Added personalized chat template icons and updated suggested actions. * Added an option to connect and use an external agent through Claude, OpenAI, or Cursor. * Improved chat composer placement and empty-chat guidance. * **Style** * Action cards now support layouts without descriptions and adjust alignment automatically. * **Tests** * Updated end-to-end coverage for the revised assistant interface. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1131e3e2ce |
fix(ui): default Button variant to default instead of primary (#50160)
## What kind of change does this PR introduce? Bug fix / design-system alignment for the legacy `Button` from `ui`. ## What is the current behavior? Omitting `variant` on the legacy `Button` falls back to brand-green `primary`. That makes accidental greens easy, and it is hard to spot the real main action on busy pages. ## What is the new behavior? - Legacy `Button` now defaults to neutral `default` - Intentional primary CTAs (create, save, submit, marketing CTAs, and matching `ButtonTooltip` usages) now set `variant="primary"` so their appearance is unchanged - Neutral actions that previously relied on the old fallback (cancel, close, back, dashboard nav, and similar) become grey/white - Design-system docs updated; regression tests cover the new default `Button_Shadcn_` is unchanged. It already uses its own CVA default. This is PR 1 of 2 in a stack. PR 2 drops now-redundant `variant="default"` props. ## To test Studio (http://localhost:8082): - `/sign-in`: Sign in stays green - Open a project → Database → Tables: New table stays green - Auth → Users → Invite: Invite user stays green; Cancel / dismiss controls stay neutral - Project Settings → General: edit a field so Cancel and Save appear. Cancel is neutral, Save is green Design system (http://localhost:3003): - Components → Button: default demo is neutral; primary demo is green; featured preview is the default variant Marketing (optional): - www header: Start your project stays green; logged-in Dashboard is neutral <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Style** - Buttons now default to a neutral style, while primary actions across Studio, documentation, marketing pages, forms, dialogs, and error states use prominent primary styling. - Updated button examples and previews clarify the distinction between default and primary variants. - Event registration now includes a directional arrow icon. - **Tests** - Added coverage confirming default button styling and explicit primary styling behave as expected. - Updated related test fixtures to use primary styling where appropriate. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
30ab816ff4 |
feat(studio): make the Connect framework and client selectors searchable (#50072)
## What kind of change does this PR introduce? Feature. ## What is the current behavior? The Framework and Client selectors in the Connect sheet are plain selects. Neither is scannable at its current length, and Client is the worse of the two at 19 options. ## What is the new behavior? Both are searchable comboboxes. Each keeps its selection, filters as you type, matches on the underlying key as well as the label so `nextjs` finds `Next.js`, and announces its empty state to screen readers. | Before | After | | --- | --- | | <img width="1182" height="1250" alt="CleanShot 2026-09-07 at 14 47 12@2x" src="https://github.com/user-attachments/assets/6243c549-03cc-41bf-8b3c-a186ca0e93b5" /> | <img width="1178" height="1162" alt="CleanShot 2026-09-07 at 14 46 42@2x" src="https://github.com/user-attachments/assets/d7ca5e72-3f8b-48e5-b20f-84382e4e4fd7" /> | Placeholder, search and empty-state copy now sit on the field definition in the schema, next to the label, so one combobox component serves both fields without guessing at plurals. Client keeps its icons hidden, matching what the select did. The comment about MCP images being unoptimized still stands, so this is not the PR to turn them on. Radix Select brings its own scroll lock, so replacing it with a popover would have regressed touch scrolling in the sheet. #50103 moved that guard into `CommandList` and has merged, so this branch now carries the feature only. ## To test - Open the Connect sheet on the deploy preview. - Open the Framework selector, search for `native`, confirm only React Native remains, select it, and confirm the generated connection instructions update. - Search `nextjs` and confirm Next.js matches on its key. - Switch to the MCP tab and open Client. Search `cur` and confirm Cursor matches. - Confirm both lists cap their height and scroll, and that the sheet behind stays put. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Framework selection now uses a searchable combobox for easier navigation of long lists. * Search results clear automatically when the combobox closes. * Long framework lists appear in a contained, scrollable area. * **Accessibility** * Screen readers announce when no frameworks match the search. * Improved combobox and listbox relationships support assistive technologies. * The dropdown opens as a modal layer to keep focus within the selection experience. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
23a5bd4707 |
fix: update inbound links to the pooling guide (#50187)
## 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. Link string changes only, no content changes. ## What is the current behavior? Nine inbound links in `apps/www` and `apps/studio` point at anchors on the connecting to Postgres guide that don't exist. All nine are already broken on production today: `#connection-pooler`, `#connection-pool`, `#how-connection-pooling-works`, `#serverside-poolers`, and `#connecting-with-drizzle` are all missing from the live page. #49869 moves the pooling content to a child page, so these links need current destinations either way. ## What is the new behavior? Point each link at the page that holds the content now. - **Studio, 3 links.** The Connect sheet's Drizzle link goes to the Drizzle guide. The connection pooling and pooling modes links go to `pooling-and-limits#how-connection-pooling-works`. - **www, 6 links.** Three blog posts, the Heroku comparison page, and the Dedicated poolers feature entry go to `pooling-and-limits`. The feature entry uses `#shared-pooler`. ## Additional context Split out of #49869. These paths belong to `@supabase/marketing` and `@supabase/Dashboard` in CODEOWNERS, and pulling both teams into a docs-only restructure for nine link strings isn't a good trade. Merge after #49928. The destinations don't exist on production until the docs pages land. ## Manual testing 1. Open [Supavisor: Scaling Postgres to 1 Million Connections](https://zone-www-dot-com-git-fix-pooler-docs-links-supabase.vercel.app/blog/supavisor-1-million). The "connection pooling" link in the opening paragraph resolves to `connecting-to-postgres/pooling-and-limits#how-connection-pooling-works`. 2. Open [Dedicated poolers](https://zone-www-dot-com-git-fix-pooler-docs-links-supabase.vercel.app/features/dedicated-poolers). The docs link resolves to `pooling-and-limits#shared-pooler`. 3. Open [Supabase vs Heroku Postgres](https://zone-www-dot-com-git-fix-pooler-docs-links-supabase.vercel.app/alternatives/supabase-vs-heroku-postgres). Both connection pooling links resolve to `pooling-and-limits#how-connection-pooling-works`. 4. Open [Connection pooling and limits](https://docs-git-docs-connecting-to-postgres-technical-supabase.vercel.app/docs/guides/database/connecting-to-postgres/pooling-and-limits) on the #49928 docs preview. The `how-connection-pooling-works` and `shared-pooler` headings both render with those IDs. 5. Open the Connect dialog on any project. Under Drizzle, the docs link opens the Drizzle guide. 6. Open Database settings, then Connection pooling. The pooler link opens Connection pooling and limits. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated connection pooling links across Studio, product pages, blogs, and comparison content to point to the relevant pooling guidance. * Refined links for Drizzle ORM, dedicated poolers, direct connections, and shared poolers. * Improved navigation to specific documentation sections explaining connection pooling modes and behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a96a587f65 |
fix(studio): update Swift package URL to official supabase org (#50184)
## Summary - The Studio Connect sheet's Swift install command pointed at `supabase-community/supabase-swift`, which is no longer where the package lives — it's now official under `supabase/supabase-swift`. - Updated the URL in `INSTALL_COMMANDS.supabaseswift`. ## Test plan - [x] Verified no other references to the old URL remain in Studio code (translated top-level READMEs under `i18n/` also reference the old URL but are out of scope for this fix) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Updated the Swift installation command to reference the official Supabase Swift repository. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
246bd9acbf |
Adjust vertical space for explorer notebook query cells (#50169)
## Context As per PR title - just adjusts the vertical height for a couple of empty states in QueryCells for Notebooks ### Query not run yet | Before | After | | -------- | -------- | | <img width="1072" height="350" alt="image" src="https://github.com/user-attachments/assets/cbf14619-ac01-4082-9732-41737a028c40" /> | <img width="1083" height="313" alt="image" src="https://github.com/user-attachments/assets/1144eebf-7293-4be4-adaf-af2dc21bc40f" /> | | <img width="1083" height="292" alt="image" src="https://github.com/user-attachments/assets/511754f8-5128-41b7-a4c8-542fb93b77e5" /> | <img width="1100" height="163" alt="image" src="https://github.com/user-attachments/assets/53de5b4a-8284-406a-a8ae-4602f61f3ca3" /> | ### Chart empty state | Before | After | | -------- | -------- | | <img width="1079" height="291" alt="image" src="https://github.com/user-attachments/assets/068fe573-1f65-4efc-831c-db2ddda2be1a" /> | <img width="1078" height="225" alt="image" src="https://github.com/user-attachments/assets/b9d58d8f-162d-463d-90e2-fbf3470c6db8" /> | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Style** - Improved query editor layout by reducing unnecessary spacing and ensuring result areas fit more consistently within available space. - Refined chart empty states with cleaner borders, compact spacing, and improved vertical sizing. - Updated query error presentation with more compact padding. - Simplified result panel sizing for a more consistent viewing experience. - **User Experience** - Added a play icon alongside the “Run the query to see results” prompt when no results are available. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e267b05ee9 |
Add horizontal padding for notebook home tab (#50168)
## Context Theres no padding on smaller viewports - so the main content looks squished ### Before <img width="1674" height="1882" alt="image" src="https://github.com/user-attachments/assets/e0b1fb05-d853-40db-8e06-51dec9a9376a" /> ### After <img width="947" height="981" alt="image" src="https://github.com/user-attachments/assets/28c6dab4-0c12-4851-aa40-c65d60797463" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Improved horizontal spacing on the Explorer home screen for a more balanced layout. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
86f7d245f8 |
Use green for notebook status indicator if new (#50167)
### Context As per PR title - just a tiny adjustment to use green for the status indicator if the notebook is new and yet to persist in the DB to make it visually different for notebooks that are already in the DB but have unsaved changes <img width="372" height="80" alt="image" src="https://github.com/user-attachments/assets/5ef863b1-0e7a-4b00-baab-dc76b3cf9b47" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Updated the notebook status indicator to use the brand color for new notebooks. - Improved visual distinction between new notebook states and warning-related statuses. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3ac5a6b4f7 |
Api authorization to add returnTo param when linking to /new for no org empty state (#50166)
### Context Resolves FE-4355 - Users who reach `/authorize` with zero organizations see a "Create an organization" CTA that links to a bare `/new` - After creating the org, they land on `/new/<slug>?projectName=...` instead of back at `/authorize?auth_id=...` - `returnTo` handling used to exist here ([#30211](https://github.com/supabase/supabase/pull/30211), refactored in [#44522](https://github.com/supabase/supabase/pull/44522)) but was dropped as a side effect of the interstitial redesign in [#46359](https://github.com/supabase/supabase/pull/46359) - [#47760](https://github.com/supabase/supabase/pull/47760) later patched the missing CTA back in but not the returnTo round-trip |
||
|
|
a1686025b6 |
Joshenlim/fe 4291 keep unsaved notebooks accessible after page refresh (#49673)
## Context Changes here adds a "Draft" state for notebooks with a new `notebook-drafts` store - similar to how we handle query tabs in the explorer. This implies that if a user refreshes the tab while there's unsaved changes to notebooks, the changes can be persisted locally and the user will be able to continue from where they left off. This also implies that If you create a new notebook (OR open an existing notebook and make some changes) and refresh the browser, we no longer show the native browser confirmation dialog about discarding changes. We also reuse the existing confirmation dialog when saving a notebook if its draft has diverged from the server side content - just updated the language to be more generic rather than saying that the Assistant made changes <img width="429" height="238" alt="image" src="https://github.com/user-attachments/assets/5c392aed-1633-4428-8060-28f495a01f04" /> Also fixes an unrelated issue - renaming a notebook should mark the notebook as having unsaved changes (with the orange indicator) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Unsaved notebook edits are saved locally and restored when reopening Studio. * Drafts are scoped by project and protected from server changes through conflict detection. * Notebook tabs indicate unsaved changes, including drafts from unsaved notebooks. * **Bug Fixes** * Closing a tab with local edits prompts for confirmation and removes its saved draft. * Notebook save state reflects the server-confirmed update time. * Conflict messages clearly describe changes made on the server. * **Style** * Improved keyboard focus behavior for tab controls. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c37e756983 |
Trigger update snippet when toggling favorite (#50121)
## Context Currently in the SQL Editor, toggling "favourite" for a snippet doesn't persist unless you manually save the snippet (which expects a change in the snippet's content before allowing so) - which is a bit of an odd UX This used to work before we introduced manual saving which is currently the default behaviour for the SQL Editor - `addFavorite` and `removeFavorite` would add to the `needsSaving` queue which the editor's save scheduler will subscribe and trigger the save. However the save scheduler doesn't subscribe to the queue for manual saving mode ([ref](https://github.com/supabase/supabase/blob/master/apps/studio/state/sql-editor/sql-editor-save-scheduler.ts#L90)) - hence toggling favourite on a snippet never triggers a PATCH request. Am opting to immediately trigger a PATCH request when toggling favourites which is a bit more of an expected UX imo One thing to note is that favoriting a snippet essentially does a save on the snippet - which means the contents will be persisted as well, although i think this is alright ## To test - [ ] Verify that toggling favourite for a SQL snippet persists immediately - Can verify by checking the context menu CTA to see if it's changed from "Add to favourites" to "Remove from favourites" or vice versa <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Improvements** - Favoriting or unfavoriting SQL snippets now saves immediately. - Favorite changes are handled consistently across the SQL Editor, including the utility panel and snippet navigation. - Pending content saves are coordinated to prevent favorite changes from being overwritten. - If saving a favorite fails, the previous favorite state is restored and an error notification is shown. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
08224b40d3 |
ColumnDefaultValue null value suggestion to apply if column is nullable (#50117)
## Context In the Table Editor when editing a column's default value, only text type columns have the NULL value suggestion which is incorrect as that suggestion should be available irregardless of data type as long as the column is nullable. This PR adjusts that to add the NULL value suggestion if the column is nullable. (e.g timestamptz here) <img width="478" height="444" alt="image" src="https://github.com/user-attachments/assets/4f6856bf-26d5-4633-ba69-a1b6a23c8534" /> Am also opting to use `ColumnDefaultValue` within the TableEditor's `Column` component for consolidation. So in this case, if the column type selected is an enum, users can select from a list, similar to how it'd be in the ColumnEditor <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved column default-value editing with context-aware suggestions. * Added support for nullable columns to select `NULL` as a default value. * Added enum-aware default-value options and improved control layout customization. * **Bug Fixes** * Prevented editing default values for identity integer columns. * Improved accessibility and testability for default-value controls. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |