sixty

agent client

Supabase

Le seul agent qui sait ce qu’*est* le point d’entrée plutôt que ce qu’il a coûté — il peut donc distinguer une requête lente d’une règle qui en a refusé une.

paquet
@sixty-sh/supabase sur npm
tourne sur
À côté de l’agent navigateur, dans un projet dont le backend est Supabase.
source
sixty-sh/sixty-supabase

L’installer

For a frontend with no server of your own to deploy: runs entirely in the browser with a public, origin-pinned key. If the project has any server, use browser or node.

L’installation est écrite comme un prompt pour l’agent de code que vous avez déjà ouvert, pas comme une liste de tâches pour vous. C’est délibéré : elle nomme ce qui doit être vrai une fois l’installation terminée plutôt que les fichiers à modifier, parce que l’endroit où va le code dépend du framework et que le mettre au mauvais endroit échoue silencieusement. Un agent peut lire votre dépôt et le déduire ; un paragraphe sur une page de documentation, non.

Le même texte est ce que renvoie install_sixty via le serveur MCP et ce que le collecteur sert à /v1/setup?kind=lovable. Il n’en existe qu’une seule copie.

l’installation Supabase, en entier
Add sixty.sh performance monitoring to this app. It measures Supabase query
shape, page speed, stuck loading states and browser errors, and reports
anonymously.

Before anything else: does this project run a server of its own? A Lovable
app often grows one — an API route, a serverless function, an Express or
FastAPI backend added later, a Supabase edge function you deploy. If it has
one, STOP and ask for the "browser" install instead, or the "node" or
"python" one if the server holds logic worth measuring. Those keep the key
server-side behind a proxy and can measure the server as well as the page.
This install is for the case where the frontend is genuinely the only code
you deploy, and it trades a world-readable key for that.

If that is this project, work out which shape it is, because it decides where
the code goes and there is no error if you get it wrong — it just silently
never runs:

  A. Client-only Vite SPA. There is a createRoot(...) call in a file like
     src/main.tsx and no server entry.
  B. Server-rendered framework app — React Router v7 framework mode, Remix,
     or similar. Signs: an entry.client.tsx / entry.server.tsx pair, a
     root.tsx, a hydrateRoot(...) call, or a routes.ts.

Then:

1. Add two dependencies: @sixty-sh/supabase and @sixty-sh/browser.

2. Call init() from "@sixty-sh/browser" exactly once, in the browser.

      init({ key: "sixty_pk_YOUR_KEY" })

   In shape A, module scope in the app entry is fine.
   In shape B it MUST go in the client entry (entry.client.tsx), after
   hydration. Do not put it in a shared module that the server also
   evaluates: there it runs during server rendering, finds no window,
   returns null, and reports nothing at all — with no error to tell you.

3. Find where the Supabase client is created. Search the repository for
   "createClient(" rather than guessing a path — it is often in
   src/integrations/supabase/client.ts but in this kind of project it may be
   anywhere. Then, at module scope in that same file:

      import { withSixty } from "@sixty-sh/supabase"
      withSixty(supabase, { key: "sixty_pk_YOUR_KEY", service: "my-app" })

   Use the client that already exists. withSixty patches the PostgREST
   prototype and returns the same object it was given, so it instruments every
   query in the app without replacing the export.

Constraints — correctness requirements, not style preferences:

- Do NOT create a second Supabase client. There must still be exactly one.
- Do NOT edit vite.config.ts and do NOT add a Vite plugin.
- Do NOT change any existing query, component, or hook. This is
  instrumentation only; no behaviour should change.
- The key above is PUBLIC by design: write-only, pinned to one service, and
  refused from any origin it does not list. Paste it literally. Do not move it
  into an environment variable or a secret.
- Do NOT add any analytics library, user id, session id, or cookie. This agent
  is deliberately anonymous and must stay that way.

When you are done, tell me which shape you found and which files you changed,
then publish the app. Findings need two published releases with traffic under
each before anything can be compared.

Il lui faut une clé publique — épinglée à vos origines, parce qu’une application sans serveur à elle n’a nulle part où garder un secret.

Ce qu’il mesure

signalunitéce que cela veut dire
errorserror ratea larger fraction of calls are throwing
new_erroroccurrencesan error that did not occur in the previous release
latencyms per callthis operation takes longer end to end than it used to
silent_empty—The query runs and succeeds, and returns no rows where it used to return plenty. Nothing reports an error, so the page just renders blank — this is what a broken permission rule looks like from the outside.
auth_failures—The server is turning these away on permission grounds rather than failing. People see an empty page or a save that quietly does nothing.

Les pannes qu’il sait nommer

Ce ne sont pas des signaux. Ce sont les classes qu’il pose sur une erreur, et c’est ce qui fait la différence entre « un appel a échoué » et « une règle l’a refusé ».

rls_deniedA row-level security policy refused the statement (Postgres 42501). It reaches the browser as an empty list and your logs as nothing at all.
schema_missingA column, table, relationship or function the code expects is not in the database.
constraint_violatedA write was rejected by a database constraint.
jwt_expiredA session token was expired or invalid where one was required.
realtime_duplicate_subscriptionOne topic subscribed concurrently three times or more — an effect with no teardown, seen from the wire.
realtime_channel_errorA channel reported CHANNEL_ERROR or TIMED_OUT instead of subscribing.

Où il s’accroche

  • supabase-js — Appels PostgREST, canaux temps réel et auth, instrumentés là où ils sont faits.
  • Vite — Un plugin, pour les projets construits avec.

Bases de données

  • PostgREST — La requête HTTP décrit la requête SQL : la table, les filtres et le code d’échec sont donc lisibles sans passer par une requête.

Ce que seul celui-ci fait

  • Un nom pour la panne — Tout autre agent peut dire qu’un appel a échoué. Celui-ci peut dire qu’une règle l’a refusé, qu’une colonne manque, ou que le jeton avait expiré — parce qu’une requête PostgREST décrit la requête plutôt que de simplement coûter quelque chose.
  • Le temps réel autant que les lectures — Des canaux qui échouent, expirent, ou se retrouvent abonnés trois fois parce qu’un effet n’a pas de nettoyage.

Ce qu’il ne peut pas faire

  • Ceci est un ajout à l’agent navigateur ou Lovable, pas un remplacement. Il explique les échecs Supabase ; il ne mesure pas la page.
  • Un projet sans serveur à lui utilise une clé publique épinglée à l’origine. S’il lui est poussé une route d’API ou une fonction edge, prenez le niveau navigateur ou Node — la clé reste côté serveur et le serveur est mesuré en plus.

Configuration

Chaque agent lit les mêmes quatre variables, et DRIFT_* répond toujours partout où SIXTY_* répond — le produit a été renommé, et ce nom ne nous appartient pas au point de le retirer des déploiements des autres.

SIXTY_API_KEYSans elle l’agent reste inerte et le dit. Il ne devine jamais, ne réessaie jamais contre un point d’entrée inconnu, et ne lève jamais d’exception.
SIXTY_SERVICEComment appeler ce service. Par défaut le nom du projet là où il est lisible.
SIXTY_RELEASELa plus importante. Récupérée automatiquement sur Vercel, Render, Railway, Fly, Heroku et GitHub Actions ; partout ailleurs, mettez-y le SHA du commit. Sans elle, chaque mesure atterrit dans un unique seau sans nom et aucune comparaison n’est jamais possible.
SIXTY_ENDPOINTOù remonter. Par défaut http://localhost:4319, ce qui est juste sur un portable et faux dès l’instant où l’application est servie à quelqu’un d’autre.

Le reste — intervalle d’envoi, taux d’échantillonnage, quoi instrumenter — est dans le README du paquet lui-même, là où il peut rester vrai à mesure que l’agent change.

L’agent Supabase de sixty — ce qu’il mesure et comment l’installer