mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 11:55:05 +03:00
codex/fix-tanstack-e2e
20717
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2759b13efc |
refine display settings ui (#49466)
<img width="392" height="343" alt="image" src="https://github.com/user-attachments/assets/4a17e3ad-364d-45c6-9770-0f937ad18418" /> ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Studio UI refinement. ## What is the current behavior? The Explorer result settings popover uses a spacious vertical layout with mixed control heights and local active-state overrides. ## What is the new behavior? - Condenses the result settings into the horizontal form layout used by compact settings surfaces. - Uses base ToggleGroup, Select, MultiSelector, and Switch component variants. - Adds shared tiny Toggle and MultiSelector sizes so the compact controls render at 26px. - Uses the accent token for shared toggle active states. - Keeps the chart configuration behavior and disabled states intact. ## Verification - UI and UI Patterns focused tests - UI, UI Patterns, and Studio typechecks - Studio ESLint - Local visual verification against the supplied prototype <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Chart-specific configuration options now appear only when chart view is selected, keeping display settings focused and relevant. * Updated chart controls provide clearer options for scale, cumulative values, and labels. * Added compact sizing for multi-select fields and toggles to improve alignment with other form controls. * Refined toggle styling and adjusted small-size dimensions for a more consistent interface. * **Tests** * Added coverage for compact multi-select and toggle sizes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com> |
||
|
|
ee6961beb0 |
fix(studio): clarify assistant tool terminal states (#49364)
## 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? Small Assistant terminal-state fixes. ## Stack context This stack is based on #49352 (`chore/assistant-tool-outcomes`) and assumes #49350–#49352 merge first. Review bottom to top: 1. #49361 — assistant notebook run tool 2. #49362 — assistant notebook run UI 3. #49364 — terminal-state polish ## What is the current behavior? Completed notebook updates can be re-diffed against newer live content, and log-query failures can use SQL-specific or empty fallback UI. ## What is the new behavior? - Replaces completed notebook update previews with a stable success/error/skipped summary. - Keeps the Open notebook action on successful updates. - Uses logs-specific failure copy for Assistant log queries. - Shows an explicit fallback when a failed log tool input or output cannot be parsed. ## How to test manually ### Notebook update terminal states 1. Ask the AI Assistant to update an existing notebook, then approve the proposal. 2. Confirm the proposal becomes a compact **Notebook updated: [name]** summary instead of re-diffing against the newly saved notebook. 3. Click **Open notebook** and confirm it opens the updated notebook. 4. Request another notebook update and click **Skip**. Confirm the terminal summary says **Skipped notebook update**. 5. Refresh or reopen the conversation and confirm both summaries remain stable. ### Logs failure copy 1. Ask the Assistant to query Logs with an intentionally invalid table or column and approve the query. 2. Confirm the failed result says **Failed to query logs**, not **Failed to execute SQL**. 3. Confirm the failed tool remains visible rather than disappearing when its result cannot be rendered. ## Automated test The focused top-of-stack suite passes 9 test files and 85 tests. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added clearer failure messaging when query logs contain invalid input, missing results, or errors. - Added compact summaries for completed, failed, and skipped notebook updates. - Notebook update summaries include an “Open notebook” link when applicable. - **Bug Fixes** - Improved handling and display of query-log failures instead of showing blank content. - Preserved detailed previews for notebook updates that are still in progress. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1a013ea2c8 |
feat(studio): render assistant notebook runs (#49362)
<img width="1944" height="1053" alt="image" src="https://github.com/user-attachments/assets/74c6968b-5ad4-46f7-adcc-a144221877b2" /> ## 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? Assistant notebook-run UI, reusable result previews, and approval flow. ## Stack context This stack is based on #49352 (`chore/assistant-tool-outcomes`) and assumes #49350–#49352 merge first. Review bottom to top: 1. #49361 — assistant notebook run tool 2. #49362 — assistant notebook run UI 3. #49364 — terminal-state polish ## What is the current behavior? The `run_notebook` tool has no dedicated Assistant renderer, and the shared notebook preview cannot display saved query results. ## What is the new behavior? - Adds a run mode to the shared minified notebook preview. - Adds a dedicated renderer for notebook-run tool parts and wires it into `Message.Parts.tsx`. - Loads the current notebook and presents all cells behind one **Run notebook** approval. - Renders database and Logs results inside their matching notebook cells using the existing Explorer table/chart renderer and row-limit metadata. - Gives cells with results separate bordered surfaces while preserving the existing create/update layouts. - Warns when the notebook changed before approval or since a historical run. - Preserves raw run results for the user while the model receives separately sanitized output. - Handles malformed input and notebook-loading failures without hiding the approval state. ## How to test manually This PR now contains both the reusable result preview and the `tool-run_notebook` Assistant wiring, so it can be tested directly from this branch. #49364 is not required for the notebook-run UI path. 1. Create and save a notebook with at least six cells. Include: - a markdown cell - a database query that returns rows - a query that returns no rows - a query that fails - a Logs query - a database query with a row limit 2. Ask the AI Assistant: **Read this notebook and analyze it using its current results.** 3. Confirm the approval card displays the notebook name and current cells, with one **Run notebook** button and one **Skip** action. 4. Click **Skip** and confirm the card remains visible with **Skipped notebook run**. 5. Ask again and click **Run notebook**. Confirm the card enters a running state, then shows **Notebook executed** with each result under the cell that produced it. 6. Confirm the successful empty query says **Success. No rows returned** and shows **0 rows**. 7. Confirm the failed query shows its error without hiding the other cell results. 8. Confirm row counts and database row-limit copy appear below the corresponding results. 9. Confirm only the first five cells are initially visible, then click **Show more cells** and verify the remaining cells appear. 10. Refresh or reopen the conversation and confirm the completed notebook preview and results remain visible. 11. Start another run but leave it awaiting approval. Edit and save the notebook in another tab, then return and confirm the card warns **Notebook changed since the Assistant read it**. 12. Complete a run, then edit and save the notebook. Reopen the conversation and confirm the historical card warns **Notebook changed since this run**. 13. Ask the Assistant to create or update a notebook and confirm those proposal previews retain their grouped layout. ## Automated test `mise exec node@22 -- pnpm --dir apps/studio exec vitest --run components/ui/AIAssistantPanel/AssistantNotebookPreview.test.tsx components/ui/AIAssistantPanel/NotebookRunRenderer.test.tsx` 12 tests pass at this stack boundary. |
||
|
|
dcac820571 |
feat(studio): add assistant notebook run tool (#49361)
## 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? Assistant feature and data-handling plumbing. ## Stack context This stack is based on #49352 (`chore/assistant-tool-outcomes`) and assumes #49350–#49352 merge first. Review bottom to top: 1. #49361 — assistant notebook run tool 2. #49362 — assistant notebook run UI 3. #49364 — terminal-state polish ## What is the current behavior? The Assistant can read and edit notebooks, but it cannot execute all saved query cells as one approved operation. ## What is the new behavior? - Adds a `run_notebook` tool with one approval gate for the complete notebook. - Executes database and log cells sequentially in notebook order. - Rejects stale runs when the notebook changed after the Assistant read it. - Resolves primary and read-replica connections and forwards authorization to log and replica requests. - Shares rows with the model only when the organization's AI data-sharing level permits it. - Strictly validates and sanitizes persisted notebook-run output before replaying message history. - Registers the tool in prompts, filtering, mocks, and tool construction. ## How to test manually This is the tool/data layer; use the top-of-stack preview from #49364 for the complete UI while checking these behaviors. 1. In Explorer, create and save a notebook named **Assistant run smoke test** with: - a markdown cell - a working database query - a working Logs query - a database query that returns no rows, such as `select 1 where false` 2. Open the AI Assistant and ask: **Read the “Assistant run smoke test” notebook and analyze it using its current results.** 3. Confirm the Assistant reads the notebook and requests one `run_notebook` approval for all query cells, rather than requesting one approval per cell. 4. Approve the run. Confirm database and Logs queries execute in notebook order, the markdown cell is not executed, and the Assistant responds only after the complete run finishes. 5. Start another run but do not approve it yet. In another tab, edit and save the notebook. Return to the pending approval and approve it. 6. Confirm the stale run is rejected, the Assistant reads the latest notebook version, and a new approval is required. 7. Optional privacy check: set the organization AI data-sharing level to schema-only, run a query containing a recognizable value, and confirm the value remains visible in the notebook result UI but is not repeated in the Assistant's answer. ## Automated test `mise exec node@22 -- pnpm --dir apps/studio exec vitest --run lib/ai/tool-filter.test.ts lib/ai/tools/index.test.ts lib/ai/tools/mock-tools.test.ts lib/ai/tools/notebook-tools.test.ts lib/ai/tools/tool-sanitizer.test.ts` 80 tests pass at this stack boundary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added AI-assisted notebook execution for database and log cells, with approval, freshness checks, replica support, and per-cell error handling. - Added notebook deletion and database discovery and validation for notebook management. - Added configurable privacy controls for notebook results. - Added request header support for analytics SQL execution. - **Bug Fixes** - Improved replica lookup handling so other notebook cells can continue when one lookup fails. - Prevented invalid, unauthorized, or overly detailed notebook execution results from being exposed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com> |
||
|
|
580af6e336 |
fix(www): stop blog tag and author breadcrumbs from becoming the page h1 (#49507)
<!-- ccr-slack-attribution --> _Requested by **Pam Chia** · [Slack thread](https://supabase.slack.com/archives/C07P3AU3J2D/p1787616624076769)_ **Before:** searching "supabase blog" on Google surfaces blog tag sitelinks titled `Blog/Tags/Supabase` and `Blog/Tags/Community`, each with the same snippet scraped from the footer newsletter form ("Get product updates and news from Supabase"). **After:** those results use the route's real title, `Blog | Supabase`, with a description specific to the tag, for example "Blog posts tagged Supabase." This change stops the visible breadcrumb on blog tag and author pages from being the page's only `<h1>`, and gives tag and category pages distinct meta descriptions. ## How this changes the Google result The bad sitelinks come from two independent mechanisms, and each half of this PR targets one of them: **Titles.** Google prefers a page's `<h1>` over its `<title>` when the two disagree, and on tag pages the only `<h1>` is the breadcrumb, whose textContent is exactly `Blog/Tags/Supabase` (JSX strips the whitespace between the children). Demoting the breadcrumb to a `<nav>` removes the conflicting heading, so Google should fall back to the route's real `<title>`: - `Blog/Tags/Supabase` becomes `Blog | Supabase` - `Blog/Tags/Community` becomes `Blog | Community` **Snippets.** The "Get product updates and news from Supabase. Subscribe ..." text is not a meta description; it is Google's own synthesized snippet, scraped from the footer newsletter form. Every tag and category page shipped the byte-identical description "Latest news from the Supabase team.", and Google discards a description duplicated across many URLs. With a unique per-page description, Google has a usable candidate again: - tag rows should show `Blog posts tagged Supabase.` / `Blog posts tagged Community.` - category rows (`Blog | Engineering`, `Blog | Product`) already had correct titles but the same scraped snippet; they should now show `Blog posts in Engineering.` / `Blog posts in Product.` Two caveats. Meta descriptions are suggestions, not directives, so Google can still synthesize its own snippet; removing the duplicate-description cause makes the supplied one much more likely to win, but does not force it. And the replacement `<h1>` is the constant sr-only `Supabase Blog` on every listing page: if Google again prefers the h1 over the title, all sitelinks would read `Supabase Blog`. A page-specific heading ("Posts tagged Supabase", "Posts by <author>") would eliminate that residual risk and is a candidate follow-up. Neither change appears in search results until Google recrawls and reprocesses these URLs (see Additional context; the tag routes are absent from the sitemap, which slows this). Requesting reindexing of a few of these URLs in Search Console would speed it up. ## 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 (SEO / accessibility), `apps/www` only. ## What is the current behavior? Two separate defects feed the same bad search result. Google prefers a page's `<h1>` over its `<title>` when the two disagree, and on tag pages the only `<h1>` is the breadcrumb. `apps/www/app/blog/tags/[tag]/TagClient.tsx:21-27` wraps `Blog` / `/` / `Tags` / `/` / `<tag>` in an `<h1>`; JSX strips the whitespace between those children, so the element's textContent is exactly `Blog/Tags/Supabase`. The route's own `<title>` is already fine (`apps/www/app/blog/tags/[tag]/page.tsx:26`). `apps/www/app/blog/authors/[author]/AuthorClient.tsx:55-60` has the identical defect. Category pages escape it because `apps/www/app/blog/BlogLayoutShell.tsx:19` counts `/blog/categories/` as a listing route and renders the sr-only `<h1>Supabase Blog</h1>` at line 23, while `CategoryClient.tsx` renders no `<h1>` of its own. Separately, every tag and category page shipped the byte-identical description `Latest news from the Supabase team.` (`apps/www/app/blog/tags/[tag]/page.tsx:27`, `apps/www/app/blog/categories/[category]/page.tsx:23`). Google discards a description reused verbatim across many pages and generates its own snippet, in this case from the footer newsletter copy at `apps/www/components/Footer/index.tsx:179`. ## What is the new behavior? - `BlogLayoutShell.tsx` — `isListingRoute` now covers `/blog/tags/` and `/blog/authors/` alongside `/blog/categories/`, via a `LISTING_ROUTE_PREFIXES` constant. Those routes now render the same sr-only `<h1>Supabase Blog</h1>` category pages already had. - `TagClient.tsx` and `AuthorClient.tsx` — the breadcrumb is now a `<nav aria-label="Breadcrumb">` instead of an `<h1>`. Every existing className, the `/` separator spans and their `px-2` padding are unchanged. The `h1` element selector in `apps/www/styles/globals.css:176-179` applies `font-heading font-medium tracking-normal`, so those three utilities move onto the `nav` to keep the rendering byte-identical. No visual change is intended; only the element and its accessible role change. - `tags/[tag]/page.tsx` and `categories/[category]/page.tsx` — `generateMetadata` now returns `Blog posts tagged ${label}.` and `Blog posts in ${label}.`, matching the shape the author route already uses (`apps/www/app/blog/authors/[author]/page.tsx:37`). Both use `startCase` from `apps/www/lib/helpers.tsx:75-81` rather than `capitalize`, so `launch-week` reads "Launch Week" and matches the filter chip label at `apps/www/components/Blog/BlogFilters.tsx:56-57`. Title and description use the same label. ## Additional context `apps/www` is owned by `@supabase/marketing` per `.github/CODEOWNERS:13`, so marketing should review this. Recovery is not immediate: Google has to recrawl these routes before the corrected titles and descriptions show up in search results. Noted follow-ups, deliberately out of scope here: - `/blog/tags/*` and `/blog/authors/*` are absent from the generated sitemap (`apps/www/internals/generate-sitemap.mjs`), which slows discovery and recrawl. - The page bodies still pass a `capitalize`-derived label to `TagClient` and `CategoryClient`, so the visible tag breadcrumb reads "Launch week" while the title now reads "Launch Week". Aligning the visible label would be a rendered-text change, so it is left for a separate PR. - `openGraph` metadata on these routes is untouched and still carries the generic copy. ### How it was tested Prettier passes on the five changed files with the repo config, in both the default and the `SORT_IMPORTS=false` mode CI uses. Full typecheck and lint could not be run in this environment (no `node_modules`); the changes are type-trivial — a `string[]`.`some()` predicate, a JSX tag swap, and two template literals over an existing exported `startCase(string): string` helper — and the diff parses clean under `tsc` with module resolution disabled. Worth a reviewer eyeballing the tag and author pages side by side against production to confirm the breadcrumb renders identically. --- _Generated by [Claude Code](https://claude.ai/code/session_0164goAzGTkGnoxzCKagJ3Hw)_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
40d9a2e929 |
fix(studio): invalidate notebook cache after assistant delete (#49496)
Stacked on supabase/supabase#49415. ## Summary - collect completed assistant delete_notebook tool calls as deleted cache effects - evict deleted notebooks from the React Query cache and notebook state - cover collector, cache eviction, and the open-tab Notebook not found state ## Verification - pnpm test:studio -- notebook-cache-invalidation ExplorerNotebookTab.assistant-cache-invalidation - pnpm --filter studio typecheck - touched-file ESLint and Prettier checks <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved notebook deletion handling so removed notebooks no longer remain visible after deletion. * Navigation and cached notebook data now update promptly when a notebook is deleted. * Attempting to access a deleted notebook now displays a clear “Notebook not found” message. * **Tests** * Added coverage for notebook deletion, cache invalidation, navigation updates, and the resulting not-found state. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
5f50338a2f |
fix(studio): keep region flags visible on light surfaces (#49517)
## What kind of change does this PR introduce? Studio interface fix. ## What is the current behavior? Region flags with light backgrounds, such as Japan, can disappear against light Studio surfaces. Flag rendering is also repeated across region selectors and infrastructure views. ## What is the new behavior? Region flags use a shared `RegionFlag` component with the existing small radius and a subtle 1px border. The treatment is applied consistently across project creation, replication, read replicas, infrastructure, and Edge Function observability. | Before | After | | --- | --- | | <img width="746" height="246" alt="CleanShot 2026-08-25 at 14 01 07@2x" src="https://github.com/user-attachments/assets/5ccffccd-f253-47ca-a587-e97d1e8306a8" /> | <img width="746" height="234" alt="CleanShot 2026-08-25 at 14 09 20@2x" src="https://github.com/user-attachments/assets/9d59f7f6-4364-4c2c-8b97-a9673616736a" /> | ## To test - Open the new project flow and inspect the selected region and region menu. Confirm light flags remain visible without changing size or aspect ratio. - Open Database Replication and inspect region flags in the diagram and destination form. - Open `/project/<ref>/settings/infrastructure` and inspect flags in the topology, map, and read replica details. - Open Edge Function observability and inspect the region filter options. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **UI Improvements** * Standardized region flag displays across project creation, replication, infrastructure, read replica, and observability views. * Region flags now use consistent styling, rounded borders, and rendering throughout the Studio interface. * Improved visual consistency for selected regions, database nodes, tooltips, and region options. * Decorative flags in observability views are handled appropriately for assistive technologies. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
de3a8799d6 |
fix(studio): invalidate notebook caches after assistant create/update (#49415)
## Summary - The assistant's `create_notebook`/`update_notebook` tools run entirely server-side, so an open notebook tab's React Query cache and Valtio store never learn a write happened — the tab keeps showing stale content until a manual reload. - Adds `collectNotebookCacheEffects`/`applyNotebookCacheEffects` (`apps/studio/lib/ai/notebook-cache-invalidation.ts`), which scan finished assistant messages for completed `create_notebook`/`update_notebook` tool calls and evict the affected notebook via `evictNotebookFromCaches` (`apps/studio/data/content/notebooks/notebook-cache.ts`), plus invalidate the nav list. - Wired into `createChatInstance`'s `onFinish` in `state/ai-assistant-state.tsx`, with per-chat dedupe so replayed history isn't reprocessed. - Removes the cache entry outright rather than invalidating it, since a remounting `useNotebookQuery` would otherwise read the stale cached value synchronously before its refetch lands. - Explicitly skips eviction when the open tab has unsaved local edits, so an assistant write can't silently discard them. Related: [FE-4235](https://linear.app/supabase/issue/FE-4235) **Out of scope:** this only protects the client-side cache/store from being clobbered after the fact. Preventing the assistant's `update_notebook` tool call itself from overwriting a user's unsaved edits (a data-layer conflict, not a cache-freshness one) is tracked separately in [FE-4255](https://linear.app/supabase/issue/FE-4255). ## Test plan - [x] `pnpm test:studio -- notebook-cache notebook-cache-invalidation ai-assistant-state.notebook-cache-invalidation ExplorerNotebookTab.assistant-cache-invalidation ExplorerNotebookTabCoordinator` — all passing - [x] Reproduction-first component test (`ExplorerNotebookTab.assistant-cache-invalidation.test.tsx`) — verified it fails without the fix (stale content persists) and passes with it - [x] Regression test for the dirty-notebook guard (an edited, unsaved notebook is left untouched by an assistant write) - [x] `pnpm typecheck --filter=studio` / `pnpm lint --filter=studio` clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Notebook changes made through the AI assistant now appear correctly in open notebook tabs and after reopening them. * Saved notebook caches are refreshed after completed create or update actions, preventing stale content from being displayed. * Unsaved notebook changes are preserved during cache cleanup. * Closing a notebook tab now consistently removes its cached content. * **Tests** * Added coverage for assistant-driven updates, remounts, duplicate actions, project context changes, and cache behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3490a63a7c |
Hook up analyze button in notebook (#49463)
## Context Hooks up the "Analyze" CTA on a notebook which runs a prompt in the Assistant to run the notebook and summarize findings <img width="230" height="63" alt="image" src="https://github.com/user-attachments/assets/fd30f301-1c52-4e9b-810c-74820cf52720" /> Note: running notebooks have not been hooked up yet on the Assistant side of things <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an Analyze action to notebook tabs. * Notebook changes must be saved before analysis can begin, with a confirmation prompt to save. * Analysis starts automatically after a successful save. * The Analyze action now shows a loading state while analysis is being created. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
002be81efb |
[FE-4184] fix(studio): hide view logs link for disabled services (#49487)
On Multigres/HA projects, Realtime is intentionally shown as **Disabled** in the project home status hover card, but the row still linked to logs with a "View logs" hover affordance and used the same warning triangle as an unhealthy service. Disabled services now render as a non-interactive row with a neutral "off" icon. **Changed:** - `ServiceStatus.tsx` – services with status `DISABLED` render a plain `div` instead of a `Link` (no hover background, no "View logs" + chevron). All other services keep the existing click-to-logs behavior. - `DISABLED` services now show a muted `MinusCircle` icon instead of the `AlertTriangle` used for unhealthy services, so "off" no longer reads as "broken". - "View logs" affordance is also revealed on keyboard focus (`group-focus-visible`), not just hover. - Applies to any `DISABLED` service, not just Realtime – PostgREST also resolves to `DISABLED` when its `db_schema` is empty. ## To test - Open the home page of a Multigres/HA project and hover the **Status** stat to open the service hover card - Realtime row shows a muted circle-minus icon with "Disabled", no hover highlight and no "View logs" link - Other rows (Database, Auth, Storage, etc.) still highlight on hover, show "View logs" on hover or keyboard focus, and navigate to their logs page on click - Unhealthy services still show the warning triangle - On a non-HA project, all rows (including Realtime) behave as before Addresses FE-4184 --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
f1526d2d1b |
Fix running queyr cell marks notebook tab with unsaved change indicator (#49464)
## Context Fixes a small bug whereby running any query cell within a notebook will mark the notebook tab with the unsaved changes status indicator `handleSqlCommit` gets called when we run the query, and it flips the notebook's status to "unsaved" hence why its happening. Hence opting to skip committing the changes in `handleSqlCommit` if there's no change to the SQL content <img width="224" height="69" alt="image" src="https://github.com/user-attachments/assets/7015b527-b249-4f2e-bcf1-948b5fe3f5a9" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Prevented unnecessary notebook updates when committed SQL is unchanged. - Continued saving SQL changes as expected. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
63a6e27142 |
Trigger native browser confirmation when exiting session if there's unsaved changes (#49465)
## Context As per PR title - triggers the native browser discard confirmation dialog while in the explorer UI if exiting the session (e.g by refreshing or closing the tab) and there's any tabs with unsaved changes <img width="593" height="431" alt="image" src="https://github.com/user-attachments/assets/85b50c3e-ee69-4d27-8819-12151e6fc9f7" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Added a warning when attempting to leave or close the page while a notebook has unsaved changes. * Prevented unnecessary warnings when no discardable changes are present. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e616c6d267 |
Add blog post: Enterprise-managed auth for the Supabase MCP server (#49493)
## 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? New blog post announcing enterprise-managed auth for the Supabase MCP server, built with Anthropic and Okta. ## What is the current behavior? No blog post exists for this launch. ## What is the new behavior? Adds `/blog/enterprise-managed-auth-for-the-supabase-mcp-server` dated 2026-08-24, authored by Cemal Kılıç and Greg Richardson, with the OG and thumbnail images. Supersedes #49492 (closed by a branch rename). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Announced general availability of enterprise-managed authentication for the Supabase MCP server. * Added details on Okta-based administration through Claude, user-specific roles and permissions, and centralized onboarding, offboarding, and access reviews. * Included plan availability requirements and setup guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d5ee11bea0 |
fix: hand off AI assistant to the project page in org view (#49477)
Fixes FE-4200, FE-4206. ## What is the current behavior? Submitting a support ticket from an org-level page (with no project in the URL) shows a "While you wait" AI assistant card. However, the assistant is built around project-scoped context from the URL, so making it work here required adding project-context fallbacks across several features. Two previous PRs addressed individual issues, but testing continued to surface the same underlying problem in other areas, including chat persistence, message rating, table browsing, and SQL editor actions. - **#49244** - **#49430** Rather than keep adding fallbacks, this PR removes the underlying context mismatch. ## What is the new behavior? When a support ticket is submitted from an org-level page, the "While you wait" card now links to the relevant project instead of trying to run the AI Assistant without real project context. The link opens the project with the AI Assistant sidebar and hands off the support ticket. The chat is created there, so project-scoped features like schema browsing, SQL actions, message rating, and chat persistence work natively without special-casing. If there’s no relevant project, the card isn’t shown. The ticket form also restores the "No specific project" option for cases where the auto-selected project isn't relevant. ## Additional context Also fixes ?sidebar= deep links not opening the sidebar after client-side navigation. LayoutSidebarProvider now reacts to URL param changes instead of only checking on initial load. ## How to test 1. Submit a project-related support ticket from an org-level page. 2. Confirm the "While you wait" card shows "Open Assistant in project". 3. Click it and confirm the correct project opens with the AI Assistant sidebar and support chat active. 4. Verify project-scoped features work, such as schema questions and Edit query / Run. 5. Refresh and confirm the chat persists. 6. Select "No specific project" and confirm no assistant card is shown. 7. Submit a ticket from a project support page and confirm the existing inline assistant behavior is unchanged. 8. Verify a project ?sidebar=ai-assistant deep link still opens the sidebar normally. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support handoff links when a submitted ticket belongs to another project. * Handoff links securely preserve support request details without exposing them in the URL. * Opening a valid handoff link creates and selects a support chat with the submitted request context. * **Bug Fixes** * Improved sidebar behavior when URL state changes. * Project selector validation messages now remain visible. * Invalid, expired, or mismatched handoffs now fall back to a new chat and display an error message. * Handoff details are securely handled only once and cleared after use. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
89b4f1aca4 |
feat(studio): add delete_notebook tool to AI assistant (#49413)
## Summary * Adds a `delete_notebook` AI assistant tool (`needsApproval: true`) that lets the assistant delete a notebook with explicit user approval, mirroring the existing `create_notebook`/`update_notebook` tools. * Wires up a destructive-styled approval card in the AI Assistant Panel (fetches the notebook to show its name, warns the deletion is permanent) using the same `Confirm`/tool-approval plumbing as the other notebook tools. * Updates `tool-filter.ts` opt-in gating, the assistant system prompt, the eval-harness mock tools, and the eval dataset with `delete_notebook` coverage. * Adds test coverage in `notebook-tools.test.ts`, `mock-tools.test.ts`, and `NotebookProposalRenderer.test.tsx`. Closes [FE-4242](https://linear.app/supabase/issue/FE-4242/assistant-delete-notebook-tool). ## Test plan - [X] `pnpm typecheck --filter=studio` passes - [X] `pnpm --filter studio exec vitest run` for the touched files (notebook-tools, mock-tools, NotebookProposalRenderer, [Message.Parts](<http://Message.Parts>), and existing consumers of `content-delete-mutation`) — all passing - [X] `eslint` and `prettier --check` clean on all touched files - [X] Manual verification of the approval UI in a running Studio instance (not done in this session) ## Summary by CodeRabbit * **New Features** * Added AI-assisted notebook deletion with explicit confirmation and irreversible-action warnings. * Added safeguards to distinguish deleting an entire notebook from removing individual panels. * Completed deletions now display the deleted notebook’s name without an option to reopen it. * **Bug Fixes** * Improved handling of missing notebooks and invalid deletion requests. * **Tests** * Added coverage for deletion approval, denial, errors, and successful completion. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AI-assisted notebook deletion with explicit approval and irreversible-action warnings. * Added confirmation, loading, error, and completion states for notebook deletion. * Prevented accidental full-notebook deletion when only a panel or section should be removed. * Improved notebook update results by showing applied changes when available. * **Bug Fixes** * Notebook deletion now uses the required API version. * Improved handling and validation of missing notebooks during deletion. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
60f7903b52 |
fix(www): group the filter controls and announce the result count (#49410)
Closes FE-4251 ## Problem The filter sidebars are unstructured `div` nesting. Measured on a preview: * 9 checkboxes on `/features` and 13 on `/partners/catalog`, none inside a `fieldset`, a `role="group"`, or any region. * The `/features` "Filter by tags:" `h2` has no `id`, so nothing can reference it as a group name. * The only landmarks on `/features` are two `nav` elements, so the filter panel is unreachable by landmark navigation. A screen reader user meets a checkbox announced as "authentication, checkbox" with nothing conveying that it filters features by tag. Separately, both result counts update on every filter change with no live region, so the outcome of toggling a filter is never announced. ## Solution * Wrap each checkbox set in a labelled `role="group"`. * Wrap each filter panel in an `aside` labelled "Filters". * Add `aria-live="polite"` to both result counts. The two pages name their group differently on purpose. `/features` uses `aria-labelledby` pointing at the existing `h2`, so the visible heading is the accessible name. `/partners/catalog` uses `aria-label`, because `filtersPanel` renders into both the desktop sidebar and the mobile sheet, so an `id` would appear twice in the DOM. That file already calls out the duplicate-id hazard at line 152 as its reason for using wrapping labels. Chose `role="group"` over `fieldset` and `legend` to avoid resetting UA styling in a styled sidebar. The single self-hosted checkbox keeps its own label and needs no group. ## Manual testing **/features** 1. Open [/features](https://zone-www-dot-com-git-www-filter-groups-and-live-count-supabase.vercel.app/features) with Screenreader. 2. Confirm the tag checkboxes report as a group named "Filter by tags:". 3. Confirm a "Filters" landmark appears in landmark navigation. 4. Tick a tag filter. The result count changes and is announced. **/partners/catalog** 5. Open [/partners/catalog](https://zone-www-dot-com-git-www-filter-groups-and-live-count-supabase.vercel.app/partners/catalog) at a desktop width. The filter panel is `hidden md:block`, so the landmark only exists at md and above. 6. Confirm the category checkboxes report as a group named "Categories". 7. Open the mobile filter sheet at a narrow width and confirm the group is still named, with no duplicate ids. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility Improvements** * Improved screen reader navigation for partner catalog and feature filters. * Added accessible labels and landmarks for filter sections. * Updated result counts to be announced when selections change. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
78d6d57faa |
fix(www): stop rendering the invisible Clear all filters button (#49409)
Closes FE-4250 <img width="661" height="294" alt="Screenshot 2026-08-21 at 10 44 38 AM" src="https://github.com/user-attachments/assets/db7e09db-845c-43a8-a6ca-5d0c67436355" /> ## Problem With no filters active, `/features` still rendered the "Clear all filters" button and hid it with `opacity-0`. Found with VoiceOver, which announced "You are currently on a button" on an apparently empty control. Measured on a preview with no filters active: | Property | Value | | -- | -- | | `opacity` | `0` | | `visibility` | `visible` | | `display` | `block` | | `tabIndex` | `-1` | | `aria-hidden`, `inert`, `disabled` | none | | `pointer-events` | `auto` | | Layout | 256 x 26px | Two assumptions were wrong. `opacity: 0` does not remove an element from the accessibility tree, and `tabIndex="-1"` only removes it from tab order, not the tree. Screen readers walk the tree. It was also a live 256 x 26 mouse target, so a sighted user could click an invisible button. ## Solution Render it conditionally, matching `IntegrationsContent.tsx` which already does this and was unaffected. No layout shift. The button is the last child of the sidebar column, so nothing above it moves when it appears. ## Manual testing 1. Open [/features](https://zone-www-dot-com-git-www-features-clear-filters-button-supabase.vercel.app/features) with no filters applied. Confirm no "Clear all filters" button exists anywhere in the DOM. 2. Tick a tag filter in the left sidebar. The button appears. 3. Click it. Every filter clears, the count returns to 79 features, and the button disappears again. For the before state, open [/features on production](https://supabase.com/features) with no filters, then run this in the console. It reveals the button that is present but invisible: ```js const b = [...document.querySelectorAll('button')].find(x => /Clear all filters/.test(x.textContent)) Object.assign(b.style, { opacity: '1', outline: '3px solid red' }) ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * The “Clear all filters” button now appears only when filters are active. * Improved keyboard navigation by removing inactive filter controls from the tab order. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
21265b2e59 |
docs(database): make writing and running the tests part of the procedure (#49276)
Ref DOCS-1274 Follow-up to #49017, now merged. This is the go-to-green piece: everything aimed at the three failing eval checks, and nothing else. Technical corrections follow in the PR stacked on this one. ## Problem `build-docs-002-rls-guide` points an agent at this guide with a vibe-coder prompt that never says RLS, policy, role, or test. Grants, policies, access probes, indexes, and security-definer placement all pass. Three checks fail, and have failed on every recorded run: | Check | What it measures | Why it failed | | --- | --- | --- | | `pgTAP test file(s) written under supabase/tests/` | Any `.sql` file exists | The agent never wrote one. | | `supabase test db runs at least 8 assertions and all pass` | Suite runs, ≥8 assertions, none failing | Nothing to run. The only example was `plan(4)`, under the floor even if copied perfectly. | | `tests assert allow and deny per operation … for anon and authenticated` | LLM judge on coverage | Never reached the judge: "no test files to review". | The guide already had a `Test your policies` section, so this isn't a strength problem. Agents don't read the page. They fetch it through an LLM extraction guided by their own query, and that query asked for enabling RLS, policy syntax, `auth.uid()`, indexes, and security definer functions. It never mentioned tests. A section about testing never enters the extract, so more testing prose cannot reach the agent. There was also a plain documentation bug underneath it: `Secure a table with RLS` said a table isn't secured until the suite passes, but the procedure beneath it ran 1–3 and ended on `grant`. A reader following the numbered steps finished without ever being told to write a test. ## Solution Put the tests where the procedure and the examples already are. - **`Secure a table with RLS`** opens with the four steps that finish a table, ending on `supabase test db`. Until the suite passes, you don't know whether the policies do what you intended. - **`Enable RLS and set the grants` gains step 4** — `supabase test new <table>_rls.test`, then `supabase test db`. The procedure ends on a passing suite instead of a grant. - **The public-read example** gains its policy and `announcements_rls.test.sql`, so a test file rides along in the enable-RLS extract. - **The four policy examples** are followed immediately by `profiles_rls.test.sql`, so one rides along in the `create policy` extract too. - **`Run the test suite` shrinks** to creating and running the files. It no longer carries content that has to survive extraction. - Each file leads with its own path as a comment, so it survives if the fence metadata is dropped. ### How that maps to the three checks | Check | Addressed by | | --- | --- | | Test files written | A complete test file now sits inside both extracts an agent's own query pulls, and step 4 of the procedure names the command that creates one. | | ≥8 assertions, all passing | `announcements_rls.test.sql` is `plan(10)`, `profiles_rls.test.sql` is `plan(14)`. Either alone clears the floor; together, 24. | | Coverage judge | `profiles` asserts allow **and** deny for all four operations. Allowed writes use `returning` + `results_eq`, proving state changed rather than that nothing raised. `using`-filtered denials use `is_empty`, asserting the row is unchanged rather than that an error was raised — the case the rubric explicitly fails suites for getting wrong. Both files switch role with `set local role` and identity with `set local request.jwt.claim.sub`, and cover `anon` as well as `authenticated`. | ## Manual testing 1. Open the [Row Level Security guide](https://docs-git-docs-rls-tests-in-procedure-supabase.vercel.app/docs/guides/database/postgres/row-level-security) on the preview. `Secure a table with RLS` opens with a four-step definition of done ending on `supabase test db`. 2. Read `Enable RLS and set the grants`. The procedure runs 1–4 and ends on writing and running the test, not on the grant. 3. Scroll to `DELETE policies`. The four policies are followed immediately by `profiles_rls.test.sql`, not a pointer to a later section. 4. Open the [markdown version](https://docs-git-docs-rls-tests-in-procedure-supabase.vercel.app/docs/guides/database/postgres/row-level-security.md), which is what agents fetch. Both test files are present, each leading with its path. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Documentation - Updated database security guidance for enabling row-level security and configuring grants. - Added per-table pgTAP testing requirements and revised `supabase test db` examples. - Expanded examples for permitted and denied access across public and authenticated roles. - Added dedicated guidance for profile testing and security-definer member/non-member cases. - Documented recursive-policy `42P17` failures and the security-definer workaround. - Clarified indexing, denial diagnosis, returned-row verification, and table-hardening links. - Streamlined the general policy-testing guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0243ad7cf1 |
fix(www): make the view toggles a radio group and fix the filter rows (#49346)
Closes FE-4227 > [!NOTE] > Bottom of a stack. #49409 and #49410 sit on top of this one, so merge this first. ## Problem Five defects in the view toggles on `/features` and `/partners/catalog`, plus one in the `/features` filter rows. All measured on a preview. **Toggles** | Defect | Evidence | | -- | -- | | No pointer cursor | Tailwind 4 Preflight no longer sets `cursor: pointer` on buttons. 14 of 19 buttons on `/features` computed to `default`. Anchors were unaffected, which is why it looked inconsistent rather than total. | | The selected toggle offered a pointer | It is a no-op, so the cursor promised an action that does nothing. | | The selected state was invisible in light mode | `bg-surface-300` and `bg-surface-75` both resolve to pure white. Contrast ratio exactly 1.000. The light theme base lightness is `.995` and each surface step adds `.024`, so every lighter step clamps at white. The only cue left was icon colour. | | Hover inverted the selection | Unselected hover is `bg-surface-200`, a 2.7% black overlay, while the selected state was white. Hovering the wrong button made it look selected. | | No grouping | Two unrelated buttons. Nothing conveyed one choice with two options, and the selected view was not programmatically determinable at all. | **Filter rows on /features** A pointer appeared only on the narrow gap between each checkbox and its label: | Element | Computed cursor | | -- | -- | | wrapper `div` | `pointer` | | `label` | `default` | | checkbox | `default` | `cursor-pointer!` sat on the wrapper. A declaration targeting an element always beats an inherited value, so `!important` on the parent changed nothing and both children overrode it. ## Solution **Toggles become a `ToggleGroup`** on both pages, replacing the raw button pairs. * `type="single"` renders `role="group"` with `role="radio"` and `aria-checked` per item. That describes one choice with two options rather than two independent toggles, so a screen reader announces the selection and its position in the set. * Each group gets an `aria-label`, which the existing `ToggleGroup` usage on `/pricing` lacks. * Selected item gets `cursor-default`, unselected gets `cursor-pointer`. * Selected background becomes `bg-surface-400`, a 5.4% overlay that clears the 2.7% unselected hover and removes the inversion. **Filter rows** become wrapping `label` elements with `cursor-pointer` directly on the label, matching `IntegrationsContent.tsx`. The whole row becomes a click target, and `id` values derived from raw product names go away. `toggleVariants` sets the selected background to `bg-surface-300` under both `data-[state=on]:` and `aria-checked:`, and twMerge only dedupes matching prefixes. Both are overridden here so adopting the primitive does not reintroduce the invisible state this PR fixes. The primitive defect is FE-4245. ### Behaviour change The toggle pair is now a single tab stop navigated with arrow keys, rather than two separate tab stops. That is correct for a mutually exclusive group, but it is a change from current behaviour. ### Related, deliberately not here | Work | Where | | -- | -- | | Checkbox primitive pointer cursor | #49408, so the shared-package change is reviewed separately. The checkbox itself still shows an arrow on this branch. | | Naming these toggles, which rely on `title` | FE-4229 | | Base-layer cursor fix across www, Docs and Studio | FE-4228 | | Sharing one component between the two pages | FE-4244 | ## Manual testing 1. Open [/features](https://zone-www-dot-com-git-www-view-toggle-pointer-cursor-supabase.vercel.app/features) in light mode. The selected toggle is visibly darker than the unselected one. 2. Hover the selected toggle. The cursor is an arrow. Hover the unselected one. It is a pointer, and it does not become darker than the selected one. 3. Tab to the toggle pair. It takes one tab stop. Move between options with the arrow keys. 4. Inspect either toggle. It has `role="radio"` with `aria-checked` tracking the selection, and the wrapping group has an `aria-label`. 5. Hover a tag filter row over the label text and over the gap between the checkbox and the text. Both show a pointer. The checkbox itself still shows an arrow here; that is #49408. 6. Click a filter row well away from the checkbox. The filter toggles. 7. Repeat steps 1 to 4 on [/partners/catalog](https://zone-www-dot-com-git-www-view-toggle-pointer-cursor-supabase.vercel.app/partners/catalog). --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c79d7be7d9 |
fix(www): give the feature and partner card grids list semantics (#49411)
Closes FE-4252 ## Problem `/features` renders 79 feature cards as bare `Link` elements in a grid `div`. Measured on a preview, `main` contains zero `ul`, `ol`, `li`, and zero `role="list"`. `/partners/catalog` is the same. A screen reader user gets a run of loose links with no "list, 79 items", no set size, and no way to navigate by list. Sighted users see an obvious grid of cards, and the structure conveying that is purely visual. Same defect class as FE-4101 and DOCS-1279, both already in this milestone. ## Solution Make each card container a `ul` with one `li` per card. Four containers: | File | Container | | -- | -- | | `apps/www/pages/features.tsx` | feature card grid | | `apps/www/app/partners/catalog/IntegrationsContent.tsx` | featured partners grid | | same | grid view | | same | list view | This change makes a Screenreader announce the number of items and track them. Most of this diff is re-indentation from the added wrapper. ## Manual testing **/features** 1. Open [/features](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/features) with Screenreader. Confirm the cards report as a list of 79 items, and that the count tracks the filters. 2. Check the grid at mobile, tablet and desktop widths. Cards stay equal height within a row and the column counts are unchanged. **/partners/catalog** 3. Open [/partners/catalog](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/partners/catalog) in grid view with Screenreader. Confirm both the featured section and the main grid are lists. 4. Switch to [list view](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/partners/catalog?view=list). Confirm it is a list and the dividing lines between rows are unchanged. Compare any of these against [production](https://supabase.com/features). The rendering should be identical; only the markup changes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility** * Improved semantic structure for partner catalog and feature cards using properly organized lists. * Expanded card links to make larger portions of featured and grid cards clickable. * Preserved existing layouts, content, and filtering behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
932180541e |
fix(ui-patterns): give the shared InfoTooltip trigger an accessible name (#49345)
Closes FE-4093 ## Problem The shared `InfoTooltip` trigger's only child is an SVG and it has no accessible name, so a screen reader announces an unnamed button and the information the tooltip carries is unreachable. `button-name`, critical. `/pricing` renders 34 of them. ## Solution * Add an optional `label` prop rendered as `sr-only` text, with a generic fallback so the 22 call sites that pass nothing still get a name. The prop is optional because 26 files import this component across www, Studio, design-system and ui-patterns. * Drop the redundant `role="button"` from a native button. * Label the four www call sites. A shared fallback alone would leave `/pricing` announcing 34 identical names, which passes axe and stays unusable. The labels come from the feature title and plan already in scope, so no pricing data changes. Docs is unaffected. It has its own `InfoTooltip` at `apps/docs/features/ui/InfoTooltip.tsx` and never imports the shared one. ## Manual testing 1. Open [/pricing](https://zone-www-dot-com-git-ui-patterns-infotooltip-ac-07e2ab-supabase.vercel.app/pricing) using a Screenreader. 2. Tab through the comparison table. Each info tooltip announces its own feature, for example "About Database size". 3. Tab to a plan-specific tooltip. It announces the feature and the plan, for example "About Automatic backups on the pro plan". 4. Confirm the icons render unchanged and the tooltips still open on hover and on focus. 5. Run axe on the page. `button-name` reports zero elements. 6. Open the [design system InfoTooltip page](https://design-system-git-ui-patterns-infotooltip-acces-66ec02-supabase.vercel.app/design-system/docs/fragments/info-tooltip) and confirm the demo still renders. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility Improvements** * Added descriptive labels to pricing information tooltips. * Improved screen reader context for compute estimates, features, and plan-specific pricing. * Added a default “More information” label for unlabeled tooltips. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
235488e66b |
fix(studio): guard two undefined dereferences crashing the table editor and SQL editor (#49412)
<!-- ccr-slack-attribution --> _Requested by **Ali Waseem** · [Slack thread](https://supabase.slack.com/archives/C063LNYJJKS/p1787336596649619)_ **Before:** editing a cell in the table editor could throw, and the edit was silently lost — the typed value vanished and nothing was saved. Separately, opening the SQL editor could throw before the editor rendered, and the global error boundary replaced the entire page, so there was no editor at all until a reload. **After:** a row change with no matching previous row is a no-op instead of a throw, and the SQL editor shows its normal loading state instead of taking down the page. Two independent undefined guards for two confirmed Sentry crashes, one per commit so either can be dropped on its own. **How:** the first commit moves the existing previousRow guard in `useOnRowsChange` above the `changedColumn` computation that dereferences it, and drops the non-null assertion that hid the problem from TypeScript. The second reads the snippet content in `deriveSnippetIdentity` through optional chaining, so a missing `snippets` map, or an entry without a `snippet`, resolves to still-loading — the same answer the old code gave for an id that is not in the map. Behaviour is unchanged in every case that did not crash. ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? **[K7M, Cannot read properties of undefined (reading 'idx')](https://supabase.sentry.io/issues/7681899596/)** — 4 events / 1 user — in `apps/studio/components/grid/components/grid/Grid.utils.tsx`. Inside `useOnRowsChange`, the callback passed to `Object.keys(rowData).find(...)` reads the candidate column off `previousRow` through a non-null assertion, three lines above the `if (!previousRow || !changedColumn) return` that was meant to protect it. `rows.find(...)` returns undefined whenever no row matches, and the assertion is why TypeScript never flagged the dereference. The four events came from one user inside about two minutes, so it is deterministic rather than a one-off, and every throw is an edit the user loses. **[K7J, Cannot use 'in' operator to search for a snippet uuid in undefined](https://supabase.sentry.io/issues/7680905437/)** — 1 event / 1 user, full-page crash — in `apps/studio/components/interfaces/SQLEditor/SQLEditor.utils.ts`, line 331. `deriveSnippetIdentity` applies the `in` operator to its `snippets` argument and then reads `snippets[id].snippet.content`. The parameter is declared required and non-optional, but `snippets` arrived undefined at runtime, so `in` threw and the error reached the global error boundary, which unmounted the whole SQL editor page. The `snippets[id].snippet` read on the same line is a second unguarded dereference: an entry without a `snippet` crashes identically. ## What is the new behavior? Both crashes become no-ops. - Grid: return early when `previousRow` is missing, then compute `changedColumn`, with the assertion removed. When a previous row is found, the code takes exactly the path it took before. - SQL editor: `snippets?.[id]?.snippet?.content === undefined` replaces the `in` check. A missing map, a missing entry, and an entry with no `snippet` all read as still loading, which is what the surrounding code already does while a snippet is being fetched. The parameter type is left required, since the only caller (`useSnippetIdentity.ts`) passes the store's `snippets` record, which is typed as always present — the type is not the thing that was wrong. Two test cases are added to the existing `deriveSnippetIdentity` block, which previously only passed fully populated maps: one for an undefined `snippets` map, and one for an entry missing its `snippet`. ## Additional context **Why `snippets` was undefined is unexplained.** The store initialises it to an empty object (`apps/studio/state/sql-editor/sql-editor-state.ts:34`) and its only reassignment writes an object, so there is no code path in studio that sets it to undefined. This commit is a defensive guard against a crash, not a root-cause fix, and nothing here should be read as an explanation. **Verification:** no local checks were possible in the authoring environment — the checkout has no `node_modules` and `pnpm install` cannot complete there, so typecheck, lint and the studio unit tests could not be run. CI on this PR is the only verification. --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
1cffe632e3 |
fix: webhook apikey (#47317)
## TL;DR Database webhooks/Cron jobs now add `apikey: <secret-key>` for edge function auth.. ## ref: - related to: https://github.com/supabase/supabase/pull/46890 - towards COM-269 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Improved edge function webhook authentication by automatically selecting the appropriate API key or authorization header format. * Authorization headers are now added or normalized when required, while preserving existing custom headers and supported credentials. ## Improvements * Simplified “Add header” and “Add parameter” controls with clearer labels. * Updated authentication actions to clearly describe the selected header type. ## Tests * Expanded coverage for key formats, authorization behavior, header preservation, and revised control labels. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Tomás Pozo <tomaspozo@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
8dcebc08ca |
fix: ESLint errors relating to accessibility in account preferences (#49301)
## 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? Improve toggle accessibility and `aria-label` for screen readers. ## What is the current behavior? Toggles have no accessible name or description because FormItemLayout is not properly linked to the Switch. An `aria-label` was missing. ## What is the new behavior? An `aria-label` and IDs have been added to associate the label with the switch and make the toggles accessible to screen readers. ## Additional context No visual changes have been made. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility** * Improved screen reader labels for password visibility controls. * Linked preference labels with their corresponding toggle controls. * Added descriptive identifiers to telemetry, dashboard, and hotkey settings for easier navigation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
66bfb8a22d |
chore(docs): add Tomás Torgal to humans.txt (#49483)
<!-- ccr-slack-attribution --> _Requested by **Ivan Vasilov** · [Slack thread](https://supabase.slack.com/archives/C0161K73J1J/p1787582317369359?thread_ts=1787582317.369359&cid=C0161K73J1J)_ ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update — adds a new joiner to `apps/docs/public/humans.txt`. ## What is the current behavior? Tomás Torgal is not listed in humans.txt. ## What is the new behavior? Tomás Torgal joined as Account Executive EMEA and asked to be added to humans.txt. Added in alphabetical order, between `Tomás Pozo` and `Tyler Hillery`. ## Additional context Part of the onboarding process. Name-only entry, matching the file's existing convention. Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
dbeb67e4b7 |
feat: add learn more link for enterprise mcp auth (#49475)
## 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? add "Learn more" link for enterprise mcp auth <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added a link to enterprise MCP authentication guidance in the advanced SSO settings. * Clarified the field label and description by updating “IDJAG” to “ID-JAG” terminology. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
166cab8dee |
docs: fix api link path in pg_net.mdx (#49478)
## 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? fix: Updates the Data API link in current permission section ## What is the current behavior? The link currently points to the wrong path, resulting in a 404 error. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the Data API permissions documentation link to point to the current API guide. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
665f043ecb |
fix(docs)link-ch-sql-syntax (#49473)
semi related to this PR: https://github.com/supabase/changelog/pull/234 Trying to ensure the information architecture links someone reading the debugging docs to the correct info on SQL syntax required by CH. This is a simple QOL change vs doing a larger IA fix ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? docs update ## What is the current behavior? Does not direct users to CH sql syntax doc ## What is the new behavior? Directs users to CH sql syntax doc ## Additional context https://supabase.com/changelog/48235-migration-of-supabase-management-api-logs-all-analytics-endpoint-to-logs-endpoint <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the MCP server description to link to Logs Explorer documentation for the supported ClickHouse SQL syntax used when querying logs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e478aabb80 |
Clarify pg_net net schema grants (#49472)
## 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? Documentation update — adds a new "Permissions" section to the pg_net guide. ## What is the current behavior? The pg_net docs don't explain the default permission model for the net schema. Customers running security reviews flag that net schema objects (net.http_request_queue, net._http_response) are readable by anon/authenticated via inherited PUBLIC grants, and some have run their own REVOKE scripts to lock this down. This breaks the pg_net background worker, since postgres (the role the worker runs as) inherits its own access through that same PUBLIC grant. ## What is the new behavior? Adds a "Permissions" section clarifying that the default grants are safe as-is, net isn't exposed through the Data API, and anon/authenticated are NOLOGIN roles with no direct database connection. ## Additional context For background and reviewer discussion on the accuracy of this, see the https://supabase.slack.com/archives/C02FHG9QQAF/p1787299415288589. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added permissions guidance for the `net` schema. * Clarified access available to `anon` and `authenticated` roles. * Explained why these permissions do not expose request data through the Data API or direct database connections. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Jeremias Menichelli <jmenichelli@gmail.com> |
||
|
|
3bc52101ee |
(docs/pipelines): early access destinations (#49304)
## What kind of change does this PR introduce? Docs update ## Summary - Add Early Access setup and reference guides for ClickHouse, DuckLake, and Snowflake. - Update Pipelines navigation and shared documentation with destination-specific data models, source requirements, schema-change support, and recovery behavior. - Keep all three destinations organization-gated. DuckLake is documented only as a Pipelines replication destination i.e. query compute remains external and this is not a Warehouse launch. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added ClickHouse, DuckLake, and Snowflake as Early Access Pipelines destinations. * Added BigQuery as a managed destination. * Added destination navigation and setup guides covering configuration, replication behavior, schema changes, type mappings, troubleshooting, and monitoring. * **Documentation** * Clarified destination availability, regional guidance, requirements, limitations, and processing behavior. * Documented destination-specific schema-change support, table identity requirements, reset behavior, and CDC replication modes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c32db2b80b | fix(studio): track resourceAccess='account' for legacy access tokens (#49448) | ||
|
|
18896e33de |
fix(studio): give two DropdownMenuTriggers asChild so they stop nesting buttons (#49264)
## 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. Two `DropdownMenuTrigger`s wrap a `Button` without `asChild`, so each renders a `<button>` inside a `<button>`. One of them also loses its `aria-label`, leaving an icon-only menu trigger with no accessible name. ## What is the current behavior? `DropdownMenuTrigger` forwards to `DropdownMenuPrimitive.Trigger`, which renders its own `<button>` unless `asChild` is set. So this: ```tsx <DropdownMenuTrigger> <Button variant="default" className="px-1" icon={<MoreVertical />} aria-label={`Open actions for ${hook.title}`} /> </DropdownMenuTrigger> ``` produces `<button><button/></button>`, which is invalid HTML, and puts the props on the inner element rather than on the thing that actually opens the menu. Measured by rendering `HookCard` before and after, rather than reasoning about it: | | before | after | | --- | --- | --- | | `container.querySelectorAll('button button').length` | 1 | 0 | | `aria-label` on `[aria-haspopup="menu"]` | `null` | `Open actions for Send Email` | That second row is the part worth caring about. The `aria-label` was written deliberately for a button whose only content is a `MoreVertical` icon, and it lands on the nested inner button instead of the trigger, so a screen reader gets no name for the control it actually operates. Two sites: - `components/interfaces/Auth/Hooks/HookCard.tsx`, the per-hook actions menu. This is the one with the orphaned `aria-label`. - `components/layouts/ProjectLayout/PauseFailedState.tsx`, the overflow menu next to "Download backup". ## What is the new behavior? Both get `asChild`, so the `Button` becomes the trigger. No nesting, and the props land where they were meant to. ## Additional context #48948 fixed exactly this in `RestoreFailedState.tsx`, which sits in the same directory as `PauseFailedState.tsx` and has the same overflow-menu shape. This is that fix applied to the two places it was not. I swept all 4398 `.tsx` files across studio, www, docs, design-system, ui-library, `packages/ui` and `packages/ui-patterns` for any Radix-style trigger (`DropdownMenu`, `Tooltip`, `Popover`, `Dialog`, `Sheet`, `AlertDialog`, `HoverCard`, `Collapsible`, `ContextMenu`, `Menubar`, `Select`, `Tabs`, `Accordion`) that wraps a button-like element without `asChild`. After discarding one false positive in `EdgeFunctionDetails.tsx`, where the `Button` is a sibling of `TabsTrigger` inside `TabsList` rather than its child, these two are the only ones left. So this should be the end of the pattern rather than the start of a series. No test added, matching what #48948 did for the same change. The `asChild` behaviour belongs to Radix, and a test asserting DOM nesting around two JSX attributes would be testing the library. I did verify it the other way round while developing: a throwaway render assertion failed on unmodified master with a nested-button count of 1 and a null trigger `aria-label`, and passed after the change. Happy to commit that assertion if you would rather have it in the suite. Gates: `test:prettier` passes repo wide, `typecheck --filter=studio --force` passes 9/9, `--filter studio run lint:ratchet` reports rules improved, and the tests covering both touched directories pass (18 files, 143 tests, including the `RestoringState` suite that came in with #48948). Freshman contributor. Found this with Claude Code's help by checking whether the `asChild` fix in #48948 had siblings, and I confirmed the nesting and the missing accessible name myself before touching anything. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved dropdown menu trigger behavior in the authentication hooks and project layout interfaces. * Existing buttons now correctly serve as menu triggers without changing available actions or menu behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f857be2063 |
feat: enable idjag for all (#49462)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? remove feature flag gate for enterprise mcp auth <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Advanced SSO settings are now available for all SSO configurations. * **Changes** * Removed organization-specific eligibility restrictions for advanced SSO settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
de2a7d8d9e |
Add view options to Query (#49447)
Currently Query tabs in explorer do not support view options e.g. table vs chart. This adds display state to query tabs to match the behaviour of Notebooks ## To test - create a query in explorer - Run a query - Set the display options via toolbar <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Query results can now be displayed as either a table or chart. * Chart settings are saved with each query draft and restored when reopened. * Display preferences are maintained independently across query drafts. * Editing a preview query now converts it into a permanent tab. * **Bug Fixes** * Invalid or legacy display settings safely fall back to the table view without removing saved drafts. * Charts and empty states now use the available editor space more effectively. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
caceeb429f |
[MUL-1336] fix(studio): show HA project costs as free during Alpha (#49383)
HA (Multigres) projects are free during Alpha, but the project creation form still presented the forced large compute as a real charge. The footer now shows **$0/m** for HA projects, with the usual compute price struck through + a "Free during Alpha" note in the cost-breakdown tooltip and the compute size dropdown. Follows the pattern from #49249. Addresses [MUL-1336](https://linear.app/supabase/issue/MUL-1336/bug-when-creating-new-projects). <img width="688" height="167" alt="Screenshot 2026-08-21 at 5 27 39 PM" src="https://github.com/user-attachments/assets/804b9243-77ae-4961-9083-5e1290734d3a" /> <img width="503" height="202" alt="Screenshot 2026-08-21 at 5 27 32 PM" src="https://github.com/user-attachments/assets/f217edd4-2204-4e5e-87f8-f54974e3c6fa" /> **Changed:** - `ProjectCreationFooter`: "Additional costs" shows `$0/m` when HA is on; the tooltip gains a "High availability projects are free during Alpha for up to 2 projects." sentence; the New-project row's price renders struck through with a "Free during Alpha" sub-line; the HA project's compute is excluded from "Total Monthly Compute Costs" (clamped at 0 so credits can't produce a negative total — a no-op for non-HA since spend already floors above zero) - `ComputeSizeSelector`: the per-option `$X/hour (~$Y/month)` line renders struck through with "Free during Alpha" beneath it when HA is on (both tagged `data-field="instance-details"` so the collapsed trigger keeps hiding them) - `ProjectCreationForm`: threads the watched `highAvailability` value into the footer The "Confirm compute costs" modal was already suppressed for HA by the existing `!values.highAvailability` guard — no change needed there. ## To test - On a paid org, open New Project and toggle High Availability on: the footer should read `$0/m` (brand green, no strikethrough), its ⓘ tooltip should show the HA sentence and the New row's `$110` struck through with "Free during Alpha", and the Total should exclude the $110; the compute dropdown's Large option should show its price struck through with "Free during Alpha" - Toggle HA off (and on/off a few times): all cost displays should revert exactly to normal — green real price, no strikethrough, no "Free during Alpha" anywhere outside the HA toggle's own description - With HA off and compute size Medium, submit: the "Confirm compute costs" modal should still appear as before (Cancel works) - Collapsed compute-size trigger should never show a price line or "Free during Alpha" in either state <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features - High-availability project options now show compute pricing as free during Alpha. - Standard compute prices are displayed with a strikethrough alongside the Alpha-free notice. - Project cost summaries accurately show no additional compute charge for high-availability selections. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
b9df7aaf9e |
[FE-3711] feat(studio): make compute config read-only for HA projects (#49359)
Makes the compute-size configuration on Settings → Infrastructure read-only for High Availability (Multigres) projects during Alpha — HA projects run on a single fixed compute size and resizing isn't supported yet (previously attempting one could leave a project stuck Resizing). Gated on `project.high_availability` via the existing `useHighAvailability()` hook — the same signal every other HA gate in Studio uses. **Changed:** - Compute size options other than the project's current size render with the existing locked treatment (greyed out, lock icon, tooltip) for HA projects, and the whole radio group is disabled - A `HighAvailabilityDisabledSectionNotice` in the Compute section explains that HA projects run on a fixed compute size during Alpha - The compute branch of `onSubmit` and the read-replica compute-recommendation handoff are skipped for HA projects, so a compute change can never reach `POST /billing/addons` - The "Contact Us" larger-sizes card is hidden for HA projects - Form initialization now also fires once the project loads for HA projects (disk-attribute queries never run on their cloud provider, so the existing reset effect never fired and the picker showed the `ci_micro` fallback as selected) **Added:** - Two MSW page tests in the Infrastructure suite covering the HA read-only state and the unchanged editable state for non-HA projects ## To test - On an HA (Multigres) project: Settings → Infrastructure should show a notice under Compute size, the project's current size selected, every other size locked with a tooltip, no "Contact Us" card, and clicking any option should never surface the "Review changes" bar - On a regular project: compute selection, "Review changes" → "Confirm changes", and the Contact Us card all behave as before - `pnpm vitest run "tests/pages/project/[ref]/settings/infrastructure.test.tsx"` Addresses [FE-3711](https://linear.app/supabase/issue/FE-3711/make-compute-configuration-read-only-for-mvp) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added High Availability notices and guidance to the Compute settings. * High Availability projects now show compute sizes as read-only, with explanations for unavailable options. * Hid the larger-instance contact option for High Availability projects. * **Bug Fixes** * Prevented unsupported compute resizing and add-on changes for High Availability projects. * Preserved compute resizing and review actions for standard projects. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
48cc37f0d2 |
refactor(studio): extract notebook cache eviction helper (#49414)
## Summary Part 1 of the FE-4247 stack ([FE-4247](https://linear.app/supabase/issue/FE-4247/assistant-invalidate-cache-after-notebook-editdeletion)). Pure refactor, no behavior change — extracts the notebook cache eviction logic that `ExplorerNotebookTabCoordinator` had open-coded into a shared helper, so the upcoming assistant create/update/delete cache invalidation (PR 2/3 in the stack) can reuse it instead of duplicating the two-cache-layer eviction dance. - New `evictNotebookFromCaches({ queryClient, projectRef, id, mode })` in `apps/studio/data/content/notebooks/notebook-cache.ts`. `mode: 'refresh' | 'remove'` selects `invalidateQueries` vs `removeQueries` on `contentKeys.resource`. Drops the notebook from `notebooksState` only when its status is `'saved'`, matching the original open-coded guard exactly. Returns whether it evicted, so callers can branch. - `ExplorerNotebookTabCoordinator` now calls the helper with `mode: 'remove'` instead of inlining the logic. ## Test plan - [x] `pnpm test:studio -- notebook-cache ExplorerNotebookTabCoordinator` — new helper tests (refresh/remove/dirty-guard/unknown-id) and existing coordinator tests all pass - [x] `pnpm typecheck --filter=studio` - [x] `pnpm lint --filter=studio` — 0 errors, no new warnings <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved detection of unsaved notebook changes for tab indicators and close confirmations. - Empty, never-saved notebooks are no longer included in discard prompts. - Improved cache cleanup when closing saved notebooks while preserving unsaved work. - Added safeguards for missing notebook records. - **Tests** - Added coverage for notebook cache refresh, removal, preservation, and no-op scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
fdf33e72c4 |
fix(studio): clean up onboarding returnTo paths (#49283)
## What kind of change does this PR introduce? Bug fix. Follow-up to #41041 and DEPR-318. ## What is the current behavior? Marketing "Start your project" links go to `/dashboard`, which redirects unauthenticated users to `/org` and sets `returnTo=/org`. That value survives when they switch from sign-in to sign-up, so email verification still lands on the org list instead of org creation. ## What is the new behavior? - Sign-in's **Sign up** link rewrites `returnTo=/org` (and `/organizations`) to `/new` - Docs mobile menu, www homepage/product CTAs, and solution page CTAs link to `/dashboard/sign-up` for guests - Signed-in visitors get the dashboard URL instead, so they never hit the sign-up form - Shared `DASHBOARD_SIGN_UP_URL` / `getDashboardCtaHref` helpers for www Stacked on #41041. ## To test Stacked on #41041. The studio preview below includes both PRs. www and docs have their own previews. ### Studio: sign-in → sign-up rewrite Using the [studio-staging preview](https://studio-staging-git-dnywh-fixonboarding-return-to-supabase.vercel.app/) from Vercel checks: 1. Open the preview while logged out. It should land on `/dashboard/sign-in?returnTo=%2Forg` 2. Click **Sign up**. Expect the URL to include `returnTo=%2Fnew` ### Optional: www CTAs Using the [www preview](https://zone-www-dot-com-git-dnywh-fixonboarding-return-to-supabase.vercel.app/): 3. Logged out: homepage, product, or solutions **Start your project** should go to `/dashboard/sign-up` 4. Logged in: the same CTAs should go to `/dashboard` (not sign-up) (thought this will be hard if not impossible to test on staging) ### Optional: docs CTAs Using the [docs preview](https://docs-git-dnywh-fixonboarding-return-to-supabase.vercel.app/): 5. On mobile nav while logged out, click **Start your project**. Expect `/dashboard/sign-up` ### Compare on supabase.green Optional. Just to show what happens currently on `master`: 6. Open **supabase.green** while logged out, then click **Sign up** from `/dashboard/sign-in?returnTo=%2Forg`. `returnTo` should stay as `/org` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Start-project and sign-up links now direct visitors to registration while signed-in users continue to reach the dashboard. * Homepage, product, solution, and mobile navigation CTAs now provide consistent authentication-aware destinations. * Sign-up links preserve return destinations and existing navigation parameters. * **Bug Fixes** * Corrected mobile navigation and marketing CTA links that previously sent visitors to the dashboard root instead of the appropriate sign-up flow. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ee931e49a1 |
fix(studio): send new signups to org creation directly (#41041)
## What kind of change does this PR introduce? Bug fix. Resolves DEPR-318. ## What is the current behavior? New users who confirm their email land on `/sign-in`, then `/organizations`, then get bounced to `/new` via a `useEffect`. Cancelling org creation with zero orgs sends them back to `/organizations`, which immediately redirects into `/new` again. ## What is the new behavior? - Signup email verification redirects to `/new` directly - `/organizations` with zero orgs shows the existing empty state instead of force-redirecting ## To test ### One-time setup Assuming you don’t already have a staging account with **zero** orgs: 1. On **supabase.green**, sign up with a fresh email and confirm it 2. Stop at org creation. Do **not** create an org ### On this PR Using the [studio-staging preview](https://studio-staging-git-dnywh-fixremove-org-redirect-supabase.vercel.app/) from Vercel checks: 4. Sign in on the preview with that account 5. Open `/dashboard/organizations`. Expect the **Create an organization** empty state, with no redirect to `/new` 6. Open `/dashboard/new`, click **Cancel**. Expect to land on `/organizations` and stay there ### Compare on supabase.green Optional. Just to show what happens currently on `master`: 7. Repeat steps 3–5 on **supabase.green**. `/organizations` should bounce to `/new`, and **Cancel** should send you back into org creation <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved signup redirects by preserving valid destinations and relevant query parameters. * Added safer fallback behavior for missing, invalid, or unsupported destinations. * Improved handling of signup redirects provided in multiple formats. * Prevented automatic redirection from the organizations page when no organizations exist. * **Style** * Updated the organizations page title capitalization for consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
21a27eeb4f |
feat(www): canonicalize homepage markdown at /index.md (#49384)
The www root markdown lived at an accidental URL: `/.md` served the
homepage markdown only because middleware strips the `.md` suffix and
the empty slug fell through to the homepage allowlist entry, while the
canonical-looking `/index.md` 404'd. The served markdown also opened
with stale legacy positioning copy that no longer matches the site. I
renamed the homepage content slug to `index` end-to-end so `/index.md`
is the one canonical markdown URL.
**Changed:**
- **`/index.md` serves the homepage markdown (200 `text/markdown`)**:
`content/md/homepage.md` renamed to `index.md`; the middleware bare-root
slug mapping, the generator's sort special-case, and the homepage
alternate tag follow, so the tag now advertises `/index.md`.
- **Legacy aliases 308 to the canonical URL**: `/.md`, `/homepage.md`,
and bare `/index` redirect via `lib/redirects.js`; `/llms/homepage.txt`
retargeted straight to `/index.md` to avoid a redirect chain. New
`next.config.test.ts` assertions pin all four.
- **Positioning refreshed**: the markdown now opens with "Supabase is
the Postgres development platform" (matching the site title), replacing
the outdated tagline.
- **Generator safety**: the redirect-exclusion filter in
`generateMdContent.mjs` now exempts the `index` slug (its HTML page is
`/`, not `/index`, so a `/index` redirect never refers to it), and the
build fails if `content/md/index.md` ever goes missing while middleware
still maps `/` to the `index` slug.
- **CI actually runs the new assertions**: I widened the `www-tests.yml`
paths filter to include `apps/www/lib/**/*.js`,
`apps/www/content/md/**`, and `apps/www/scripts/**/*.mjs`. It previously
only matched `.ts*` and the next.config files, so a PR touching only
`lib/redirects.js`, the markdown content, or the generator would skip
the tests that pin these redirects.
**Note:** the existing homepage alternate tag still exists, re-pointed
to the canonical URL. Whether the homepage should advertise a markdown
sibling at all is a separate decision; leaving it aimed at a 308 would
break tag consumers. Positioning wording is editorial, happy to tweak.
## To test
Tested on Vercel preview:
- [x] `curl -si <preview>/index.md`: expect 200 `content-type:
text/markdown`, body opens with the Postgres development platform
positioning and no longer contains the old tagline
- [x] `curl -sI <preview>/.md`: expect 308 with `location: /index.md`
- [x] `curl -sI <preview>/homepage.md` and `curl -sI
<preview>/llms/homepage.txt`: expect 308 with `location: /index.md`
- [x] `curl -sI <preview>/index`: expect 308 with `location: /`
- [x] `curl -s -H "Accept: text/markdown" -o /dev/null -w "%{http_code}
%{content_type}" <preview>/`: expect `200 text/markdown` (bare-URL
negotiation unchanged)
- [x] `curl -s <preview>/ | grep -o 'type="text/markdown"
href="[^"]*"'`: expect href ending `/index.md`
## Linear
- fixes GROWTH-1117
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added support for `/index.md` as the canonical Markdown representation
of the homepage.
- Added permanent redirects for legacy homepage Markdown and text URLs.
- Added `/index` to `/` redirect handling.
- **Bug Fixes**
- Updated homepage metadata, alternate links, Markdown negotiation, and
content generation to consistently use the new canonical path.
- Improved homepage content description.
- **Tests**
- Expanded coverage for homepage Markdown routes, redirects, and URL
matching.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
5c6ef8ae3d |
Joshenlim/fe 4221 explorer tab behaviours to mimic sql editor (#49386)
## Context Improves the tab behaviour for explorer to follow the SQL Editor - Tabs now start as preview tabs and become permanent once you start interacting with them - Query Tabs become permanent as soon as you start typing in the editor - Chat tabs become permanent as soon as you start typing in the chat input - Notebook tabs become permanenet as soon as you make any changes to the notebook - Notebooks with unsaved changes will show the orange dot indicator <img width="197" height="67" alt="image" src="https://github.com/user-attachments/assets/3005c379-a49a-4cd8-8d90-65406b186141" /> - Closing a notebook tab with unsaved changes will show a confirmation dialog - Except if the new notebook has no content (no changes) <img width="375" height="218" alt="image" src="https://github.com/user-attachments/assets/6ad10779-6415-4c55-bb4f-61d938e744c9" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Explorer chat, query, and notebook tabs now begin as previews and become permanent when edited or saved. * Added unsaved-change indicators and close confirmation for edited notebook tabs. * Confirmed closure of edited notebooks now discards unsaved changes. * **Bug Fixes** * Improved restoration and persistence of Explorer drafts. * Notebook saves now reflect the latest edits and tab state. * Prevented stale save responses from incorrectly marking newer edits as saved. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4dc973048d |
Add confirmation modal when running notebook if notebook contains query cells that aren't read only (#49376)
## Context Adds a confirmation modal when hitting "run notebook" if the notebook contains any query cells that involve any sort of mutation (insert, update, alter, etc, etc). Also gives users the option to run the notebook's read only cells as an alternative. <img width="432" height="355" alt="image" src="https://github.com/user-attachments/assets/0413a3ad-5419-4c83-8bf3-976bfa683b9a" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added confirmation prompts before running queries that may modify data or database structure. * Prompts identify potentially mutating notebook queries and allow running read-only cells instead. * Query execution now includes checks for destructive operations and missing row-level security, with optional automatic setup. * Notebook runs use the latest saved and unsaved SQL and reliably reset execution status. * **Bug Fixes** * Improved notebook layout behavior so content shrinks correctly within flexible sections. * **Tests** * Expanded coverage for mutation detection, comments, multiple statements, live SQL, and cell filtering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
34454037d3 |
clean up docs admonition structure (#48669)
## What kind of change does this PR introduce? Docs update. Resolves DEPR-634. Stacked on #48664. The linter package and CI revision pins will be updated after [supa-mdx-lint#121](https://github.com/supabase-community/supa-mdx-lint/pull/121) merges and is released. ## What is the current behavior? Admonition body content can contain structural headings, which inherit prose spacing and produce awkward callout layouts. Standalone Docs actions are also rendered as ordinary body content in two places. | Before | | --- | | <img width="1264" height="840" alt="70168" src="https://github.com/user-attachments/assets/00aa7620-a6b4-452c-971f-b3ce2eda0e8c" /> | | _Recent violation with Markdown header in `children`. Notice the big gap up top._ | ## What is the new behavior? - Documents that admonition titles belong in the `title` prop, standalone calls to action belong in `actions`, and document sections belong outside admonitions. - Configures heading-inside-admonition violations as errors for the forthcoming linter release. - Moves the UI-library and wrapper dashboard buttons into the existing `actions` slot without changing the shared component. Validated with the forthcoming linter across all 810 Docs sources, Docs type-checking, targeted ESLint and Prettier checks, and desktop/mobile rendering. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified admonition guidelines for optional titles, headings, rich content, and standalone calls to action. * Improved guidance on when contextual links and interactive examples belong in admonition content. * **Style** * Updated documentation call-to-action buttons to use the designated actions area. * **Quality Improvements** * Added validation to prevent headings inside admonitions and maintain consistent formatting. * Updated documentation linting to apply the latest validation rules. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a18253f7c7 |
QueryEditor to have the same validations as per SQL editor (#49380)
## Context Adds the same validations such as UPDATE without where clause, or destructive query into the QueryEditor of explorer / notebooks. Kicks in for both notebook cells and query tab <img width="887" height="718" alt="image" src="https://github.com/user-attachments/assets/27757d41-e5df-4473-9278-ec30ff2306ca" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added safety checks for potentially destructive database queries. - Queries may pause for confirmation before execution. - Added optional RLS statement handling during query execution. - Added warnings and cancellation support for pending query runs. - Added read-only mode to prevent SQL edits and proposal acceptance. - **Bug Fixes** - SQL commits now use the current editor content. - Discarding a proposed query is handled directly and reliably. - **Tests** - Added coverage for query approval, cancellation, and RLS-enabled table creation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
233cbdc8e5 |
Restore notebook diff preview for completed updates (#49402)
## Summary This is **PR 3 of 3** in the FE-4243 stack fixing "Notebook update proposal shows 'unapplyable' error for already-completed updates." - Consumes the `previous_content` field added by PR 2 (#49401) to reconstruct diffs for already-applied notebook updates - Restores the diff preview that PR 1 initially dropped — completed updates now show the full before/after instead of a generic "Notebook updated" message - Uses the same diff derivation function called pre-approval, guaranteeing the rendered diff matches what was shown during confirmation - Includes defensive fallback handling for older persisted chats (before `previous_content` existed) and edge cases **Depends on**: PR 2 (#49401) merging first — this PR consumes the `previous_content` field from that server change. Resolves FE-4243 ## Test plan - ✅ 19/19 tests pass in NotebookProposalRenderer.test.tsx (2 confirmed as real regressions) - ✅ 118/118 tests pass in full AIAssistantPanel suite - ✅ Typecheck: clean on modified files - ✅ ESLint: zero errors/warnings on changed files - ✅ Lint ratchet: passes (some rules improved) - ✅ New regression tests cover: delete_cell, insert_cell, missing previous_content, and operations that no longer reconcile - ✅ No notebook fetch in completed update tests (proves no redundant re-fetching) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added visual previews showing notebook changes, including inserted and deleted cells, when prior content is available. * Prevented duplicate cells from appearing in update previews. * Retained a compact completion message when change details are unavailable or inconsistent. * Ensured previews are shown only for the relevant notebook. * **Tests** * Added coverage for notebook update previews, deletion and insertion diffs, duplicate prevention, notebook matching, and fallback behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8920439569 |
Expose previous notebook content in update_notebook (#49401)
## Summary - Plumb pre-update notebook snapshot through `update_notebook` tool response as `previous_content` - Add sanitizers in `tool-sanitizer.ts` to strip snapshot before model sees it - Add client-side stripping in `prepareMessagesForAPI` to avoid re-uploading snapshot on subsequent turns - This is PR 2 of 3 fixing Linear issue FE-4243 (notebook update proposal shows 'unapplyable' error for already-completed updates) - Ships no visible behavior change on its own; enables PR 3 to restore diff preview for completed updates ## Test plan - [x] Unit tests: 80/80 passing across notebook-tools.test.ts, tool-sanitizer.test.ts, generate-assistant-response.utils.test.ts, message-utils.test.ts, and mock-tools.test.ts - [x] Typecheck: clean for all changed files - [x] ESLint: zero errors, lint:ratchet passes (exit 0) - [x] Integration: previous_content is correctly populated with pre-update notebook, stripped before model context, and stripped on client-side re-upload <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Notebook updates now retain previous content for recovery and history. - AI responses expose only the notebook’s ID and name, keeping previous content out of model-visible data. - **Tests** - Added coverage for notebook update results, content sanitization, and message preparation, including cases where previous content is absent or preserved. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b2a216b617 |
feat(billing): Use the customer data endpoint to update billing emails (#49160)
## What kind of change does this PR introduce?
Change the update billing email component so it uses the update customer
endpoint instead of the update org endpoint. This allows users that have
the BILLING_WRITE permission to use the endpoint to update relevant
organization data, while keeping the restrictions of the update
organization endpoint that allow updating other values (e.g. the org
name).
This change requires an update in the Update Customer endpoint to
support billing email updates. Do not merge until that is deployed.
## What is the current behavior?
- Admins are not allowed to update the billing emails of an
organization.
- The update organization endpoint (`PATCH
/platform/organizations/{slug}/`) is used to update the billing email
details.
## What is the new behavior?
- Both admin and owners are allowed to update the billing email details.
- The update customer endpoint (`PUT
/platform/organizations/{slug}/customer`) is used to update the billing
email details.
### Additional Context
[Platform PR](https://github.com/supabase/platform/pull/37145), needs to
be deployed first.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Billing email settings now use customer profile information.
* Added support for updating primary and additional billing email
addresses.
* Billing customer details now display address and billing name
information.
* **Bug Fixes**
* Prevented unrelated billing profile fields from being overwritten
during updates.
* Billing forms now synchronize correctly when customer profile data
changes.
* Removed unnecessary organization name requirements from billing
profile updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
0218de559b |
fix(studio): validation scroll area bug in scoped pat (#49395)
## 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? When trying to submit the scoped pat creation form a second time, after expanding accordion in the `<ScrollArea />` the `scrollTo` was breaking the height of the container. This PR fixes that. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved the missing-permissions warning when creating scoped access tokens. - The warning now scrolls into view after each invalid submission attempt, using smooth scrolling when supported. - Prevented repeated scrolling during unrelated form updates or motion-preference changes. - Selecting a permission or applying a non-empty preset clears the warning state. - Improved accessibility by respecting reduced-motion preferences. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c172195269 |
test(studio): add eval cases for list_databases-driven notebook creation (#49398)
## Summary - Adds three eval cases exercising the behavior this stack wires up: a happy path where the model calls `list_databases` before targeting a named read replica, a guard against fabricating an identifier when the user names a region/replica `list_databases` doesn't actually return, and a guard against targeting a non-primary database when the user never asked for one. Part 6/6 (final) of the stack for FE-4225 (expose valid database identifiers to the notebook AI agent). Stacked on #49334. ## Test plan - [x] Ran all three cases against the real model; inspected transcripts directly - [x] Re-verified reworded `correctAnswer` text against real outputs via the correctness evaluator - [x] `pnpm --filter studio exec tsc --noEmit` passes - [x] `prettier --check` passes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added evaluation coverage for selecting the correct database replica when creating notebooks. * Verified primary-database defaults when no database is specified. * Added checks to prevent fabricated database identifiers when a requested replica is unavailable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
27ff49c145 |
Stop re-deriving notebook update diffs after completion (#49399)
## Summary
- Fixes false-negative "This update can't be applied" warning for
completed notebook updates (FE-4243)
- When `state='output-available'` (tool completed), skips notebook fetch
and diff derivation
- Renders compact "Notebook updated: {name}" instead of a phantom/failed
diff
- `UnapplyableNotebookUpdateNotice` now accepts and forwards
`footerAction` prop, preserving "Open notebook" link
- Different warning copy for terminal confirm states
(success/error/denied): "Preview unavailable / notebook has changed"
instead of "can't be applied"
- Preserves diff derivation for non-completed states
(output-denied/error)
This is PR 1 of a 3-PR stack; PRs 2-3 restore the full diff preview for
completed updates (requires server snapshot).
Towards FE-4243
## Test plan
- [x] All 15 tests in NotebookProposalRenderer.test.tsx pass
- [x] Typecheck clean
- [x] ESLint clean
- [x] Regression tests added: completed updates with missing target
cells (auto & manual approval)
- [x] Confirms denied/error states still derive against live content
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added clearer status handling for AI-generated notebook updates.
- Completed updates now show a confirmation with the notebook name when
available.
- Update actions and footer controls now adapt to the proposal’s current
state.
- **Bug Fixes**
- Improved messaging when notebook changes prevent an update preview
from being reconstructed.
- Preserved accurate previews for denied or failed updates using the
notebook’s latest content.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|