/**
* Browser analytics (PostHog). Everything here is a no-op unless the server sent a config, which it only does
* when POSTHOG_KEY is set. posthog-js is loaded lazily, so instances without analytics never download it.
*
* Privacy rules enforced here:
* - Honors Do Not Track and Global Privacy Control, and a per-browser opt-out (setAnalyticsOptOut).
* - Runs only on the forge's own origin, never on editor, user-content, sites or pages origins.
* - URLs lose query strings and fragments; repository paths are redacted unless the repo is known public.
* - Autocapture never records element text or attributes; inputs are masked in replays, and replays pause on
* private repositories and on account, settings and auth pages.
*/
import type { PostHog } from "posthog-js";
import { scrubErrorMessage } from "./scrub-error";
export type ClientAnalyticsConfig = { key: string; host: string; origin: string; personEmail: boolean };
export type AnalyticsViewer = { id: string; email?: string; isAdmin?: boolean } | null;
const OPT_OUT_KEY = "gitfor:analytics-opt-out";
export const INGEST_PREFIX = "/ingest";
/** PostHog's app host for toolbar links: us.i.posthog.com -> us.posthog.com. */
function uiHost(host: string): string {
return host.replace(/^https:\/\/(us|eu)\.i\.posthog\.com$/, "https://$1.posthog.com");
}
const REDACTED = "[private]";
/** First path segments that are app pages, not account names. */
const APP_ROOTS = new Set([
"",
"abuse",
"admin",
"explore",
"ingest",
"features",
"forgot-password",
"login",
"new",
"notifications",
"orgs",
"projects",