sixty

agente de cliente

React Native

Una aplicación no tiene un span del lado servidor con el que compararse, así que una llamada rechazada o una respuesta vacía solo son visibles desde el dispositivo. Este es el agente que las hace visibles.

paquete
@sixty-sh/react-native en npm
funciona sobre
iOS y Android. Alrededor de 2,6 µs de coste bloqueante por cada petición que observa.
código
sixty-sh/sixty-react-native

Cómo instalarlo

iOS and Android. API shape and latency, errors and crashes, render loops — with a public key.

La instalación está escrita como un prompt para el agente de código que ya tienes abierto, no como una lista de tareas para ti. Es deliberado: nombra lo que tiene que ser cierto cuando la instalación esté terminada en vez de qué archivos editar, porque dónde va el código depende del framework y ponerlo en el sitio equivocado falla en silencio. Un agente puede leer tu repositorio y deducirlo; un párrafo en una página de documentación no.

El mismo texto es lo que devuelve install_sixty a través de el servidor MCP y lo que el colector sirve en /v1/setup?kind=react-native. Hay una sola copia.

la instalación de React Native, completa
Add sixty.sh monitoring to this React Native app. It measures API call shape
and latency, JavaScript errors and crashes, and runaway re-render loops, and
reports anonymously.

Before editing, ask: "Do you want mobile incident replay?" Enable replay
only if the user says yes. It retains a bounded screen/request/error timeline
around failures, never screenshots, screen text, bodies, headers or ids.

1. Install @sixty-sh/react-native. Also install
   @react-native-async-storage/async-storage if it is not already present —
   without it, telemetry buffered when the user backgrounds the app is lost,
   and that is how most sessions end.

2. Call init() once, at the top of the entry file (index.js or App.tsx),
   before anything else imports:

      import { init, composeRelease } from "@sixty-sh/react-native"

      init({
        key: "sixty_pk_YOUR_KEY",
        service: "my-app",
        endpoint: "https://ingest.sixty.sh",
        release: composeRelease({ version: APP_VERSION, build: BUILD_NUMBER }),
        // replay: true, // uncomment only with explicit consent
      })

   Work out where the version and build number actually come from in THIS
   project — expo-constants, react-native-device-info, a generated file, or a
   constant somebody maintains by hand. Do not add a dependency just for this;
   if none exists, hardcode the current version and say so in your summary.

   IF this app ships over-the-air updates (expo-updates or CodePush), the
   release MUST also include the update id:

      composeRelease({ version, build, updateId: Updates.updateId })

   Without it every OTA bundle reports as the same release, and since OTA is
   how most changes ship, almost nothing can ever be compared. Nothing errors;
   the feed just stays empty.

3. Add the Babel plugin to babel.config.js:

      plugins: ["@sixty-sh/react-native/babel"]

   Then start Metro with --reset-cache once. Metro caches transformed modules
   and will not notice the plugin list changed, so without this the build
   succeeds and the transform is silently not applied.

4. Wire the navigator, or every measurement in the app is filed under one
   route and no per-screen finding is possible. Find the NavigationContainer:

      import { createNavigationTracker } from "@sixty-sh/react-native/navigation"
      const tracker = createNavigationTracker()

      <NavigationContainer onReady={tracker.onReady} onStateChange={tracker.onStateChange}>

   If this app does not use React Navigation, call setRoute("ScreenName") from
   wherever it does track the current screen instead.

5. If the app has React error boundaries, call reportError(error) from
   componentDidCatch. React calls the boundary instead of any global handler,
   so errors caught there are invisible to the agent otherwise — and those are
   the ones that leave a user looking at a fallback screen.

Constraints — correctness requirements, not style preferences:

- Do NOT wrap or replace fetch. React Native's fetch is implemented on top of
  XMLHttpRequest, which the agent already instruments; adding a fetch wrapper
  makes every request count twice and nothing will look wrong.
- Do NOT change any existing screen, hook, or network call. This is
  instrumentation only; no behaviour should change.
- The key above is PUBLIC by design: write-only and pinned to one service.
  Paste it literally. Do not move it into an environment variable.
- Do NOT add any analytics library, user id, session id, or device id. This
  agent is deliberately anonymous and must stay that way.

When you are done, tell me where you found the version number, whether this
app ships OTA updates, and whether you cleared the Metro cache. Findings need
two released builds with traffic under each before anything can be compared.

Necesita una clave pública — anclada a tus orígenes, porque una aplicación sin servidor propio no tiene dónde guardar un secreto.

Qué mide

señalunidadqué significa
client_errorof viewsthis error is being thrown in real users’ browsers
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.
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.
latencyms per callthis operation takes longer end to end than it used to
errorserror ratea larger fraction of calls are throwing
runawaycalls per minutethis operation is being called far more often than anything triggers it

Dónde se engancha

  • React Navigation — Conectado al navegador de pantallas, para que las mediciones se archiven bajo una pantalla. Saltárselo deja todos los números bajo una sola ruta.
  • Tus propios componentes — Un plugin de Babel. Metro cachea los módulos transformados y no se entera de una lista de plugins nueva, así que hay que limpiar la caché o la build no hace nada en silencio.

Qué hace solo este

  • Señales de red desde el dispositivo — Rechazos de autenticación y respuestas correctas pero vacías, que en un teléfono son el único sitio donde cualquiera de las dos es observable.
  • Versiones conscientes de las OTA — El id de la actualización over-the-air forma parte del identificador de versión. Sin él, cada bundle enviado por aire es la misma versión y la comparación no tiene nada que comparar.

Qué no puede hacer

  • Una clave pública, porque una aplicación no tiene origen por el que hacer de proxy ni sitio donde viva un secreto. A diferencia del nivel de navegador, aquí no se renuncia a ningún modo mejor.
  • dead_interaction está ligado a button, a y form, y todavía no sabe de Pressable ni de onPress. effect_loop y missing_cleanup son reglas de React y se aplican a este código sin cambios.

Configuración

Todos los agentes leen las mismas cuatro variables, y DRIFT_* sigue respondiendo allí donde lo hace SIXTY_* — el producto se renombró y ese nombre no es nuestro para retirarlo de los despliegues de otra gente.

SIXTY_API_KEYSin ella el agente se queda inerte y lo dice. Nunca adivina, nunca reintenta contra un endpoint desconocido, y nunca lanza una excepción.
SIXTY_SERVICECómo llamar a este servicio. Por defecto, el nombre del proyecto donde sea legible.
SIXTY_RELEASELa que más importa. Se recoge automáticamente en Vercel, Render, Railway, Fly, Heroku y GitHub Actions; en cualquier otro sitio, ponla al SHA del commit. Sin ella cada medición cae en un único cubo sin nombre y no se puede hacer ninguna comparación.
SIXTY_ENDPOINTDónde reportar. Por defecto http://localhost:4319, que es correcto en un portátil y erróneo en cuanto la aplicación se sirve a alguien más.

El resto — intervalo de envío, tasa de muestreo, qué instrumentar — está en el propio README del paquete, que es donde puede seguir siendo cierto según cambia el agente.

El agente React Native de sixty — qué mide y cómo se instala