Commit Graph
300 Commits
Author SHA1 Message Date
Beng EuandIvan Vasilov b3dc867f90 chore(studio): clear .next/dev/cache in predev, to mitigate high memory usage from cache buildup (#45199)
Proposed mitigation, the obvious tradeoff is that clearing the cache
will make compilation slower on subsequent dev server starts, but more
consistent.

Various people have been observing `next-server` use up to ~34 GB
memory. I've observed 12.59 GB memory, with ~1.5k `postcss` processes:
```
ps aux | grep postcss | grep -v grep | wc -l
1526
```
Going down to 3 `postcss` process and 4.71 GB memory after clearing
cache:
```
ps aux | grep postcss | grep -v grep | wc -l
3
```


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

* **Chores**
* Development infrastructure: adds an automated pre-development step
that clears the local dev cache before starting the development server
by introducing a new lifecycle hook and supporting cleanup script;
purely maintenance-oriented with no user-facing changes or functional
impact.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-04-24 10:11:57 +02:00
Matt Rossman c0c6f70f02 chore(studio): bump braintrust 3.4.0 → 3.9.0 (#44729)
Bumps braintrust from 3.4.0 to ~~3.7.1~~ 3.9.0

~~Notable fix: v3.7.0 preserves the returned promise in tracing channel
hooks, which should resolve incorrect duration reporting in the
dashboard (braintrustdata/braintrust-sdk-javascript#1617)~~

3.9.0 includes this fix for double counted durations
https://github.com/braintrustdata/braintrust-sdk-javascript/pull/1769

See eval results in comment below, this fixes the issue where LLM
Duration was clocking in larger than total Duration.

<img width="2384" height="1548" alt="CleanShot 2026-04-21 at 09 27
36@2x"
src="https://github.com/user-attachments/assets/7ad5a75c-e3c4-44e1-98d8-ad4849049f7a"
/>


Closes AI-578

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

## Summary by CodeRabbit

* **Chores**
  * Updated Braintrust dependency to version 3.9.0

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-21 10:17:36 -04:00
Gildas Garcia 1a0fc71151 fix: improve performances on large schema image export (#45042)
## Problem

When users export a large schema, the UI becomes unresponsive for a long
time.
This is because the underlying `html-to-image` library calls
`getComputedStyle` for every node.

## Solution

- Upgrade `html-to-image` to its latest version
- Use the new `includeStyleProperties` property to call
`getComputedStyle` only once
- Extract the image export logic into a new hook

## How to test

- Open
https://studio-staging-git-gildasgarcia-fe-2998-suggest-e7fb9e-supabase.vercel.app/dashboard/project/pdmusqfyrsascxykhlge/database/schemas?schema=auth
- Rearrange tables so that they are all visible
- Export the schema as png
- It should takes (~10-15secs)

- Do the same in this PR preview
https://studio-staging-gy13zepyf-supabase.vercel.app/dashboard/project/pdmusqfyrsascxykhlge/database/schemas?schema=auth
- It should takes ~3-5secs



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

* **Improvements**
* Improved schema export: more reliable PNG/SVG exports that better
preserve visual styling, show progress state during downloads, and
surface success/error notifications.
* **Chores**
* Updated image-export library to a newer version for improved
compatibility and performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-20 16:12:37 +02:00
Ali Waseem 3ed436de74 feat: new shortcuts hook with registrations (#44954)
## 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?

- Brand new hook APIs for registering shortcuts using tanstack hotkeys
- Support for command menu injection when shortcut is added

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

* **New Features**
* Centralized keyboard shortcuts system with per‑shortcut registration
and per‑user enable/disable preferences stored locally
  * Added a "Copy results as Markdown" shortcut (Mod+Shift+M)
* Shortcuts can be surfaced in the Command Menu with a visual shortcut
badge for discoverability

* **Documentation**
* Legacy keyboard shortcut hooks marked as deprecated and documentation
updated to point to the new shortcut API
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-17 08:20:36 -06:00
Gildas Garcia 16fd60134d chore: migrate auth providers form to zod (#44865)
## Problem

We currently have 2 libraries for schema validation: `yup` that was used
with `formik` and `zod` which is now the preferred one.

## Solution

- Migrate the auth providers form to `zod`
- Remove `yup`

No visual changes.

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

* **Bug Fixes**
* Preserve empty numeric inputs in auth provider forms to avoid
unintended conversion.

* **Refactor**
* Migrated auth provider form validation to a new validation system for
more consistent rules.
* Strengthened provider-specific validation (email, phone/SMS, OAuth,
SAML, Web3), added improved SMS test-OTP/date checks, and adjusted
initial handling for password-required-characters.

* **Chores**
  * Removed an unused validation dependency from project packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-16 15:27:29 +02:00
Gildas Garcia 0395fd969f chore: upgrade react-markdown (#44913)
## Problem

We'd like to update react to `19` but many of our dependencies don't
support it.

## Solution

Update those dependencies. This PR focuses on `react-markdown`

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

* **Chores**
* Upgraded react-markdown to 10.1.0 (and remark-gfm to 4.0.0) across
projects for improved Markdown support.
* **Style**
* Adjusted Markdown rendering so typography and spacing are applied via
surrounding containers, improving consistent styling across docs and UI.
* **New Content**
  * Added a new RSS feed item for a recent blog post.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-16 09:12:43 +02:00
Alex Hall d70ed2ef76 chore: Add new OAuth scopes for analytics config to studio (#44826)
## Summary

Adds support for new OAuth scopes for reading and writing analytics
config to the app creation dialog and consent screen.

Depends on https://github.com/supabase/platform/pull/31539
2026-04-15 15:59:43 -04:00
Gildas Garcia bacd524b22 chore: update react-hook-form (#44893)
## Problem

We'd like to update react to `19` but many of our dependencies don't
support it.

## Solution

Update those dependencies. This PR focuses on `react-hook-form`

## How to test

Play with some forms, especially those that use arrays of values
(database/enumerated types for instance) and the highly dynamic ones
(auth providers for instance)

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

## Summary by CodeRabbit

* **Chores**
* Bumped the form-handling library version across apps and packages for
improved compatibility and stability.

* **Refactor**
* Improved component form typings and generics in the studio to increase
type safety and reduce potential runtime issues.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-15 17:27:06 +02:00
Alaister YoungandAlaister Young 1b1d05ff96 chore: upgrade vite to v8 and vitest to v4 (#44833)
Upgrade vite and vitest to their latest major versions across the
monorepo, along with related packages.

**Changed:**
- `vite` catalog: `^7.3.2` → `^8.0.8` (Rolldown replaces esbuild/Rollup)
- `vitest` catalog: `^3.2.0` → `^4.1.4`
- `@vitejs/plugin-react`: `^4.3.4` → `^6.0.1`
- `@vitest/coverage-v8`: `^3.2.0` → `^4.1.4`
- `@vitest/ui`: `^3.2.0` → `^4.1.4`
- `vite-tsconfig-paths`: `^4.3.2` / `^5.1.4` → `^6.1.1`

**Pinned to vite 7:**
- `apps/lite-studio` — `@react-router/dev` hasn't declared vite 8
support yet
- `blocks/vue` — Nuxt plugins (`vite-plugin-inspect`, `vite-dev-rpc`,
`vite-hot-client`, `vite-plugin-vue-tracer`) haven't declared vite 8
support yet

**Test fixes for vitest 4 breaking changes:**
- **`apps/studio/lib/api/snippets.utils.test.ts`** — Replaced
`vi.mock('fs/promises')` automock with an explicit factory. Vitest 4's
automocking doesn't create mock functions for getter-based exports on
Node built-ins, so `mockedFS.access.mockResolvedValue` etc. were
`undefined`.
- **`apps/studio/lib/api/self-hosted/functions/index.test.ts`** —
Changed `mockReturnValue` to `mockImplementation(function() { ... })`
for a constructor mock. Vitest 4 no longer allows `mockReturnValue` when
the mock is called with `new`.
- **`apps/studio/tests/pages/api/mcp/index.test.ts`** — Changed arrow
function to regular `function` in `mockImplementation` for
`StreamableHTTPServerTransport`. Arrow functions can't be constructors,
and vitest 4 now enforces this.
- **`packages/ui-patterns/vitest.setup.ts`** — Changed `ResizeObserver`
mock from arrow function to regular `function` for the same constructor
enforcement reason. This was crashing Radix popover rendering in jsdom.

## To test

- `pnpm test:studio` — all 226 test files should pass
- `pnpm --filter ui-patterns vitest run` — all 183 tests should pass
- `pnpm --filter www test -- --run` — all 19 tests should pass
- `pnpm --filter ui vitest run` — all tests should pass
- `pnpm --filter dev-tools vitest run` — all tests should pass
- `pnpm --filter ai-commands vitest run` — all tests should pass

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

* **Chores**
* Standardized and updated development tooling versions and version
sources for consistent installs across the repo (Vite, Vitest,
vite-tsconfig-paths and related plugins/catalog entries).
* **Tests**
* Improved test mocks and typings (updated mock
factories/implementations and tightened spy/type assertions) to increase
test reliability and compatibility with updated tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-04-16 00:13:48 +09:00
Gildas Garcia 74e8bb656f chore: upgrade framer-motion (#44906)
## Problem

We'd like to update react to `19` but many of our dependencies don't
support it.

## Solution

Update those dependencies. This PR focuses on `framer-motion`

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

## Summary by CodeRabbit

* **Chores**
* Updated animation library dependencies to the latest compatible
versions across applications and packages to ensure consistent
performance and stability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-15 17:07:56 +02:00
Alaister YoungandAlaister Young f8183479e7 chore(studio): switch to type: module and convert configs to ESM/TS (#44839)
Switch studio's package.json to `"type": "module"` so the package runs
as native ESM. This aligns the runtime module system with what we
actually write (`import`/`export`), improves tree-shaking, and reduces
friction with ESM-only dependencies.

**Changed:**
- `next.config.js` → `next.config.ts` – ESM imports/exports, proper TS
types, fixed type narrowing on redirect `has` and `basePath` fields
- `csp.js` → `csp.ts` – `module.exports.getCSP` → named `export
function`
- `tailwind.config.js` → `tailwind.config.ts` – ESM imports
- `postcss.config.js` – `module.exports` → `export default` (stays `.js`
since PostCSS doesn't support TS configs)

**Removed:**
- Unused `path` import in next config
- Deprecated Sentry `hideSourceMaps` option (default behavior in Sentry
v10)

**Added:**
- Type declaration for `config/tailwind.config` CJS package

## To test

- A general smoke test of studio should suffice

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

* **Refactor**
* Modernized the Studio package to ES module style and improved
TypeScript typings and config declarations to reduce build/runtime
issues.
* Updated styling and post-processing configuration format for more
consistent tooling behavior.

* **Chores**
* Updated code ownership entries to reflect migrated/renamed
configuration files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-04-14 18:44:28 +09:00
Alaister YoungandAlaister Young c31230a90e chore(studio): remove @headlessui/react dependency (#44845)
Remove `@headlessui/react` as a direct dependency from both
`apps/studio` and `packages/ui`. It's incompatible with React 19 (at the
pinned v1 version) and overlaps with our existing Radix/shadcn
primitives.

The only usage was the `<Transition>` component in 3 files + a dead
`Overlay` component in `packages/ui`.

**Removed:**
- `@headlessui/react` from `apps/studio/package.json` and
`packages/ui/package.json`
- Dead `packages/ui/src/lib/Overlay/` directory (not exported or
imported anywhere)

**Changed:**
- `ChooseFunctionForm.tsx` — replaced `Transition` with a shadcn
`Accordion` for the "View definition" toggle
- `FileExplorerColumn.tsx` — replaced `Transition` with `framer-motion`
`AnimatePresence` for drag-over overlay
- `PreviewPane.tsx` — removed `Transition` wrapper entirely (wasn't
visually animating on prod), replaced with simple conditional render

Note: `@headlessui/react` will remain in `pnpm-lock.yaml` as a
transitive dependency of `@graphiql/react` and
`@graphiql/plugin-doc-explorer` — that's expected and not something we
control.

## To test

- **Triggers page** (`/dashboard/project/_/database/triggers`): Create
or edit a trigger, click "Choose a function" to open the side panel.
Click "View definition" on a function row — the SQL definition should
expand/collapse with a smooth height animation. Clicking the row itself
should still select the function.
- **Storage explorer**
(`/dashboard/project/_/storage/buckets/<bucket>`): Navigate into a
folder, drag a file over the column — the drag overlay should fade
in/out smoothly.
- **Storage file preview**
(`/dashboard/project/_/storage/buckets/<bucket>`): Click on a file — the
preview pane should appear on the right (no animation, same as current
prod behaviour).

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

* **Refactor**
* Replaced several transition wrappers with new animation/mounting
behavior for overlays, preview panes, and drag-over UI to improve
consistency and responsiveness.
* Swapped the function-definition toggle for an Accordion and updated
click handling to prevent accidental row selection.
* Removed the legacy overlay component, its context, and associated
overlay styling.

* **Chores**
  * Removed HeadlessUI dependency from project packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-04-14 17:51:29 +09:00
K-Dog (Kevin) 7cc86b8783 chore: bump next to 16.2.3 / turbo to 2.9.6 (#44798)
Next.js 16.2

• Up to ~60% faster rendering
• Up to ~400% faster 𝚗𝚎𝚡𝚝 𝚍𝚎𝚟 startup
• Server Function 𝚍𝚎𝚟 logging
• Redesigned error page
• Better hydration errors
• 𝙴𝚛𝚛𝚘𝚛.𝚌𝚊𝚞𝚜𝚎 display in error overlay

https://nextjs.org/blog/next-16-2

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

* **Chores**
* Updated core build/dev tooling versions for more predictable installs
(analyzer and Turbo bumped).
* Relaxed workspace release gating by reducing minimum release age and
narrowing the list of tooling exclusions, streamlining staged upgrades.
* No runtime or public API changes; configuration and tooling-only
updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-13 16:01:57 +08:00
Charis bf46092290 ci: add safesql ratchet (#44678)
We are currently migrating to the safeSql utility for all SQL arguments
of executeSql. During the migration, executeSql will continue to accept
plain strings for backwards compatibility. Adding a custom ESLint rule
so we can ratchet this and prevent new calls of executeSql with plain
strings.

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

## Summary by CodeRabbit

* **New Features**
* Added SQL safety validation throughout the application to enforce
secure query construction and prevent SQL-related vulnerabilities
* Introduced type-aware linting to identify and catch type-related
issues during development and continuous integration processes

* **Chores**
* Enhanced continuous integration pipeline with improved code quality
enforcement

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-09 15:32:33 -04:00
Gildas Garcia 1c228ad18c Chore dnd kit supabase grid columns sort (#44654)
## Problem

We currently have 3 different libraries for drag & drop, two of which
are not actively maintained anymore.

## Solution

Migrate all usage of the two unmaintained libraries to DndKit.
This PR focuses on using DndKit instead of `react-dnd` for column
reordering in the table editor

## Screencast


https://github.com/user-attachments/assets/54fb36f4-5671-42e2-9698-2ae928a69f55

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

* **New Features**
* Column drag-and-drop rebuilt with a live drag preview and improved
pointer/keyboard handling

* **Improvements**
* More reliable column reordering with refined move/freeze/unfreeze
behavior and stable index recomputation
* Standardized column type/format display and simplified grid rendering

* **Accessibility**
  * Added accessible labeling for column actions controls

* **Tests**
* End-to-end locator updated to target the column actions button
deterministically
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-08 16:09:18 +02:00
Gildas Garcia 8923d52511 chore: use dndkit for table editor columns sorting (#44617)
## Problem

We currently have 3 different libraries for drag & drop, two of which
are not actively maintained anymore.

## Solution

Migrate all usage of the two unmaintained libraries to DndKit.
This PR focuses on using DndKit instead of `react-beautiful-dnd` for
table editor columns sorting

## Screencast


https://github.com/user-attachments/assets/7c0bd298-4115-4c41-9dac-644c546d2c80

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

* **Improvements**
* Redesigned column drag handle with clearer grab affordance, hover and
disabled states.
* More reliable column reordering — drag-and-drop behaves consistently,
including edge cases when moving columns.
* Smoother drag interactions and improved visual feedback while moving
columns.

* **Chores**
* Replaced legacy drag-and-drop implementation with a streamlined,
modern reorder system.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-07 14:50:28 +02:00
Ivan VasilovandClaude Opus 4.6 3f9765e2f8 refactor(studio): migrate all react-contexify usage to ContextMenu_Shadcn_ (#44520)
## 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?

Refactor

## What is the current behavior?

Studio uses `react-contexify` (an imperative, ID-based context menu
library) for right-click menus in the Table Editor grid, Log Table, and
Storage file explorer. This requires `createPortal` workarounds, a
separate CSS file, and has known bugs with fragment rendering.

## What is the new behavior?

All context menus now use the declarative `ContextMenu_Shadcn_`
(Radix-based) component that is already the standard across Studio. Each
context menu wraps its trigger element directly, removing the need for
imperative `show()` calls, portal hacks, and menu ID constants. The
`react-contexify` dependency and all associated styles are removed.

**Changes by area:**
- **Grid row context menu**: `RowRenderer` wraps each `<Row>` with
`ContextMenu_Shadcn_`. `RowContextMenu` refactored to accept `row`
directly as a prop instead of looking it up by index.
- **Log table**: Row renderer wraps each row with a context menu for
"Copy event message". Removes `cellPosition` state and `createPortal`.
- **Storage**: `FileExplorerRow` reuses its existing `rowOptions` array
for both the dropdown and context menu. `FileExplorerColumn` inlines the
column menu (new folder, select all, view/sort submenus). Three
standalone context menu files deleted.
- **Cleanup**: Removed `react-contexify` from `package.json`, deleted
`contextMenu.scss`, removed styles from `grid.scss`.

## Additional context

Net -370 lines. Follows the TODO comment in `CellContextMenuWrapper.tsx`
and the existing eslint ban on `react-contexify` imports.

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

* **Refactor**
* Replaced legacy right-click menus with a unified shadcn-style context
menu across grids, logs, and the storage explorer.
* Simplified row/column/item context menu behavior and copy actions;
menus now mount and trigger more reliably.

* **New Features**
* Added row-level context menu providers to ensure consistent triggering
and positioning for row actions.

* **Chores**
  * Removed legacy context-menu styles and deprecated menu components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 13:46:29 +02:00
Ivan Vasilov 52e670e7b0 chore: Bump next version for ui-library and design-system (#41313)
This PR changes the `next` version in the main catalog which switches
`design-system` and `ui-library` apps to next v16.
2026-04-02 14:43:40 +02:00
Ivan Vasilov bed5a96349 chore: Bump Typescript to v6 (#44204) 2026-03-26 15:27:35 +01:00
Raminder Singh 4fdad068d8 fix: upgrade button not shown on Stripe Sync Engine integration page (#44116)
This version fixes a problem in which the upgrade button was not
enabled. The last two versions (1.0.29 and 1.0.30) of
`stripe-experiment-sync` package returned version 1.0.28 from the
exported function `getCurrentVersion`. The `getCurrentVersion` function
is used by studio code to show the upgrade button if the installed
version is lower than the current version. Version 1.0.31 fixes this
bug.
2026-03-24 10:50:08 +05:30
Gildas Garcia 06190d15b9 Gildasgarcia/fe 2426 show relationship line context and highlight on hover (#44023)
## Problem

When you have many tables, it's hard to follow the relations between
them in the Schema Visualiser

## Solution

When selecting an edge (the line between tables), highlight it along
with the related tables and columns to make it easier.
Also, if there is enough space, display a popover showing the relation
details

## Screencasts


https://github.com/user-attachments/assets/11d35fa7-3674-4f13-b77f-8ebe25c66b04
2026-03-23 17:41:50 +01:00
Raminder Singh d73911697b chore: bump stripe-experiment-sync to version 1.0.29 (#44014)
Version `1.0.29` of `stripe-experiment-sync` was published with some
critical fixes related to some records not syncing.
2026-03-23 20:49:24 +05:30
Matt Rossman d29fbf6eb7 feat(assistant): upgrade AI SDK v5 → v6 (#43931)
Upgrades `ai` from v5 to v6 and all related packages.

**Package bumps:**
- `ai`: `5.0.52` → `^6.0.116`
- `@ai-sdk/openai`: `2.0.32` → `^3.0.41`
- `@ai-sdk/react`: `2.0.52` → `^3.0.118`
- `@ai-sdk/provider`: `^2.0.0` → `^3.0.8`
- `@ai-sdk/provider-utils`: `^3.0.0` → `^4.0.19`
- `@ai-sdk/amazon-bedrock`: `^3.0.0` → `^4.0.81`
- `@ai-sdk/mcp`: N/A → `^1.0.25`
- `openai`: bumped to `^4.104.0`
- `braintrust`: `3.0.x` → `^3.4.0`

**Breaking change migrations:**
- `generateObject` removed in v6 — migrated 5 API routes to
`generateText` with `Output.object({ schema })`, returning
`result.output`
- `convertToModelMessages` is now async — added `await`
- MCP import path changed: `experimental_createMCPClient` from `ai` →
`createMCPClient` from `@ai-sdk/mcp`
- `openai()` defaults to Responses API — added `store: false` to
provider options for ZDR org compatibility

**Streaming fix:**
Added `Content-Encoding: none` header to `pipeUIMessageStreamToResponse`
calls. Without it, proxy middleware buffers the entire SSE response
before flushing, causing the full reply to appear at once.

**Zero Data Retention fix:**
In recent AI SDK versions, `openai()` default to Responses API instead
of the legacy chat completions API. This produces a 404 from OpenAI with
message `"Items are not persisted for Zero Data Retention organizations.
Remove this item from your input and try again."` The Responses API is
OpenAI's [recommended
endpoint](https://developers.openai.com/api/docs/guides/migrate-to-responses).

This PR adds `store: false` as mentioned in
https://github.com/vercel/ai/issues/10060 to avoid incompatible
persistence attempts.

**References:**
- https://ai-sdk.dev/docs/migration-guides/migration-guide-6-0
-
https://ai-sdk.dev/docs/troubleshooting/streaming-not-working-when-proxied
- https://github.com/vercel/ai/issues/10060

Closes AI-514
Related AI-509
2026-03-19 09:07:33 -04:00
Ivan Vasilov ba1fd158a1 chore: Bump vulnerable dependencies (#43907) 2026-03-18 12:47:18 +01:00
Raminder SinghandJoshen Lim 65237597e4 feat: upgrade flow and other improvements (#43289)
This PR:

* Adds an upgrade flow to the stripe sync engine, allowing users to
upgrade to the latest version when it becomes available.
* When a new version of sync engine becomes available, users will see an
upgrade button instead of install button.
* Bumps `supabase-management-js` to version 2.0.2 and
`stripe-experiment-sync` to version 1.0.27.
* Uses `parseSchemaComment` and related logic from the
`stripe-experiment-sync` package in order to avoid writing duplicate
code in supabase ui.
* Allows installation/uninstallation to timeout after 5 minutes to avoid
these operations from getting stuck in case an error occurs in their
processing. This allows users to retry the operation, as opposed to the
older behaviour where the users always see a spinner on the
install/uninstall button and couldn't do anything.
* Remove the SSL enforcement admonition as it is no longer required.
Sync engine can now be installed with or without SSL enforcement
enabled.

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-03-18 08:29:03 +00:00
Ivan VasilovandJoshen Lim 9fa96977be chore: Minor prettier fixes (#43849)
This PR fixes some prettier issues:
- Bump and unify all prettier versions to 3.7.3 across teh whole repo
- Bump the SQL prettier plugin
- When running `test:prettier`, check `mdx` files also
- Run the new prettier format on all files

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-03-17 11:17:42 +01:00
Matt Rossman 517171b246 feat(assistant): online evals support and CI workflows (#43194)
Lays groundwork for online evals on Assistant chat logs.

https://www.braintrust.dev/docs/observe/score-online

### Changes

- New workflows:
- `braintrust-scorers-deploy.yml` keeps prod scorers in sync on push to
`master`
- `braintrust-preview-scorers-deploy.yml` deploys preview scorers to the
staging project for PRs labeled `preview-scorers`, posting a comment
with scorer links
([example](https://github.com/supabase/supabase/pull/43194#issuecomment-4000097222))
- `braintrust-preview-scorers-cleanup.yml` deletes preview scorers when
the PR is closed
([example](https://github.com/supabase/supabase/pull/43194#issuecomment-4000749847))
- Adds `evals/scorer-online.ts` entry point invoked with `pnpm
scorers:deploy`, registering scorers for online evals in the Braintrust
"Assistant" project
- Refactors scorer code to separate online-compatible scorers
(`scorer-online.ts`) from WASM-dependent ones (`scorer-wasm.ts`)
- "URL Validity" scorer now only checks Supabase domains to prevent
requests to untrusted origins
- Span `input` is now shaped `{ prompt: string }` instead of plain
`string` for compatibility with offline eval scorers
- Env vars `BRAINTRUST_STAGING_PROJECT_ID` and `BRAINTRUST_PROJECT_ID`
configured in GitHub repo settings
- `generateAssistantResponse` now uses `startSpan` + `withCurrent`
instead of `traced()` to manually manage the root span lifecycle — this
ensures `onFinish` logs output to the span _before_ `span.end()` is
called, which is when Braintrust triggers scoring automations

### Online Scorers

We share scoring logic across offline and online evals, but some of our
scorers aren't transferrable to an "online" setting due to runtime
challenges or ground truth requirements.

**Supported**
- Goal Completion
- Conciseness
- Completeness
- Docs Faithfulness
- URL Validity

**Unsupported**
- Correctness (requires ground truth output)
- Tool Usage (requires ground truth requiredTools)
- SQL Syntax (uses libpg-query WASM)
- SQL Identifier Quoting (uses libpg-query WASM)
 
### How to use these scorers

Going forward if you want to add/edit online eval scorers, add the
`preview-scorers` label to a PR. This deploys scorers to the [Assistant
(Staging
Scorers)](https://www.braintrust.dev/app/supabase.io/p/Assistant%20(Staging%20Scorers)?v=Overview)
project in Braintrust with branch-specific slugs, and comments on the PR
([example](https://github.com/supabase/supabase/pull/43194#issuecomment-4000097222)).
From the Braintrust dashboard you can "Test" the scorer with traces from
any project.

<img width="1866" height="528" alt="CleanShot 2026-03-05 at 15 15 00@2x"
src="https://github.com/user-attachments/assets/4f15cebc-3f2d-4e8a-9ee2-fe8ef7bf4199"
/>

Once merged, scorers are deployed to the primary
[Assistant](https://www.braintrust.dev/app/supabase.io/p/Assistant)
project, and preview scorers are deleted from the staging project. Down
the road, scorers on the Assistant project will run automatically on a
sample of production traces.

Closes AI-437
2026-03-09 13:05:26 -04:00
Ivan Vasilov e0a736181a chore: Bump next in studio to v16.1.6 (#43149)
This pull request upgrades the `next` framework and its related
dependencies from version 16.0.11 to 16.1.6 across the `studio` project.
2026-03-05 11:59:43 +01:00
Matt Rossman 00436076bb chore(studio): bump mcp-server-supabase to 0.7.0 and mcp-utils to 0.4.0 (#43356)
Bumps `@supabase/mcp-server-supabase` from 0.6.3 to 0.7.0 and
`@supabase/mcp-utils` from 0.3.2 to 0.4.0.

**References**
- https://github.com/supabase-community/supabase-mcp/releases/tag/v0.7.0

Closes AI-462
2026-03-04 14:50:41 -05:00
Ali Waseem 28be36f04c chore: allow using multiple ports for next dev (#43398)
## 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?

Trying agents with multiple git worktrees, want the ability to run
multiple instances of dev

## Context

For agent scripts that support git worktrees, you can set STUDIO_PORT to
0 and have the OS assign a port so they don't conflict with each other
2026-03-04 10:47:35 -07:00
Charis e60b6a6a2e chore: properly add eslint-plugin-jsx-a11y package (#43108)
YES

## What kind of change does this PR introduce?

Chore / dependency fix

## What is the current behavior?

`eslint-plugin-jsx-a11y` was referenced in `eslint.config.json` but was
not listed in `package.json`, causing module resolution errors in the
IDE.

## What is the new behavior?

The package is properly added to `package.json` so it resolves correctly
in both ESLint and the IDE.
2026-02-23 20:13:05 +00:00
Ivan VasilovandJoshen Lim 75644f8396 chore: Bump react-data-grid to fix a Sentry issue (#42934)
This pull request updates the `react-data-grid` dependency and refactors
code throughout the codebase to use the new import structure and updated
APIs. The changes improve compatibility with the latest version of
`react-data-grid`, simplify imports, and update row selection logic to
match new hook signatures. Additionally, some code is reorganized to use
absolute imports for internal components.

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-02-20 14:10:13 +01:00
Matt Rossman e8ab92408f feat(assistant): enable Braintrust tracing for non-sensitive chats (#42963)
Enables Braintrust tracing for AI Assistant chats to support debugging
and future online evals.

**Code Changes**

- Wraps `generateAssistantResponse` in a Braintrust `traced()` span,
logging the user's latest message as input along with metadata
(`chatId`, `chatName`, `projectRef`, `userId`, `orgId`, `planId`, etc.)
- Threads JWT claims from `apiWrapper` → handler to log `userId` in
Braintrust without an extra API call (+ expanded `apiWrapper` tests)
- Threads `orgId` and `planId` from `getOrgAIDetails` to log in
Braintrust

**Infrastructure Changes**

- Created a "Vercel" service account in Braintrust
- Added `BRAINTRUST_API_KEY` and `BRAINTRUST_PROJECT_ID` env vars to the
studio-staging project in Vercel using a service token for the above
service account
- Added an "Overview" view to the Logs tab in the Braintrust Assistant
project to surface the new metadata

**Precautions**

- HIPAA sensitive projects are excluded from logging (see
https://github.com/supabase/supabase/pull/42787 for the detection logic)
- Production is temporarily excluded from logging until we're confident
in the setup

**Testing steps**

- Chat with the AI Assistant in the [studio-staging preview
build](https://github.com/supabase/supabase/pull/42963#issuecomment-3917178023)
below
- Visit the [Logs tab in the Braintrust Assistant
project](https://www.braintrust.dev/app/supabase.io/p/Assistant/logs)
and inspect the trace

<img width="4680" height="962" alt="CleanShot 2026-02-18 at 17 43 55@2x"
src="https://github.com/user-attachments/assets/c3a11b21-4e7f-4e90-bdab-a25ab8ee0d1f"
/>

<img width="2632" height="1288" alt="CleanShot 2026-02-18 at 17 45
04@2x"
src="https://github.com/user-attachments/assets/6c7b6ebc-5090-4ede-8f71-859ff7e386aa"
/>

**References**
- https://www.braintrust.dev/docs/integrations/sdk-integrations/vercel
- https://www.braintrust.dev/docs/instrument/custom-tracing

Closes AI-438
2026-02-19 11:43:47 -05:00
Ali Waseem c57c341244 chore: add ratchet rules to stop nesting components (#42962)
## 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?

The changes required for this React Doctor need more thought that I can
hammer with AI. Just need to stop this from happening in the future with
Ratchet rules
2026-02-18 10:09:08 -07:00
Ivan Vasilov 3d4459ef98 chore: Add more ratchets for deprecated packages and default exports (#42948)
This PR adds a new rule `no-restricted-imports` for deprecating old
packages. For now, only `react-data-grid` and `react-contexify` have
been added.

The ratchet baselines has been rerun with the new rules.
2026-02-18 09:11:54 +01:00
Ivan Vasilov a5511386ce chore: Clean up unused files from a project creation experiment (#42690)
This PR removes the onboarding schema generation and visualization
feature from the project creation flow. This was part of an experiment
which has been tested and shut down.

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

## Summary by CodeRabbit

* **Revert**
* Removed project creation workflow components and related UI surfaces
including the initial setup interface, project visual preview, and
schema generation assistant.
  * Removed database schema visualization and diagram components.
  * Cleaned up associated package dependencies.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-12 10:15:14 +01:00
kemal.earth 8ffdcfc145 feat(studio): scoped pat ui (#38170)
## 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?

Introduces UI for Scoped PAT's.

## Additional context

WIP. Testing endpoints.


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

* **New Features**
* Scoped access tokens: create, view, delete, and manage granular
resource/action permissions with custom expiry options and scoped
creation flows.
* New scoped token UI: modal/sheet creation flow, resource access
selectors, permissions editor, and a scoped token list.

* **UI Improvements**
* Tabbed Classic vs Scoped tokens layout, refreshed tokens page,
improved forms, search/filtering, and table tweaks.

* **Bug Fixes / Maintenance**
  * New data hooks and utilities for scoped tokens and token handling.

* **Removed**
  * Legacy account settings layout and legacy token banner.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-09 11:32:55 +00:00
Sean OliverandCharis Lam 6bbe2c3297 feat(telemetry): add dev telemetry toolbar (#42259)
## Problem
We need a local-only UI to inspect client and server telemetry events
and override flags during development without touching non-local env
behavior. This work is intended to be shared across Studio, Docs, and
WWW.

## Changes
- Introduced a shared `dev-tools` package with the Dev Telemetry Toolbar
UI, trigger, and provider.
- Wired the toolbar into Studio, Docs, and WWW app shells (local-only
gating).
- Added a local-only `devTelemetry()` opt-in with storage gating and SSE
subscription.
- Wired client PostHog events into a local listener and re-exported
types.
- Added local flag override cookie support in the UI and CODEOWNERS for
the new package.
- Added unit tests covering local/non-local behavior and flag utilities.

## Testing
Manual (local only):
- Start each app locally: `pnpm dev:studio`, `pnpm dev:docs`, `pnpm
dev:www`
- Open the app, run `devTelemetry()` in the browser console
- Click around and confirm both client and server events appear (client
will be page views only)
- Verify feature flag overrides (PostHog + ConfigCat) persist and
restore correctly
- Confirm dismissing the toolbar clears local storage and hides the
trigger

Unblocked by https://github.com/supabase/platform/pull/29172

Resolves GROWTH-591

Demo:

[github.com/user-attachments/assets/60b376db-7440-4ada-82f5-d1bd4af4db3b](https://github.com/user-attachments/assets/60b376db-7440-4ada-82f5-d1bd4af4db3b)

Screenshots:

<img width="1368" height="972" alt="1"
src="https://github.com/user-attachments/assets/d2f20a0c-191f-4118-bb5e-15b25f5a54a9"
/>

<img width="1423" height="790" alt="2"
src="https://github.com/user-attachments/assets/115598e2-7287-49bf-9ed7-71ecc679dee3"
/>

<img width="1433" height="882" alt="3"
src="https://github.com/user-attachments/assets/51f666f2-9efc-410f-baec-378bdee9dbfe"
/>

<img width="608" height="483" alt="4"
src="https://github.com/user-attachments/assets/584d6cf5-1b2f-4cee-9e6a-d55ce2e3bae5"
/>

<img width="628" height="305" alt="5"
src="https://github.com/user-attachments/assets/991a9b39-578a-4565-b110-537a02040a53"
/>

<img width="659" height="447" alt="6"
src="https://github.com/user-attachments/assets/95ef405c-fffa-44af-bf6a-f974b780e3fc"
/>

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

* **New Features**
* Developer Toolbar (local only): view client/server telemetry, inspect
events, and manage/override feature flags with persistent overrides,
filtering, and clear/reload.
* Client-side telemetry hooks: surface structured events to dev tooling
for realtime inspection.

* **Bug Fixes**
  * Fixed end-of-file newline in shared code.

* **Chores**
* Added dev-tools package, integrated provider and trigger across
Studio, Docs, and marketing sites, and added CODEOWNERS entry.

* **Tests**
  * Added comprehensive tests and test setup for the DevToolbar.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
2026-02-06 11:46:53 -08:00
Matt Rossman bebf26ed01 chore(studio): bump @supabase/mcp-server-supabase to 0.6.3 (#42433)
Bumps `@supabase/mcp-server-supabase` from 0.6.2 to 0.6.3

Closes AI-416

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

## Summary by CodeRabbit

* **Chores**
  * Updated dependencies to maintain compatibility and stability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-04 07:31:40 -05:00
Ivan Vasilov 5de2564df2 chore: Revert the bump of next package (#42420)
This PR reverts the bump of `next` from `16.0.11` to `16.1.6` because it
broke the self-hosted build (it got stuck and timeouts after 45 minutes)

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

## Summary by CodeRabbit

* **Chores**
  * Adjusted the Next.js runtime for the Studio app to ~16.0.0.
  * No other dependencies, scripts, or app behavior were changed.
* No public-facing API or exported declarations were added, removed, or
modified — low impact on end-user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-03 17:11:42 +00:00
Ivan Vasilov d7626c9830 chore: Bump vulnerable dependencies (#42416)
This PR fixes:
- https://github.com/supabase/supabase/security/dependabot/2721
- https://github.com/supabase/supabase/security/dependabot/2699
- https://github.com/supabase/supabase/security/dependabot/2704
- https://github.com/supabase/supabase/security/dependabot/2701
- https://github.com/supabase/supabase/security/dependabot/2708
- https://github.com/supabase/supabase/security/dependabot/2709
- https://github.com/supabase/supabase/security/dependabot/2732
- https://github.com/supabase/supabase/security/dependabot/2733
- https://github.com/supabase/supabase/security/dependabot/2750
- https://github.com/supabase/supabase/security/dependabot/2751

It also dedupes `mermaid` and `sharp` deps.

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

* **Chores**
* Updated image-processing dependency to a newer patch release for
stability.
* Upgraded framework runtime to a minor release for improvements and bug
fixes.
  * Adjusted workspace dependency override for a transitive package.
* Added a development build tool dependency to the web app for improved
tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-03 15:23:30 +01:00
Matt Rossman d21098ada4 chore(studio): upgrade @supabase/mcp-server-supabase to v0.6.2 (#42210)
* chore(mcp): upgrade @supabase/mcp-server-supabase to v0.6.2

* fix: mocks for Node.js / Web Standard HTTP APIs
2026-01-27 13:10:17 -05:00
Ivan Vasilov 07b9702be3 chore: Add prettier plugin for sorting imports (#41608)
* Add prettier plugin for sorting imports.

* Migrate the prettier config to a js file. Make the sort imports conditional which will work only in code editors.

* Remove unneeded commands for running prettier.

* Fix the regex to be more specific.

* Another fix for the import regex.
2026-01-27 10:55:59 +01:00
Ivan Vasilov 036740b5b5 chore: Bump vulnerable deps (#42182)
* Bump @modelcontextprotocol/sdk.

* Bump qs.

* Bump preact.

* Bump react-router.

* Bump @smithy/config-resolver.

* Bump undici.

* Bump devalue.

* Bump h3.

* Bump tar.

* Bump diff.

* Bump lodash.

* Dedupe @aws-sdk/credential-providers.
2026-01-27 10:29:05 +01:00
Ivan Vasilov fb2bd2abb3 chore: Bump next versions to non-vulnerable numbers (#42198)
Bump next versions to non-vulnerable numbers.
2026-01-27 08:31:54 +00:00
Matt Linkous e6c4b0c122 fix backfill issues with stripe sync engine (#42086) 2026-01-22 21:06:36 -07:00
Matt Rossman f44ed8a7a0 chore(mcp): bump @supabase/mcp-server-supabase to v0.6.1 (#41751)
chore: bump `@supabase/mcp-server-supabase` to v0.6.1
2026-01-06 16:43:42 -05:00
072883bcec feat: assistant evals (#41311)
* chore: bump `supabase` CLI

* chore: stricter message types in `generate-v4.ts`

* feat: tutorial eval

https://www.braintrust.dev/docs/evaluation

* feat: project ID for eval

* refactor: `generateAssistantResponse` out of `handlePost`

* refactor: generateAssistantResponse to lib/ai

* feat: factuality eval with assistant response

* chore: upgrade braintrust to v1.0.1

* chore: silence tsconfig warning

* feat: assertion scorer

* fix: aggregate tools across all steps

* refactor: strict tool names, remove need for `as const`

* refactor: generic tool name type in assertions

* feat: transfer mocks from `feature/braintrust`

* feat: LLM criteria assertion

* feat: braintrust evals workflow

* fix: BRAINTRUST_PROJECT_ID

* feat: `sql_similar` assertion

* fix: `OPENAI_API_KEY` in workflow env

* feat: split AssertionScorer into separate scorers

* feat: remove tutorial eval

* feat: 20 minute CI timeout

* feat: category in test case metadata

* feat: score with gpt-5

* refactor: dataset to own file, colocate scorers

* feat: "gpt-5.2-2025-12-11" for llm as a judge

* feat: SQL syntax scorer with `libpg-query`

* feat: `evals:setup` and `evals:run` scripts

* feat: `evals:setup` in CI

* feat: human readable scorer names

* chore: rename to "SQL Validity"

* feat: add 2 "sql_generation" test cases

* feat: update requiredTools in test cases

* chore: ignore Cursor MCP config

* feat: "Conciseness" score

* feat: "Completeness" scorer

* fix: generate-v4 test mocks

* feat: serialize "steps" for scorer inputs

* updated node mem options for typecheck

* updated runner

* remove ram update as actions handle this

* feat: read `BRAINTRUST_PROJECT_ID` from secrets

* feat: score helpfulness, remove old scorers

* feat: separate `evals:run` and `evals:upload` scripts

* feat: passthrough entire classifier result

* feat: use live `search_docs` impl, store docs result in metadata

* feat: reduce classifier options

* feat: filter workflow by `run-evals` PR label or `master` branch

* chore: cleanup stubbed mock tools

* fix: checkout actual branch with `ref:`

* fix: capture search_docs results from all content parts

* feat: simplify sql syntax score calculation

* feat: use AI SDK's UI message validator

* docs: justification for relative `extends`

* fix: cleanup leftover validatedMessages

* doc: note mock token isn't secret for snyk

* fix: mock ui message to pass validation

* feat: revert ignoring Cursor MCP config

Using `.git/info/exclude` instead until we have an opinion on this

* feat: add "tsconfig" as shared-data devDependency, revert relative path in tsconfig

* refactor: tool call parsing into function

* Update apps/studio/evals/assistant.eval.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* refactor: organize mock schemas and tool factories

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-22 23:45:48 -05:00
0e2c31bf60 feat: Stripe Sync Engine integration (#41317)
* add initial installation flow of stripe sync engine

* update docs link

* Add supabase_vault extension dep

* Add stripe logo to sync engine integration

* Move overview content to bottom of integration pages

* Add sync state to stripe sync page

* only check sync state if stripe integration is installed

* Use proper stripe-sync package and setup flows

* Improve sync engine installation ux

* Remove unused hardcoded dep

* Add alpha status to stripe sync engine integration

* fix typo

* run format

* fix types

* Rename the stripe-sync path to remove the 'integration". The path needs to have BASE_PATH to work on prod.

* Design tidy up (#41337)

UI tidy up

* update to latest sync engine package

* Add stripe key verification

* Remove noop try/catch

* Add integration isntallation telelemtry

* Add basic settings page

* Address coderabbit comments

* remove unused dep

* Remove state setting on render

* s/description/comment

* Cleanup settings screen UI

* Improve settings screen design

* update schema test snapshot

* Use latest stripe-sync-engine package

* Update repo url to new official location

* revert marketing change

* Update stripe sync engine package

* Add link to table from overview page

* Add feature flag and improve telemetry

* Fix missing useMemo dep

* add uninstall telemetry note

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
2025-12-20 00:42:10 +00:00
Matt RossmanandJoshen Lim 43f4f7f6a6 chore: bump @supabase/mcp-server-supabase to v0.5.10 (#41442)
* chore: bump `@supabase/mcp-server-supabase` to v0.5.10

* Update pnpm lock

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-12-17 14:15:43 -05:00