tuft-telemetry
v0.1.0
Published
An Expo-first flight recorder for coding agents. It owns Expo context, a durable journal, installation identity, lifecycle/network state, JavaScript error capture, route breadcrumbs, delivery, and cleanup.
Readme
tuft-telemetry
An Expo-first flight recorder for coding agents. It owns Expo context, a durable journal, installation identity, lifecycle/network state, JavaScript error capture, route breadcrumbs, delivery, and cleanup.
Quick start
The endpoint is the collector's base machine URL. The SDK appends /v1/events. The bearer token authorizes exactly one stream; the app never selects or sends a stream ID.
import { createExpoTelemetry } from "tuft-telemetry/expo";
export const telemetry = createExpoTelemetry({
endpoint: process.env.EXPO_PUBLIC_TUFT_TELEMETRY_URL!,
token: process.env.EXPO_PUBLIC_TUFT_TELEMETRY_WRITE_TOKEN!,
});Initialization persists an installation ID, emits app.launch with build/update/device context, installs lifecycle/network listeners, chains the React Native global error handler, and tracks unhandled rejections. shutdown() restores installed handlers/listeners.
Expo Router is an optional entry point so non-Router apps still bundle:
import { installExpoRouterTelemetry } from "tuft-telemetry/expo-router";
export const removeRouterTelemetry = installExpoRouterTelemetry(telemetry);Instrument causal phases rather than every function call:
const span = telemetry.startSpan("message.open", { source: "inbox" });
try {
span.event("cache.checked", { hit });
const message = await loadMessage();
span.end({ bodyBytes: message.bodyBytes });
} catch (error) {
span.fail(error, { phase: "network" });
throw error;
}Lower-level constructors and adapters remain exported for tests and custom integrations. See the protocol, privacy model, and limitations.
