@mushi-mushi/core 1.19.0 → 1.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +12 -0
- package/README.md +1 -0
- package/dist/index.cjs +229 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.js +214 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/payload-guard.ts","../src/api-client.ts","../src/region.ts","../src/env-config.ts","../src/pre-filter.ts","../src/logger.ts","../src/queue-crypto.ts","../src/queue.ts","../src/environment.ts","../src/reporter-token.ts","../src/uuid.ts","../src/fingerprint.ts","../src/session.ts","../src/rate-limiter.ts","../src/pii-scrubber.ts","../src/breadcrumbs.ts","../src/exception-normaliser.ts","../src/design-tokens.ts","../src/identity.ts"],"names":["getBackoffDelay","sleep","sha256Hex"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Client-side payload size guards — prevents silent edge-function failures\n * when screenshots or log buffers inflate the report body past gateway limits.\n */\n\n/** Supabase edge functions tolerate ~6 MB; stay under 4 MB for headroom. */\nexport const MAX_REPORT_PAYLOAD_BYTES = 4 * 1024 * 1024\n\n/** Screenshot data URLs above this are downscaled or dropped before POST. */\nexport const MAX_SCREENSHOT_DATA_URL_BYTES = 1.5 * 1024 * 1024\n\nexport interface PayloadGuardResult {\n ok: boolean\n bytes: number\n maxBytes: number\n reason?: string\n /**\n * True when the payload could not be serialized at all (e.g. a circular\n * reference in `metadata`). This is a distinct failure from \"too large\" —\n * the caller should surface a `SERIALIZE_FAILED` rather than a misleading\n * \"payload too large\" message.\n */\n serializeFailed?: boolean\n}\n\nfunction safeStringify(value: unknown): string | null {\n try {\n return JSON.stringify(value)\n } catch {\n return null\n }\n}\n\nexport function estimateJsonBytes(value: unknown): number {\n const json = safeStringify(value)\n return json === null\n ? Number.MAX_SAFE_INTEGER\n : new TextEncoder().encode(json).length\n}\n\nexport function checkReportPayloadSize(\n payload: unknown,\n maxBytes = MAX_REPORT_PAYLOAD_BYTES,\n): PayloadGuardResult {\n const json = safeStringify(payload)\n if (json === null) {\n return {\n ok: false,\n bytes: 0,\n maxBytes,\n serializeFailed: true,\n reason: 'Report could not be serialized (circular reference in metadata?)',\n }\n }\n const bytes = new TextEncoder().encode(json).length\n if (bytes <= maxBytes) {\n return { ok: true, bytes, maxBytes }\n }\n return {\n ok: false,\n bytes,\n maxBytes,\n reason: `Report payload ${formatBytes(bytes)} exceeds limit ${formatBytes(maxBytes)}`,\n }\n}\n\nexport function formatBytes(n: number): string {\n if (n < 1024) return `${n} B`\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`\n return `${(n / (1024 * 1024)).toFixed(2)} MB`\n}\n","import type {\n MushiApiClient,\n MushiApiResponse,\n MushiAssistantReply,\n MushiCrossAppReport,\n MushiLeaderboardEntry,\n MushiPageContext,\n MushiReport,\n MushiReportStatus,\n MushiReporterComment,\n MushiReporterReport,\n MushiRuntimeSdkConfig,\n MushiSdkVersionInfo,\n MushiTesterReputation,\n MushiTierResult,\n} from './types';\nimport { checkReportPayloadSize } from './payload-guard';\n\n/** Header carrying the signed end-user identity token (verified server-side). */\nexport const MUSHI_USER_TOKEN_HEADER = 'X-Mushi-User-Token';\n/** Build-time SDK package identity — recorded on every authenticated heartbeat. */\nexport const MUSHI_SDK_PACKAGE_HEADER = 'X-Mushi-SDK-Package';\nexport const MUSHI_SDK_VERSION_HEADER = 'X-Mushi-SDK-Version';\n\nexport interface ApiClientOptions {\n projectId: string;\n apiKey: string;\n /**\n * Override the API endpoint. Defaults to the canonical Cloud URL\n * (DEFAULT_API_ENDPOINT). Self-hosted users MUST set this.\n */\n apiEndpoint?: string;\n timeout?: number;\n maxRetries?: number;\n /** When set, sent on every request so heartbeats record the running SDK version. */\n sdkPackage?: string;\n sdkVersion?: string;\n /**\n * Returns the current signed end-user identity JWT, or null when the user is\n * anonymous. When present it is sent on the X-Mushi-User-Token header so the\n * backend can verify it and scope identity-bound features to that user.\n */\n getUserToken?: () => string | null | undefined;\n}\n\n// V5.3 (M-cross-cutting): canonical Cloud URL — the older `api.mushimushi.dev`\n// hostname was never wired up. Self-hosted users MUST override `apiEndpoint`.\nexport const DEFAULT_API_ENDPOINT = 'https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api';\nexport const MUSHI_INTERNAL_HEADER = 'X-Mushi-Internal';\nexport const MUSHI_INTERNAL_INIT_MARKER = '__mushiInternal';\n\nexport type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\nexport function createApiClient(options: ApiClientOptions): MushiApiClient {\n const {\n projectId,\n apiKey,\n apiEndpoint = DEFAULT_API_ENDPOINT,\n timeout = DEFAULT_TIMEOUT,\n maxRetries = DEFAULT_MAX_RETRIES,\n getUserToken,\n sdkPackage,\n sdkVersion,\n } = options;\n\n let baseUrl = apiEndpoint.replace(/\\/$/, '');\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n retries = maxRetries,\n internalKind?: MushiInternalRequestKind,\n extraHeaders?: Record<string, string>,\n ): Promise<MushiApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n const userToken = getUserToken?.() ?? null;\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'X-Mushi-Api-Key': apiKey,\n 'X-Mushi-Project': projectId,\n ...(sdkPackage ? { [MUSHI_SDK_PACKAGE_HEADER]: sdkPackage } : {}),\n ...(sdkVersion ? { [MUSHI_SDK_VERSION_HEADER]: sdkVersion } : {}),\n ...(userToken ? { [MUSHI_USER_TOKEN_HEADER]: userToken } : {}),\n ...(internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {}),\n ...extraHeaders,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n ...(internalKind ? { [MUSHI_INTERNAL_INIT_MARKER]: internalKind } : {}),\n } as RequestInit & { [MUSHI_INTERNAL_INIT_MARKER]?: MushiInternalRequestKind });\n\n clearTimeout(timer);\n\n // C7: data residency — follow a one-shot redirect when the\n // gateway tells us the project lives in a different region. Cache the\n // new base URL so subsequent calls go straight to the right cluster.\n if (response.status === 307 || response.status === 308) {\n const target = response.headers.get('Location');\n if (target && retries > 0) {\n const targetBase = target.replace(/\\/v1\\/.*$/, '').replace(/\\/$/, '');\n if (targetBase !== baseUrl) {\n baseUrl = targetBase;\n return request<T>(method, path, body, retries - 1, internalKind, extraHeaders);\n }\n }\n }\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n if (response.status >= 500 && retries > 0) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1, internalKind, extraHeaders);\n }\n return {\n ok: false,\n error: {\n code:\n (errorBody as { error?: { code?: string } }).error?.code ||\n `HTTP_${response.status}`,\n message:\n (errorBody as { message?: string; error?: { message?: string } }).error?.message ||\n (errorBody as { message?: string }).message ||\n `HTTP ${response.status} error`,\n },\n };\n }\n\n const payload = await response.json();\n const data = payload && typeof payload === 'object' && 'ok' in payload && 'data' in payload\n ? (payload as { data: T }).data\n : payload as T;\n return { ok: true, data };\n } catch (error) {\n clearTimeout(timer);\n\n if (retries > 0 && isRetryable(error)) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1, internalKind);\n }\n\n return {\n ok: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Unknown network error',\n },\n };\n }\n }\n\n async function requestForReporter<T>(\n method: string,\n path: string,\n reporterToken: string,\n body?: unknown,\n ): Promise<MushiApiResponse<T>> {\n const tokenHash = await sha256Hex(reporterToken);\n const ts = String(Date.now());\n const hmac = await hmacSha256Hex(apiKey, `${projectId}.${ts}.${tokenHash}`);\n const url = `${baseUrl}${path}`;\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'X-Mushi-Api-Key': apiKey,\n 'X-Mushi-Project': projectId,\n ...(sdkPackage ? { [MUSHI_SDK_PACKAGE_HEADER]: sdkPackage } : {}),\n ...(sdkVersion ? { [MUSHI_SDK_VERSION_HEADER]: sdkVersion } : {}),\n [MUSHI_INTERNAL_HEADER]: 'reporter-poll',\n 'X-Reporter-Token-Hash': tokenHash,\n 'X-Reporter-Ts': ts,\n 'X-Reporter-Hmac': hmac,\n },\n body: body ? JSON.stringify(body) : undefined,\n [MUSHI_INTERNAL_INIT_MARKER]: 'reporter-poll',\n } as RequestInit & { [MUSHI_INTERNAL_INIT_MARKER]?: MushiInternalRequestKind });\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n return {\n ok: false,\n error: {\n code: `HTTP_${response.status}`,\n message: (errorBody as { error?: { message?: string }; message?: string }).error?.message\n ?? (errorBody as { message?: string }).message\n ?? `HTTP ${response.status} error`,\n },\n };\n }\n const payload = await response.json();\n return { ok: true, data: (payload as { data: T }).data ?? (payload as T) };\n }\n\n return {\n async submitReport(report: MushiReport) {\n const guard = checkReportPayloadSize(report);\n if (!guard.ok) {\n return {\n ok: false,\n error: {\n code: guard.serializeFailed ? 'SERIALIZE_FAILED' : 'PAYLOAD_TOO_LARGE',\n message: guard.reason ?? 'Report payload exceeds size limit',\n },\n };\n }\n return request<{ reportId: string }>('POST', '/v1/reports', report, maxRetries, 'report-submit');\n },\n\n async getReportStatus(reportId: string) {\n return request<{ status: MushiReportStatus }>('GET', `/v1/reports/${reportId}/status`, undefined, maxRetries, 'report-status');\n },\n\n async getSdkConfig() {\n return request<MushiRuntimeSdkConfig>('GET', '/v1/sdk/config', undefined, maxRetries, 'sdk-config');\n },\n\n async askAssistant(input: { message: string; threadId?: string | null; context?: MushiPageContext | null }) {\n return request<MushiAssistantReply>(\n 'POST',\n '/v1/sdk/assistant',\n {\n message: input.message,\n threadId: input.threadId ?? null,\n context: input.context ?? null,\n },\n 1,\n 'community',\n );\n },\n\n async getLatestSdkVersion(packageName: string) {\n const query = new URLSearchParams({ package: packageName }).toString();\n return request<MushiSdkVersionInfo>('GET', `/v1/sdk/latest-version?${query}`, undefined, maxRetries, 'sdk-config');\n },\n\n async postDiscoveryEvent(event) {\n // Discovery is best-effort — only one retry on transient failure\n // and a tighter timeout than report submission. We don't queue\n // these offline because a stale observation is more likely to\n // misinform the proposer than it is to be useful.\n return request<{ accepted: boolean }>(\n 'POST',\n '/v1/sdk/discovery',\n event,\n 1,\n 'discovery',\n );\n },\n\n async listReporterReports(reporterToken: string) {\n return requestForReporter<{ reports: MushiReporterReport[] }>('GET', '/v1/reporter/reports', reporterToken);\n },\n\n async listReporterComments(reportId: string, reporterToken: string) {\n return requestForReporter<{ comments: MushiReporterComment[] }>(\n 'GET',\n `/v1/reporter/reports/${reportId}/comments`,\n reporterToken,\n );\n },\n\n async replyToReporterReport(\n reportId: string,\n reporterToken: string,\n body: string,\n feedbackSignal?: string,\n ) {\n return requestForReporter<{ comment: MushiReporterComment; feedback?: Record<string, unknown> }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reply`,\n reporterToken,\n { body, ...(feedbackSignal ? { feedback_signal: feedbackSignal } : {}) },\n );\n },\n\n async reopenReporterReport(reportId: string, reporterToken: string, note?: string) {\n return requestForReporter<{ outcome: Record<string, unknown> }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reopen`,\n reporterToken,\n { note: note ?? '' },\n );\n },\n\n async listNotifications(reporterToken: string, opts?: { since?: string; limit?: number }) {\n const qs = new URLSearchParams();\n if (opts?.since) qs.set('since', opts.since);\n if (opts?.limit) qs.set('limit', String(opts.limit));\n const suffix = qs.size ? `?${qs.toString()}` : '';\n return requestForReporter<{ notifications: Array<Record<string, unknown>> }>(\n 'GET',\n `/v1/notifications${suffix}`,\n reporterToken,\n );\n },\n\n async markNotificationRead(notificationId: string, reporterToken: string) {\n return requestForReporter<{ ok: boolean }>(\n 'POST',\n `/v1/notifications/${notificationId}/read`,\n reporterToken,\n {},\n );\n },\n\n async listReporterFeatureBoard(reporterToken: string) {\n return requestForReporter<{ tickets: Array<Record<string, unknown>> }>(\n 'GET',\n '/v1/reporter/feature-board',\n reporterToken,\n );\n },\n\n async voteReporterFeatureBoard(requestId: string, reporterToken: string) {\n return requestForReporter<{ voted: boolean; action: string }>(\n 'POST',\n `/v1/reporter/feature-board/${requestId}/vote`,\n reporterToken,\n {},\n );\n },\n\n // ─── Rewards program (P1) ──────────────────────────────────\n\n async submitActivity(userId, events, opts?: { userTraits?: { email?: string; name?: string; provider?: string }; reporterTokenHash?: string; optedIn?: boolean; hostJwt?: string }) {\n return request<{ accepted: number; total: number }>(\n 'POST',\n '/v1/sdk/activity',\n {\n user_id: userId,\n user_traits: opts?.userTraits,\n opted_in: opts?.optedIn,\n reporter_token_hash: opts?.reporterTokenHash,\n // P2: JWT for monetary verification; omitted when null\n ...(opts?.hostJwt ? { host_jwt: opts.hostJwt } : {}),\n events,\n },\n 1, // best-effort, 1 retry\n 'discovery',\n );\n },\n\n async getMyPoints(userId) {\n return request<{ total_points: number; points_30d: number; points_lifetime: number; tier: MushiTierResult | null }>(\n 'GET',\n `/v1/sdk/me/points?userId=${encodeURIComponent(userId)}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getMyTier(userId) {\n return request<MushiTierResult | null>(\n 'GET',\n `/v1/sdk/me/tier?userId=${encodeURIComponent(userId)}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getMyHistory(userId, opts) {\n const qs = new URLSearchParams({ userId, ...(opts?.limit ? { limit: String(opts.limit) } : {}) });\n return request<{ items: unknown[]; total: number }>(\n 'GET',\n `/v1/sdk/me/history?${qs}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getHallOfFame(limit = 10) {\n return request<{\n data: Array<{\n display_name: string;\n email_hash: string | null;\n tier_slug: string | null;\n tier_name: string | null;\n points_30d: number;\n total_points: number;\n }>;\n meta: { project_name: string };\n }>(\n 'GET',\n `/v1/sdk/hall-of-fame?limit=${limit}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n // ─── Cross-app community (in-widget tester identity) ──────────\n\n async sendMagicLink(email: string) {\n return request<{ ok: boolean }>(\n 'POST',\n '/v1/tester/magic-link',\n { email },\n 1,\n 'community',\n );\n },\n\n async linkReporterToken(reporterTokenHash: string, jwt: string) {\n return request<{ ok: boolean; linked: number }>(\n 'POST',\n '/v1/tester/link-reporter',\n { reporter_token_hash: reporterTokenHash },\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getCrossAppReports(jwt: string, opts?: { limit?: number; offset?: number }) {\n const qs = new URLSearchParams();\n if (opts?.limit) qs.set('limit', String(opts.limit));\n if (opts?.offset) qs.set('offset', String(opts.offset));\n const suffix = qs.size ? `?${qs.toString()}` : '';\n return request<{ reports: MushiCrossAppReport[] }>(\n 'GET',\n `/v1/tester/cross-app-reports${suffix}`,\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getMyReputation(jwt: string) {\n return request<{ reputation: MushiTesterReputation | null }>(\n 'GET',\n '/v1/tester/reputation',\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getPublicLeaderboard(limit = 20) {\n return request<{ leaderboard: MushiLeaderboardEntry[] }>(\n 'GET',\n `/v1/public/tester-leaderboard?limit=${limit}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getTesterStatus(jwt: string) {\n return request<{ is_tester: boolean; tester_id: string | null; public_handle: string | null; display_name: string | null }>(\n 'GET',\n '/v1/me/tester-status',\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n };\n}\n\nasync function sha256Hex(value: string): Promise<string> {\n const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nasync function hmacSha256Hex(secret: string, value: string): Promise<string> {\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const buffer = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(value));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, 10_000);\n}\n\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof TypeError) return true; // network failures\n return false;\n}\n","/**\n * C7: Data residency region resolution.\n *\n * The SDK supports four regional clouds:\n * - 'us' → United States (default; legacy `dxptnwrhwsqckaftyymj`)\n * - 'eu' → European Union (Frankfurt)\n * - 'jp' → Japan (Tokyo)\n * - 'self' → self-hosted / BYO Supabase\n *\n * Customers choose a region at project creation time, and the gateway will\n * 307-redirect any cross-region calls to the correct host. The SDK caches\n * the resolved hostname in `localStorage` (browser) so that subsequent\n * sessions skip the redirect.\n */\n\nexport type MushiRegion = 'us' | 'eu' | 'jp' | 'self';\n\nexport const REGION_ENDPOINTS: Record<Exclude<MushiRegion, 'self'>, string> = {\n us: 'https://api.us.mushimushi.dev/functions/v1/api',\n eu: 'https://api.eu.mushimushi.dev/functions/v1/api',\n jp: 'https://api.jp.mushimushi.dev/functions/v1/api',\n};\n\nconst ROUTING_CACHE_KEY = 'mushi_region_v1';\nconst ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\ninterface RegionCacheEntry {\n region: MushiRegion;\n endpoint: string;\n ts: number;\n}\n\n/**\n * Resolve the regional endpoint for a project. Looks up the public\n * `region_routing` table on the legacy US gateway (the catalog of record),\n * then caches the result.\n *\n * Falls back to the explicit `apiEndpoint` if anything goes wrong — failure\n * here must never block report submission.\n */\nexport async function resolveRegionEndpoint(opts: {\n projectId: string;\n apiEndpoint: string;\n region?: MushiRegion;\n storage?: Storage;\n fetcher?: typeof fetch;\n}): Promise<string> {\n const explicit = opts.region;\n if (explicit && explicit !== 'self' && REGION_ENDPOINTS[explicit]) {\n return REGION_ENDPOINTS[explicit];\n }\n\n const storage = opts.storage ?? safeLocalStorage();\n const cached = readCache(storage, opts.projectId);\n if (cached) return cached;\n\n try {\n const fetcher = opts.fetcher ?? fetch;\n const url = `${opts.apiEndpoint.replace(/\\/$/, '')}/v1/region/resolve?project_id=${encodeURIComponent(opts.projectId)}`;\n const res = await fetcher(url, { method: 'GET' });\n if (!res.ok) return opts.apiEndpoint;\n const body = (await res.json()) as { region?: MushiRegion; endpoint?: string };\n if (!body.region || !body.endpoint) return opts.apiEndpoint;\n writeCache(storage, opts.projectId, { region: body.region, endpoint: body.endpoint, ts: Date.now() });\n return body.endpoint;\n } catch {\n return opts.apiEndpoint;\n }\n}\n\nfunction safeLocalStorage(): Storage | undefined {\n try {\n return typeof globalThis !== 'undefined' && 'localStorage' in globalThis\n ? (globalThis as { localStorage: Storage }).localStorage\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readCache(storage: Storage | undefined, projectId: string): string | null {\n if (!storage) return null;\n try {\n const raw = storage.getItem(`${ROUTING_CACHE_KEY}:${projectId}`);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as RegionCacheEntry;\n if (Date.now() - parsed.ts > ROUTING_CACHE_TTL_MS) return null;\n return parsed.endpoint;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(storage: Storage | undefined, projectId: string, entry: RegionCacheEntry): void {\n if (!storage) return;\n try {\n storage.setItem(`${ROUTING_CACHE_KEY}:${projectId}`, JSON.stringify(entry));\n } catch {\n /* no-op: quota exceeded etc. */\n }\n}\n","/**\n * FILE: packages/core/src/env-config.ts\n * PURPOSE: Reads Mushi credentials from the environment when they are not\n * supplied explicitly. This lets every framework init work with\n * zero-config — just run `npx mushi-mushi` once, add the .env.local\n * line, and the provider/plugin/init works without props.\n *\n * Resolution order per field:\n * 1. Vite / SvelteKit / Angular (VITE_MUSHI_*)\n * 2. Next.js (NEXT_PUBLIC_MUSHI_*)\n * 3. Nuxt (NUXT_PUBLIC_MUSHI_*)\n * 4. Expo managed workflow (EXPO_PUBLIC_MUSHI_*)\n * 5. Node / React Native / server (bare MUSHI_*)\n *\n * Vite statically replaces `import.meta.env.VITE_*` at build time, so the\n * literal key references here are intentional — they make bundlers replace\n * the values even when accessed indirectly.\n *\n * Next.js and Expo, by contrast, do STATIC string replacement that only\n * inlines literal `process.env.NEXT_PUBLIC_*` / `process.env.EXPO_PUBLIC_*`\n * dot-notation references. A dynamic `process.env[key]` lookup is explicitly\n * unsupported and silently resolves to `undefined` in production client\n * bundles (Expo even ships an ESLint rule against it). Every `process.env`\n * read below is therefore a literal, statically-analyzable reference.\n */\n\nexport interface ResolvedEnvConfig {\n projectId?: string;\n apiKey?: string;\n apiEndpoint?: string;\n}\n\nfunction first(...values: (string | undefined)[]): string | undefined {\n return values.find((v) => v !== undefined && v !== '');\n}\n\nfunction tryImportMetaEnv(key: string): string | undefined {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const env = (import.meta as any).env;\n return typeof env === 'object' && env !== null ? (env[key] as string | undefined) : undefined;\n } catch {\n return undefined;\n }\n}\n\n// `process` is declared locally because the core package intentionally omits\n// `@types/node` to stay browser-safe. The reads below MUST use literal\n// `process.env.<KEY>` dot-notation (never `process.env[key]`) so Next.js and\n// Expo can inline the values during their build-time static replacement pass.\ndeclare const process: { env: Record<string, string | undefined> };\n\n/**\n * Evaluate a literal `process.env.<KEY>` read, degrading to `undefined` when\n * `process` is not defined (a pure browser runtime where the bundler did not\n * inline the value) instead of throwing a ReferenceError.\n */\nfunction readProcessEnv(read: () => string | undefined): string | undefined {\n try {\n return read();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Reads Mushi projectId, apiKey, and (optionally) apiEndpoint from\n * the environment. Returns only the fields that are present so callers\n * can cleanly spread: `{ ...resolveEnvConfig(), ...explicitConfig }`.\n */\nexport function resolveEnvConfig(): ResolvedEnvConfig {\n const projectId = first(\n tryImportMetaEnv('VITE_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_PROJECT_ID'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_PROJECT_ID),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_PROJECT_ID),\n readProcessEnv(() => process.env.MUSHI_PROJECT_ID),\n );\n\n const apiKey = first(\n tryImportMetaEnv('VITE_MUSHI_API_KEY'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_API_KEY'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_API_KEY'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_API_KEY'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_KEY),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_KEY),\n readProcessEnv(() => process.env.MUSHI_API_KEY),\n );\n\n const apiEndpoint = first(\n tryImportMetaEnv('VITE_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_API_ENDPOINT'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_ENDPOINT),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_ENDPOINT),\n readProcessEnv(() => process.env.MUSHI_API_ENDPOINT),\n );\n\n const result: ResolvedEnvConfig = {};\n if (projectId) result.projectId = projectId;\n if (apiKey) result.apiKey = apiKey;\n if (apiEndpoint) result.apiEndpoint = apiEndpoint;\n return result;\n}\n","import type { MushiPreFilterConfig } from './types';\n\nexport interface PreFilterResult {\n passed: boolean;\n reason?: string;\n}\n\nconst DEFAULT_MIN_LENGTH = 10;\nconst DEFAULT_MAX_LENGTH = 2000;\n\nconst SPAM_PATTERNS: RegExp[] = [\n /^(.)\\1{10,}$/, // repeated single character\n /^[A-Z\\s!?]{20,}$/, // all caps shouting\n /^[\\d\\s]+$/, // numbers only\n /^[^a-zA-Z\\u00C0-\\u024F\\u4E00-\\u9FFF\\u3040-\\u309F\\u30A0-\\u30FF]{10,}$/, // no real letters\n // \"test\" removed — users legitimately write \"I was testing…\" in real reports.\n // Keep clearly-nonsense patterns that are never real sentences.\n /^(asdf|qwerty|lorem ipsum)[.,!?\\s]*$/i, // standalone keyboard-mash or placeholder\n];\n\nconst GIBBERISH_PATTERN = /^[bcdfghjklmnpqrstvwxz]{6,}/i; // consonant-only strings\n\nexport function createPreFilter(config: MushiPreFilterConfig = {}) {\n const {\n enabled = true,\n blockObviousSpam = true,\n minDescriptionLength = DEFAULT_MIN_LENGTH,\n maxDescriptionLength = DEFAULT_MAX_LENGTH,\n } = config;\n\n function check(description: string): PreFilterResult {\n if (!enabled) {\n return { passed: true };\n }\n\n const trimmed = description.trim();\n\n if (trimmed.length < minDescriptionLength) {\n return { passed: false, reason: `Too short (min ${minDescriptionLength} characters)` };\n }\n\n if (trimmed.length > maxDescriptionLength) {\n return { passed: false, reason: `Too long (max ${maxDescriptionLength} characters)` };\n }\n\n if (blockObviousSpam) {\n for (const pattern of SPAM_PATTERNS) {\n if (pattern.test(trimmed)) {\n return { passed: false, reason: 'Detected as spam' };\n }\n }\n\n if (GIBBERISH_PATTERN.test(trimmed)) {\n return { passed: false, reason: 'Detected as gibberish' };\n }\n\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 1);\n if (words.length < 2) {\n return { passed: false, reason: 'Description needs at least 2 words' };\n }\n }\n\n return { passed: true };\n }\n\n function truncate(description: string): string {\n const trimmed = description.trim();\n if (trimmed.length <= maxDescriptionLength) return trimmed;\n return trimmed.slice(0, maxDescriptionLength) + '...';\n }\n\n return { check, truncate };\n}\n","/**\n * FILE: logger.ts\n * PURPOSE: Zero-dependency structured logger for the mushi-mushi SDK ecosystem.\n *\n * OVERVIEW:\n * - Production-grade logging with levels, scoped namespaces, and child loggers\n * - JSON output for server/production, pretty-formatted output for development\n * - Automatic environment detection (browser vs Node vs Deno)\n * - Structured metadata on every log entry\n * - No external dependencies — safe to ship in any SDK bundle\n *\n * USAGE:\n * import { createLogger } from '@mushi-mushi/core'\n * const log = createLogger({ scope: 'mushi:api' })\n * log.info('Request received', { method: 'POST', path: '/v1/reports' })\n * const child = log.child('ingest', { reportId: 'abc' })\n * child.warn('Slow query', { latencyMs: 420 })\n *\n * TECHNICAL DETAILS:\n * - Log levels: debug(10) < info(20) < warn(30) < error(40) < fatal(50) < silent(99)\n * - Format auto-detected: JSON in production/server, pretty in development\n * - Pretty format uses ANSI colors when supported (Node/Deno TTY)\n * - Child loggers inherit parent scope + metadata, can override level\n * - Timestamps are ISO 8601 with millisecond precision\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent'\n\nexport type LogFormat = 'json' | 'pretty' | 'auto'\n\nexport interface LoggerOptions {\n scope: string\n level?: LogLevel\n meta?: Record<string, unknown>\n format?: LogFormat\n /**\n * Where to write log output.\n * - `'stdout'` (default): normal servers, browsers.\n * - `'stderr'`: use for stdio MCP servers where stdout is the JSON-RPC\n * protocol pipe; any non-JSON-RPC bytes there corrupt the connection.\n */\n destination?: 'stdout' | 'stderr'\n}\n\nexport interface Logger {\n debug(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n error(msg: string, meta?: Record<string, unknown>): void\n fatal(msg: string, meta?: Record<string, unknown>): void\n child(scope: string, meta?: Record<string, unknown>): Logger\n setLevel(level: LogLevel): void\n}\n\nexport interface LogEntry {\n ts: string\n level: LogLevel\n scope: string\n msg: string\n [key: string]: unknown\n}\n\nconst LEVEL_VALUE: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n fatal: 50,\n silent: 99,\n}\n\nconst LEVEL_LABEL: Record<string, string> = {\n debug: 'DBG',\n info: 'INF',\n warn: 'WRN',\n error: 'ERR',\n fatal: 'FTL',\n}\n\nconst ANSI = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n white: '\\x1b[37m',\n bgRed: '\\x1b[41m',\n} as const\n\nconst LEVEL_COLOR: Record<string, string> = {\n debug: ANSI.dim,\n info: ANSI.green,\n warn: ANSI.yellow,\n error: ANSI.red,\n fatal: `${ANSI.bgRed}${ANSI.white}${ANSI.bold}`,\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nfunction detectFormat(): 'json' | 'pretty' {\n try {\n if (typeof (globalThis as any).Deno !== 'undefined') return 'json'\n } catch { /* not Deno */ }\n\n const proc = typeof (globalThis as any).process !== 'undefined'\n ? (globalThis as any).process\n : undefined\n\n if (proc?.env) {\n if (proc.env.NODE_ENV === 'production') return 'json'\n if (proc.env.LOG_FORMAT === 'json') return 'json'\n if (proc.env.LOG_FORMAT === 'pretty') return 'pretty'\n if (proc.stdout?.isTTY) return 'pretty'\n }\n\n if (typeof (globalThis as any).window !== 'undefined') return 'pretty'\n\n return 'json'\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nfunction flattenMeta(meta: Record<string, unknown>): string {\n const parts: string[] = []\n for (const [k, v] of Object.entries(meta)) {\n if (v === undefined || v === null) continue\n if (typeof v === 'object') {\n parts.push(`${k}=${JSON.stringify(v)}`)\n } else {\n parts.push(`${k}=${String(v)}`)\n }\n }\n return parts.join(' ')\n}\n\nfunction formatPretty(entry: LogEntry): string {\n const { ts, level, scope, msg, ...rest } = entry\n const time = ts.slice(11, 23)\n const color = LEVEL_COLOR[level] ?? ''\n const label = LEVEL_LABEL[level] ?? level.toUpperCase()\n const metaStr = Object.keys(rest).length > 0 ? ` ${ANSI.dim}${flattenMeta(rest)}${ANSI.reset}` : ''\n\n return `${ANSI.dim}${time}${ANSI.reset} ${color}${label}${ANSI.reset} ${ANSI.cyan}[${scope}]${ANSI.reset} ${msg}${metaStr}`\n}\n\nfunction formatJson(entry: LogEntry): string {\n return JSON.stringify(entry)\n}\n\n/* eslint-disable no-console */\nfunction makeEmitter(destination: 'stdout' | 'stderr') {\n if (destination === 'stderr') {\n // Write everything to stderr — required for stdio MCP servers.\n return (level: LogLevel, formatted: string): void => {\n void level\n console.error(formatted)\n }\n }\n return (level: LogLevel, formatted: string): void => {\n switch (level) {\n case 'error':\n case 'fatal':\n console.error(formatted)\n break\n case 'warn':\n console.warn(formatted)\n break\n default:\n console.log(formatted)\n }\n }\n}\n/* eslint-enable no-console */\n\nfunction buildLogger(\n scope: string,\n minLevel: LogLevel,\n baseMeta: Record<string, unknown>,\n formatter: (entry: LogEntry) => string,\n emit: (level: LogLevel, formatted: string) => void,\n): Logger {\n let currentLevel = minLevel\n\n function log(level: LogLevel, msg: string, meta?: Record<string, unknown>): void {\n if (LEVEL_VALUE[level] < LEVEL_VALUE[currentLevel]) return\n\n const entry: LogEntry = {\n ts: new Date().toISOString(),\n level,\n scope,\n msg,\n ...baseMeta,\n ...meta,\n }\n\n emit(level, formatter(entry))\n }\n\n return {\n debug: (msg, meta?) => log('debug', msg, meta),\n info: (msg, meta?) => log('info', msg, meta),\n warn: (msg, meta?) => log('warn', msg, meta),\n error: (msg, meta?) => log('error', msg, meta),\n fatal: (msg, meta?) => log('fatal', msg, meta),\n\n child(childScope: string, childMeta?: Record<string, unknown>): Logger {\n return buildLogger(\n `${scope}:${childScope}`,\n currentLevel,\n { ...baseMeta, ...childMeta },\n formatter,\n emit,\n )\n },\n\n setLevel(level: LogLevel) {\n currentLevel = level\n },\n }\n}\n\n/**\n * Create a structured logger instance.\n *\n * @example\n * const log = createLogger({ scope: 'mushi:api', level: 'info' })\n * log.info('Server started', { port: 3000 })\n *\n * const child = log.child('auth', { userId: 'u-123' })\n * child.warn('Token expired')\n */\nexport function createLogger(options: LoggerOptions): Logger {\n const {\n scope,\n level = 'info',\n meta = {},\n format = 'auto',\n destination = 'stdout',\n } = options\n\n const resolvedFormat = format === 'auto' ? detectFormat() : format\n const formatter = resolvedFormat === 'json' ? formatJson : formatPretty\n const emit = makeEmitter(destination)\n\n return buildLogger(scope, level, meta, formatter, emit)\n}\n\n/**\n * Noop logger that discards all output.\n * Useful when logging should be completely disabled.\n */\nexport const noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {},\n child: () => noopLogger,\n setLevel: () => {},\n}\n","/**\n * AES-GCM at-rest encryption for the offline queue (Wave S1 / D-16).\n *\n * Why this exists: on shared devices (kiosks, support-agent laptops) a\n * queued bug report sits in plaintext IndexedDB until the next flush.\n * Browser extensions, other tabs on the same origin, and forensic tools\n * with disk access can all read it. For a QA/bug-reporting SDK that\n * encourages users to paste sensitive data into descriptions, that's\n * unacceptable.\n *\n * Design:\n * - Generate a non-extractable AES-GCM key on first call (256-bit).\n * - Persist the `CryptoKey` object itself (Web Crypto allows IDB round-\n * trip of `CryptoKey` without ever serialising the raw bytes).\n * - Use a 12-byte random IV per payload; prepend it to ciphertext so\n * decrypt() needs no out-of-band state.\n * - Never block the caller — all errors bubble up so the queue can fall\n * back to plaintext storage with a debug log (see queue.ts).\n *\n * The key is tied to the browser origin (same-origin IDB). It does NOT\n * protect against an attacker with admin shell on the device: the browser\n * WILL decrypt on demand for anyone with origin access. That's the same\n * guarantee every origin-bound browser secret has and is the correct\n * threat model for offline bug reports.\n */\n\nconst KEY_DB = 'mushi-mushi-keyring';\nconst KEY_STORE = 'keys';\nconst KEY_RECORD_ID = 'offline-queue/v1';\n\nlet cachedKey: CryptoKey | null = null;\nlet cachedKeyPromise: Promise<CryptoKey> | null = null;\n\nfunction hasWebCrypto(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as unknown as { crypto?: Crypto }).crypto !== 'undefined' &&\n typeof (globalThis as unknown as { crypto: Crypto }).crypto.subtle !== 'undefined' &&\n typeof indexedDB !== 'undefined'\n );\n}\n\nfunction openKeyDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(KEY_DB, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(KEY_STORE)) {\n db.createObjectStore(KEY_STORE);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function loadKey(): Promise<CryptoKey | null> {\n const db = await openKeyDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(KEY_STORE, 'readonly');\n const req = tx.objectStore(KEY_STORE).get(KEY_RECORD_ID);\n req.onsuccess = () => resolve((req.result as CryptoKey) ?? null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function storeKey(key: CryptoKey): Promise<void> {\n const db = await openKeyDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(KEY_STORE, 'readwrite');\n tx.objectStore(KEY_STORE).put(key, KEY_RECORD_ID);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Lazily get (or generate once + persist) the AES-GCM key for this origin.\n * `extractable: false` — so a script-level attacker can't `exportKey()` and\n * ship the raw bytes to their server, only use it via `encrypt`/`decrypt`.\n */\nexport async function getOfflineQueueKey(): Promise<CryptoKey> {\n if (cachedKey) return cachedKey;\n if (cachedKeyPromise) return cachedKeyPromise;\n if (!hasWebCrypto()) {\n throw new Error('Web Crypto + IndexedDB required for offline queue encryption');\n }\n cachedKeyPromise = (async () => {\n const existing = await loadKey();\n if (existing) {\n cachedKey = existing;\n return existing;\n }\n const key = await crypto.subtle.generateKey(\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n await storeKey(key);\n cachedKey = key;\n return key;\n })();\n return cachedKeyPromise;\n}\n\nexport interface EncryptedPayload {\n /** Magic marker so decrypt() can tell encrypted vs legacy plaintext rows. */\n readonly _mme: 1;\n readonly iv: string;\n readonly ct: string;\n}\n\nfunction bytesToB64(bytes: Uint8Array): string {\n let s = '';\n for (const b of bytes) s += String.fromCharCode(b);\n return btoa(s);\n}\n\nfunction b64ToBytes(s: string): Uint8Array<ArrayBuffer> {\n const bin = atob(s);\n const out = new Uint8Array(new ArrayBuffer(bin.length));\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport async function encryptJson(plain: unknown): Promise<EncryptedPayload> {\n const key = await getOfflineQueueKey();\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const data = new TextEncoder().encode(JSON.stringify(plain));\n const cipher = new Uint8Array(await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data));\n return { _mme: 1, iv: bytesToB64(iv), ct: bytesToB64(cipher) };\n}\n\nexport function isEncryptedPayload(v: unknown): v is EncryptedPayload {\n return (\n !!v &&\n typeof v === 'object' &&\n (v as EncryptedPayload)._mme === 1 &&\n typeof (v as EncryptedPayload).iv === 'string' &&\n typeof (v as EncryptedPayload).ct === 'string'\n );\n}\n\nexport async function decryptJson<T = unknown>(payload: EncryptedPayload): Promise<T> {\n const key = await getOfflineQueueKey();\n const iv = b64ToBytes(payload.iv);\n const ct = b64ToBytes(payload.ct);\n const plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct);\n return JSON.parse(new TextDecoder().decode(plain)) as T;\n}\n","import type { MushiApiClient, MushiOfflineConfig, MushiReport } from './types';\nimport { createLogger } from './logger';\nimport {\n encryptJson,\n decryptJson,\n isEncryptedPayload,\n type EncryptedPayload,\n} from './queue-crypto';\n\nconst queueLog = createLogger({ scope: 'mushi:queue', level: 'warn' });\n\n// Wave S1 / D-16: opaque at-rest wrapper. Each queue row is either:\n// - a legacy plaintext `MushiReport` (pre-encryption; still readable)\n// - an `EncryptedRecord` with a bare `id` (so count / delete can operate\n// without decrypting every row) plus the encrypted payload blob.\ninterface EncryptedRecord {\n id: string;\n queuedAt: string;\n payload: EncryptedPayload;\n}\n\ntype StoredRow = MushiReport | EncryptedRecord;\n\nconst DB_NAME = 'mushi-mushi';\nconst STORE_NAME = 'offline-reports';\nconst DB_VERSION = 1;\nconst LS_KEY = 'mushi_offline_queue';\nconst BATCH_SIZE = 10;\nconst MAX_BACKOFF_MS = 60_000;\nconst AUTO_FLUSH_INTERVAL_MS = 30_000;\n// A queued report that can never be delivered (corrupt payload, a permanently\n// offline host, or a network layer that keeps rejecting the POST) must not\n// loop forever — otherwise it hammers the API and floods the console on every\n// flush tick and page load. Two independent give-up gates bound the retry\n// surface:\n// - MAX_DELIVERY_ATTEMPTS: drop a row after this many transient failures.\n// - MAX_QUEUE_AGE_MS: hard backstop — evict any row older than this on the\n// next flush regardless of attempt count (also clears legacy rows that\n// predate the per-row attempt counter so they stop re-flushing).\nconst MAX_DELIVERY_ATTEMPTS = 8;\nconst MAX_QUEUE_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport interface OfflineQueue {\n enqueue(report: MushiReport): Promise<void>;\n flush(client: MushiApiClient): Promise<{ sent: number; failed: number }>;\n size(): Promise<number>;\n clear(): Promise<void>;\n startAutoSync(client: MushiApiClient): void;\n stopAutoSync(): void;\n}\n\ntype StorageBackend = 'indexeddb' | 'localstorage' | 'none';\n\nexport function createOfflineQueue(config: MushiOfflineConfig = {}): OfflineQueue {\n const { enabled = true, maxQueueSize = 50, syncOnReconnect = true, encryptAtRest = true } = config;\n\n let syncCleanup: (() => void) | null = null;\n let flushInterval: ReturnType<typeof setInterval> | null = null;\n let backendType: StorageBackend | null = null;\n\n async function wrapForStorage(report: MushiReport): Promise<StoredRow> {\n const queuedAt = new Date().toISOString();\n if (!encryptAtRest) {\n return { ...report, queuedAt } as MushiReport;\n }\n try {\n const payload = await encryptJson(report);\n return { id: report.id, queuedAt, payload } satisfies EncryptedRecord;\n } catch (err) {\n // Encryption failure is non-fatal — queue integrity matters more than\n // at-rest confidentiality. We fall back to plaintext and warn.\n queueLog.warn('Offline queue: encryption failed, storing plaintext', { err: String(err) });\n return { ...report, queuedAt } as MushiReport;\n }\n }\n\n async function unwrapForSend(row: StoredRow): Promise<MushiReport | null> {\n if (isEncryptedRecord(row)) {\n try {\n return await decryptJson<MushiReport>(row.payload);\n } catch (err) {\n queueLog.warn('Offline queue: decrypt failed, dropping row', { err: String(err), id: row.id });\n return null;\n }\n }\n return row;\n }\n\n function isEncryptedRecord(row: StoredRow): row is EncryptedRecord {\n return !!(row as EncryptedRecord).payload && isEncryptedPayload((row as EncryptedRecord).payload);\n }\n\n // The delivery-attempt counter lives on the OUTER row (alongside `id` /\n // `queuedAt`), so it can be read and bumped for an encrypted record without\n // decrypting the payload.\n function rowAttempts(row: StoredRow): number {\n const n = (row as { attempts?: number }).attempts;\n return typeof n === 'number' && Number.isFinite(n) ? n : 0;\n }\n\n // True when a row has outlived MAX_QUEUE_AGE_MS. Rows without a parseable\n // `queuedAt` are never age-evicted here — the attempt counter is their gate.\n function isExpired(row: StoredRow, now: number): boolean {\n const queuedAt = (row as { queuedAt?: string }).queuedAt;\n if (!queuedAt) return false;\n const ts = Date.parse(queuedAt);\n if (Number.isNaN(ts)) return false;\n return now - ts > MAX_QUEUE_AGE_MS;\n }\n\n function detectBackend(): StorageBackend {\n if (backendType) return backendType;\n if (typeof indexedDB !== 'undefined') {\n backendType = 'indexeddb';\n } else if (typeof localStorage !== 'undefined') {\n backendType = 'localstorage';\n } else {\n backendType = 'none';\n }\n return backendType;\n }\n\n // --- IndexedDB backend ---\n\n function openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n backendType = 'localstorage';\n reject(request.error);\n };\n });\n }\n\n async function idbEnqueue(report: MushiReport): Promise<void> {\n const db = await openDb();\n const row = await wrapForStorage(report);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).put(row);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbGetAll(): Promise<StoredRow[]> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).getAll();\n request.onsuccess = () => resolve(request.result as StoredRow[]);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbDelete(id: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).delete(id);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // Overwrite an existing row in place (keyed by `id`) — used to persist the\n // incremented attempt counter after a transient failure.\n async function idbPutRow(row: StoredRow): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).put(row);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbSize(): Promise<number> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).count();\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbClear(): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // --- localStorage fallback ---\n\n function lsRead(): StoredRow[] {\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? (JSON.parse(raw) as StoredRow[]) : [];\n } catch {\n return [];\n }\n }\n\n function lsWrite(rows: StoredRow[]): void {\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(rows));\n } catch {\n // localStorage full or unavailable\n }\n }\n\n async function lsEnqueue(report: MushiReport): Promise<void> {\n const rows = lsRead();\n rows.push(await wrapForStorage(report));\n lsWrite(rows);\n }\n\n function lsDelete(id: string): void {\n const rows = lsRead().filter((r) => r.id !== id);\n lsWrite(rows);\n }\n\n // Replace an existing row in place (matched by `id`) — used to persist the\n // incremented attempt counter after a transient failure.\n function lsUpdateRow(row: StoredRow): void {\n const rows = lsRead();\n const idx = rows.findIndex((r) => (r as { id: string }).id === (row as { id: string }).id);\n if (idx >= 0) {\n rows[idx] = row;\n lsWrite(rows);\n }\n }\n\n // --- Backend-aware row mutators ---\n //\n // A queue row lives in exactly one backend (chosen once per session by\n // detectBackend). We must NOT cross-write to the other backend on failure: a\n // row read from IndexedDB does not exist in localStorage, so an `lsDelete` /\n // `lsUpdateRow` fallback is a guaranteed silent no-op. The earlier\n // `catch { lsUpdateRow(row) }` form meant a failed IndexedDB attempt-counter\n // write never persisted, so the row re-flushed forever (bypassing\n // MAX_DELIVERY_ATTEMPTS) until the 24h age sweep — see Sentry 14751132/0.\n\n // Remove a row from the active backend. A failure is non-fatal: the row\n // survives to the next flush, where the MAX_QUEUE_AGE_MS sweep is the\n // backstop. No cross-backend fallback (see note above).\n async function removeRow(backend: StorageBackend, rowId: string): Promise<void> {\n try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch (err) {\n queueLog.debug('Offline queue: row removal failed (will age out)', {\n id: rowId,\n err: String(err),\n });\n }\n }\n\n // Persist a row in place to save its bumped attempt counter. Returns false\n // when the write could not land, so the caller can give up on the row rather\n // than loop forever on a counter that never advances. No cross-backend\n // fallback (see note above).\n async function persistRow(backend: StorageBackend, row: StoredRow): Promise<boolean> {\n try {\n if (backend === 'indexeddb') await idbPutRow(row);\n else lsUpdateRow(row);\n return true;\n } catch (err) {\n queueLog.debug('Offline queue: row persist failed', {\n id: (row as { id: string }).id,\n err: String(err),\n });\n return false;\n }\n }\n\n // --- Unified interface ---\n\n async function enqueue(report: MushiReport): Promise<void> {\n if (!enabled) return;\n\n const currentSize = await size();\n if (currentSize >= maxQueueSize) {\n queueLog.warn('Offline queue full — dropping report', { maxQueueSize });\n return;\n }\n\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbEnqueue(report);\n return;\n } catch {\n // IndexedDB failed, fall through to localStorage\n backendType = 'localstorage';\n }\n }\n\n if (backend === 'localstorage' || backendType === 'localstorage') {\n await lsEnqueue(report);\n return;\n }\n }\n\n function getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, MAX_BACKOFF_MS);\n }\n\n function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async function flush(client: MushiApiClient): Promise<{ sent: number; failed: number }> {\n if (!enabled) return { sent: 0, failed: 0 };\n\n let rows: StoredRow[];\n const backend = detectBackend();\n\n if (backend === 'indexeddb') {\n try {\n rows = await idbGetAll();\n } catch {\n rows = lsRead();\n }\n } else {\n rows = lsRead();\n }\n\n // Backstop: evict any row that has outlived MAX_QUEUE_AGE_MS before we\n // spend a network attempt on it. This sweeps the whole queue (IndexedDB\n // getAll() is key-ordered, not FIFO, so a stale row may not be in the\n // batch window) and clears legacy rows that predate the attempt counter so\n // they can't re-flush forever on every page load.\n const now = Date.now();\n const fresh: StoredRow[] = [];\n for (const row of rows) {\n if (isExpired(row, now)) {\n const rowId = (row as { id: string }).id;\n await removeRow(backend, rowId);\n queueLog.debug('Offline queue: evicting stale report', { id: rowId });\n } else {\n fresh.push(row);\n }\n }\n rows = fresh;\n\n const batch = rows.slice(0, BATCH_SIZE);\n let sent = 0;\n let failed = 0;\n\n for (let i = 0; i < batch.length; i++) {\n const row = batch[i];\n const rowId = (row as { id: string }).id;\n const report = await unwrapForSend(row);\n\n if (!report) {\n // Undecryptable row — drop so it doesn't re-poison the queue forever.\n await removeRow(backend, rowId);\n failed++;\n continue;\n }\n\n const result = await client.submitReport(report);\n\n if (result.ok) {\n await removeRow(backend, rowId);\n sent++;\n } else {\n const permanent =\n result.error?.code === 'HTTP_400' ||\n result.error?.code === 'HTTP_413' ||\n result.error?.code === 'HTTP_422' ||\n result.error?.code === 'INGEST_ERROR' ||\n result.error?.code === 'VALIDATION_ERROR' ||\n // A payload that exceeds the size guard will never shrink on its own;\n // retrying re-serialises the multi-MB body every sync tick and wedges\n // the queue (it matches neither permanent nor transient otherwise).\n // SERIALIZE_FAILED (circular ref) is likewise unrecoverable on retry.\n result.error?.code === 'PAYLOAD_TOO_LARGE' ||\n result.error?.code === 'SERIALIZE_FAILED' ||\n (typeof result.error?.message === 'string' &&\n /invalid payload|description must be at least|validation/i.test(\n result.error.message,\n ));\n const transient =\n !permanent &&\n (result.error?.code === 'NETWORK_ERROR' ||\n result.error?.code === 'HTTP_403' ||\n result.error?.code === 'HTTP_429' ||\n result.error?.code === 'HTTP_502' ||\n result.error?.code === 'HTTP_503' ||\n result.error?.code === 'HTTP_504' ||\n (typeof result.error?.code === 'string' && result.error.code.startsWith('HTTP_5')));\n if (permanent) {\n await removeRow(backend, rowId);\n } else if (transient) {\n // Bump the per-row attempt counter and give up once it crosses the\n // ceiling, so a report the network keeps rejecting eventually leaves\n // the queue instead of retrying forever on every flush + page load.\n const nextAttempts = rowAttempts(row) + 1;\n if (nextAttempts >= MAX_DELIVERY_ATTEMPTS) {\n await removeRow(backend, rowId);\n queueLog.warn('Offline queue: giving up on report after repeated failures', {\n id: rowId,\n attempts: nextAttempts,\n code: result.error?.code,\n });\n } else {\n (row as { attempts?: number }).attempts = nextAttempts;\n const persisted = await persistRow(backend, row);\n if (persisted) {\n queueLog.debug('Offline queue: transient failure, will retry', {\n id: rowId,\n attempts: nextAttempts,\n code: result.error?.code,\n });\n } else {\n // The bumped counter could not be saved (e.g. an IndexedDB write\n // failure). Leaving the row would re-flush it forever with a\n // counter that never advances, defeating MAX_DELIVERY_ATTEMPTS —\n // so drop it now rather than wait 24h for the age sweep.\n await removeRow(backend, rowId);\n queueLog.warn('Offline queue: dropping report (attempt counter unpersistable)', {\n id: rowId,\n code: result.error?.code,\n });\n }\n }\n }\n failed++;\n if (i < batch.length - 1) {\n await sleep(getBackoffDelay(i));\n }\n }\n }\n\n return { sent, failed };\n }\n\n async function size(): Promise<number> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n return await idbSize();\n } catch {\n return lsRead().length;\n }\n }\n return lsRead().length;\n }\n\n async function clear(): Promise<void> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbClear();\n } catch {\n // fall through\n }\n }\n try {\n localStorage.removeItem(LS_KEY);\n } catch {\n // unavailable\n }\n }\n\n function startAutoSync(client: MushiApiClient): void {\n if (!enabled || !syncOnReconnect || typeof window === 'undefined') return;\n\n const tryFlush = () => {\n if (navigator.onLine) {\n flush(client).catch(() => {});\n }\n };\n\n window.addEventListener('online', tryFlush);\n flushInterval = setInterval(() => {\n void size().then((n) => {\n if (n > 0) tryFlush();\n });\n }, AUTO_FLUSH_INTERVAL_MS);\n syncCleanup = () => {\n window.removeEventListener('online', tryFlush);\n if (flushInterval) {\n clearInterval(flushInterval);\n flushInterval = null;\n }\n };\n }\n\n function stopAutoSync(): void {\n syncCleanup?.();\n syncCleanup = null;\n }\n\n return { enqueue, flush, size, clear, startAutoSync, stopAutoSync };\n}\n","import type { MushiEnvironment } from './types';\n\n/**\n * Capture a snapshot of the runtime environment. Called once per\n * report submission, so every read here must be:\n *\n * 1. Synchronous (UA-Client Hints `getHighEntropyValues()` is the\n * sole exception — see `kickOffUserAgentData` below; the result\n * is memoised and folded back in on the next capture).\n * 2. SSR-safe (every `window`/`document`/`navigator` access must be\n * gated on `typeof X !== 'undefined'` because the SDK is\n * imported by Next.js / Remix server bundles).\n * 3. Tolerant of missing APIs (Safari doesn't have `Network\n * Information`, Firefox doesn't have UA-CH, screen.orientation is\n * flaky on iOS) — every individual field is optional so a\n * partially-supported browser still produces a useful payload.\n */\nexport function captureEnvironment(): MushiEnvironment {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined;\n const win = typeof window !== 'undefined' ? window : undefined;\n const doc = typeof document !== 'undefined' ? document : undefined;\n const scr = typeof screen !== 'undefined' ? screen : undefined;\n\n // Trigger UA-CH high-entropy resolution in the background. The first\n // capture lands without it; the second one (and every subsequent one)\n // gets the cached values folded in. We tolerate the gap because the\n // alternative is making `captureEnvironment` async — and that would\n // ripple into every call site (the offline queue, the diagnostics\n // worker, the proactive trigger pipeline) for a field that's only\n // useful when the browser happens to be Chromium.\n void kickOffUserAgentData(nav);\n\n const connection = nav && 'connection' in nav ? (nav as NavigatorWithConnection).connection : undefined;\n\n return {\n userAgent: nav?.userAgent ?? 'unknown',\n platform: nav?.platform ?? 'unknown',\n language: nav?.language ?? 'en',\n viewport: {\n width: win?.innerWidth ?? 0,\n height: win?.innerHeight ?? 0,\n },\n url: win?.location?.href ?? '',\n referrer: doc?.referrer ?? '',\n timestamp: new Date().toISOString(),\n timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? 'UTC',\n connection: connection\n ? {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n }\n : undefined,\n deviceMemory: (nav as NavigatorWithDeviceMemory)?.deviceMemory,\n hardwareConcurrency: nav?.hardwareConcurrency,\n route: win?.location?.pathname,\n nearestTestid: findNearestTestidFromActive(doc),\n\n userAgentData: captureUserAgentData(nav),\n screen: captureScreen(scr, win),\n prefersColorScheme: matchScheme(win),\n prefersReducedMotion: matchMedia(win, '(prefers-reduced-motion: reduce)'),\n prefersReducedData: matchMedia(win, '(prefers-reduced-data: reduce)'),\n prefersContrast: matchContrast(win),\n forcedColors: matchMedia(win, '(forced-colors: active)'),\n online: typeof nav?.onLine === 'boolean' ? nav.onLine : undefined,\n displayMode: matchDisplayMode(win),\n documentTitle: doc?.title?.slice(0, 200),\n buildId: readBuildIdMeta(doc),\n pageLoadTiming: capturePageLoadTiming(win),\n };\n}\n\n/**\n * Best-effort `data-testid` resolver for freeform reports — when the user\n * opens the widget without first using the element selector we still want\n * to map the report to an Action. We start from `document.activeElement`\n * (which is the most-recently-focused interactive element on most browsers)\n * and walk up. Falls back to undefined when no testid is in scope.\n *\n * Mirrors the walk in `packages/web/src/capture/element-selector.ts` so\n * both code paths produce the same value for the same DOM state.\n */\nfunction findNearestTestidFromActive(doc?: Document): string | undefined {\n if (!doc) return undefined;\n let cur: Element | null = doc.activeElement ?? null;\n let hops = 0;\n while (cur && hops < 20) {\n const tid = cur.getAttribute?.('data-testid');\n if (tid) return tid;\n cur = cur.parentElement;\n hops++;\n }\n return undefined;\n}\n\n// ---- UA-Client Hints (Chromium) ---------------------------------------------\n\ninterface UserAgentDataLow {\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n platform?: string;\n}\ninterface UserAgentDataHigh extends UserAgentDataLow {\n architecture?: string;\n bitness?: string;\n model?: string;\n platformVersion?: string;\n uaFullVersion?: string;\n fullVersionList?: Array<{ brand: string; version: string }>;\n}\ninterface NavigatorWithUAData extends Navigator {\n userAgentData?: UserAgentDataLow & {\n getHighEntropyValues?: (hints: string[]) => Promise<UserAgentDataHigh>;\n };\n}\n\nlet cachedHighEntropy: UserAgentDataHigh | null = null;\nlet highEntropyKickedOff = false;\n\nfunction kickOffUserAgentData(nav: Navigator | undefined): void {\n if (highEntropyKickedOff) return;\n const ua = (nav as NavigatorWithUAData | undefined)?.userAgentData;\n if (!ua?.getHighEntropyValues) return;\n highEntropyKickedOff = true;\n ua.getHighEntropyValues([\n 'architecture',\n 'bitness',\n 'model',\n 'platformVersion',\n 'uaFullVersion',\n 'fullVersionList',\n ])\n .then((v) => {\n cachedHighEntropy = v;\n })\n .catch(() => {\n // Some browsers reject the promise on cross-origin or insecure contexts;\n // we just carry on without the high-entropy bits.\n });\n}\n\n/**\n * Pick the most identifying brand from UA-CH `brands` — Chromium ships\n * with three: a stable real one (\"Chromium\" / \"Google Chrome\" / \"Brave\")\n * plus a placeholder (\"Not_A Brand\") that exists to test sniffer\n * tolerance. Skip the placeholder. Prefer non-Chromium-shell brands so\n * Brave / Edge / Opera identify as themselves rather than as Chromium.\n */\nfunction pickBrand(\n brands?: Array<{ brand: string; version: string }>,\n): { brand: string; version: string } | undefined {\n if (!brands?.length) return undefined;\n const real = brands.filter((b) => !/not.?a.?brand/i.test(b.brand));\n if (real.length === 0) return undefined;\n // Prefer a brand that isn't generic Chromium / Google Chrome — that's\n // the host browser when the user runs a derivative.\n const named = real.find((b) => !/chromium|google chrome/i.test(b.brand));\n return named ?? real[0];\n}\n\nfunction captureUserAgentData(nav: Navigator | undefined): MushiEnvironment['userAgentData'] {\n const low = (nav as NavigatorWithUAData | undefined)?.userAgentData;\n if (!low && !cachedHighEntropy) return undefined;\n const fullList = cachedHighEntropy?.fullVersionList;\n const brand = pickBrand(fullList ?? low?.brands);\n const out: NonNullable<MushiEnvironment['userAgentData']> = {};\n if (brand) {\n out.browser = brand.brand;\n out.browserVersion = brand.version;\n }\n // `platform` (low entropy) is e.g. \"macOS\", \"Windows\" — fine for a default.\n if (low?.platform) out.os = low.platform;\n if (cachedHighEntropy?.platformVersion) out.osVersion = cachedHighEntropy.platformVersion;\n if (typeof low?.mobile === 'boolean') out.mobile = low.mobile;\n if (cachedHighEntropy?.model) out.model = cachedHighEntropy.model;\n if (cachedHighEntropy?.architecture) out.architecture = cachedHighEntropy.architecture;\n if (cachedHighEntropy?.bitness) out.bitness = cachedHighEntropy.bitness;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\n// ---- Screen + media queries -------------------------------------------------\n\nfunction captureScreen(\n scr: Screen | undefined,\n win: Window | undefined,\n): MushiEnvironment['screen'] {\n if (!scr && !win) return undefined;\n const out: NonNullable<MushiEnvironment['screen']> = {};\n if (typeof scr?.width === 'number') out.width = scr.width;\n if (typeof scr?.height === 'number') out.height = scr.height;\n if (typeof win?.devicePixelRatio === 'number') out.devicePixelRatio = win.devicePixelRatio;\n if (typeof scr?.colorDepth === 'number') out.colorDepth = scr.colorDepth;\n // `screen.orientation` is intermittently undefined on iOS Safari, so we\n // can't lean on the standard `Screen` type — read it loosely via an\n // index access that tolerates the missing property at runtime.\n const orientationType = (scr as unknown as { orientation?: { type?: string } } | undefined)\n ?.orientation?.type;\n if (orientationType) out.orientation = orientationType;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\nfunction matchMedia(win: Window | undefined, query: string): boolean | undefined {\n if (!win?.matchMedia) return undefined;\n try {\n return win.matchMedia(query).matches;\n } catch {\n return undefined;\n }\n}\n\nfunction matchScheme(win: Window | undefined): MushiEnvironment['prefersColorScheme'] {\n if (!win?.matchMedia) return undefined;\n if (matchMedia(win, '(prefers-color-scheme: dark)')) return 'dark';\n if (matchMedia(win, '(prefers-color-scheme: light)')) return 'light';\n return 'no-preference';\n}\n\nfunction matchContrast(win: Window | undefined): MushiEnvironment['prefersContrast'] {\n if (!win?.matchMedia) return undefined;\n if (matchMedia(win, '(prefers-contrast: more)')) return 'more';\n if (matchMedia(win, '(prefers-contrast: less)')) return 'less';\n if (matchMedia(win, '(prefers-contrast: custom)')) return 'custom';\n return 'no-preference';\n}\n\nfunction matchDisplayMode(win: Window | undefined): MushiEnvironment['displayMode'] {\n if (!win?.matchMedia) return undefined;\n // Order matters: standalone implies !browser, fullscreen implies !standalone.\n // Walk most-specific-first.\n if (matchMedia(win, '(display-mode: fullscreen)')) return 'fullscreen';\n if (matchMedia(win, '(display-mode: standalone)')) return 'standalone';\n if (matchMedia(win, '(display-mode: minimal-ui)')) return 'minimal-ui';\n if (matchMedia(win, '(display-mode: browser)')) return 'browser';\n return undefined;\n}\n\n// ---- Build id from <meta name=\"mushi:build\"> --------------------------------\n\nfunction readBuildIdMeta(doc: Document | undefined): string | undefined {\n if (!doc) return undefined;\n const el = doc.querySelector?.('meta[name=\"mushi:build\"]') as HTMLMetaElement | null;\n const v = el?.content?.trim();\n if (!v) return undefined;\n // Cap at 64 chars — git SHAs are 40, semver+meta is well under that.\n // We don't want users accidentally shoving a manifest into a meta tag.\n return v.slice(0, 64);\n}\n\n// ---- Navigation timing ------------------------------------------------------\n\nfunction capturePageLoadTiming(win: Window | undefined): MushiEnvironment['pageLoadTiming'] {\n const perf = win?.performance;\n if (!perf?.getEntriesByType) return undefined;\n let entry: PerformanceNavigationTiming | undefined;\n try {\n const entries = perf.getEntriesByType('navigation') as PerformanceNavigationTiming[];\n entry = entries[0];\n } catch {\n return undefined;\n }\n if (!entry) return undefined;\n // `startTime` is in PerformanceEntry but TS sometimes types it as\n // `number` and sometimes the test mock omits it; treat as 0 when missing.\n const start = (entry as PerformanceNavigationTiming & { startTime?: number }).startTime ?? 0;\n const out: NonNullable<MushiEnvironment['pageLoadTiming']> = {};\n // `loadEventEnd === 0` while the page is still loading — only report\n // it once it's actually fired so a fresh capture during page load\n // doesn't claim \"load completed in 0ms\".\n if (entry.domContentLoadedEventEnd > 0)\n out.domContentLoadedMs = Math.round(entry.domContentLoadedEventEnd - start);\n if (entry.loadEventEnd > 0) out.loadCompleteMs = Math.round(entry.loadEventEnd - start);\n if (entry.responseStart > 0) out.timeToFirstByteMs = Math.round(entry.responseStart - start);\n if (typeof entry.type === 'string') out.navigationType = entry.type;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\ninterface NetworkInformation {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n}\n\ninterface NavigatorWithConnection extends Navigator {\n connection?: NetworkInformation;\n}\n\ninterface NavigatorWithDeviceMemory extends Navigator {\n deviceMemory?: number;\n}\n","const STORAGE_KEY = 'mushi_reporter_token';\n\nexport function getReporterToken(): string {\n if (typeof localStorage !== 'undefined') {\n const existing = localStorage.getItem(STORAGE_KEY);\n if (existing) return existing;\n }\n\n const token = generateToken();\n\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(STORAGE_KEY, token);\n } catch {\n // localStorage full or unavailable — token is ephemeral\n }\n }\n\n return token;\n}\n\nfunction generateToken(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return `mushi_${crypto.randomUUID()}`;\n }\n\n const bytes = new Uint8Array(16);\n if (typeof crypto !== 'undefined') {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `mushi_${hex}`;\n}\n","/**\n * RFC-4122 v4 UUID generator with a capability ladder so it works in every\n * runtime a Mushi SDK ships to:\n *\n * 1. `crypto.randomUUID()` — browsers (secure context), Node 19+, Deno\n * 2. `crypto.getRandomValues()` — older browsers, RN with a crypto polyfill\n * 3. `Math.random()` — Hermes / JSC without a crypto polyfill\n *\n * Why this exists: report ids are written to the `reports.id uuid` column on\n * the backend. SDKs that minted ad-hoc ids (`rn-<ts>-<rand>`, `mushi_<hex>`)\n * failed the Postgres uuid cast (22P02) and the report was silently dropped\n * (Sentry MUSHI-MUSHI-SERVER-D). Emitting a well-formed UUID at the source\n * keeps the value valid end-to-end.\n *\n * A report id is an identifier, not a secret. The `Math.random` fallback only\n * affects collision odds — negligible at our volume, and the backend dedupes\n * on the `reports` primary key regardless — so we never throw just because a\n * runtime lacks a CSPRNG.\n */\nexport function newUuid(): string {\n const c = typeof crypto !== 'undefined' ? crypto : undefined;\n if (c?.randomUUID) {\n return c.randomUUID();\n }\n\n const bytes = new Uint8Array(16);\n if (c?.getRandomValues) {\n c.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n // Pin version (4) and variant (10xx) bits per RFC 4122 §4.4.\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\n}\n","/**\n * §3c — stable device fingerprint hash.\n *\n * Hashes a deliberately small set of long-lived device characteristics so\n * the same browser keeps the same hash across sessions, but moving to a\n * new browser/device produces a different one. This lets the server\n * detect cross-account abuse (same hash → many reporter accounts) without\n * needing fingerprint.js or any other entropy-heavy library.\n *\n * Privacy notes:\n * - We never send the raw inputs, only the SHA-256 hex digest.\n * - The set is intentionally low-entropy on purpose; this is \"is this the\n * same device\" not \"who is this user\". For high-stakes anti-fraud you\n * should still combine with server-side IP/geo signals.\n * - Cached in localStorage so subsequent calls are zero-cost.\n */\n\nconst CACHE_KEY = 'mushi_fingerprint_hash';\n\ninterface FingerprintInputs {\n userAgent: string;\n platform: string;\n language: string;\n timezone: string;\n screenWidth: number;\n screenHeight: number;\n pixelRatio: number;\n deviceMemory: number | undefined;\n hardwareConcurrency: number | undefined;\n}\n\nfunction collectInputs(): FingerprintInputs {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined;\n const scr = typeof screen !== 'undefined' ? screen : undefined;\n const win = typeof window !== 'undefined' ? window : undefined;\n return {\n userAgent: nav?.userAgent ?? 'unknown',\n platform: nav?.platform ?? 'unknown',\n language: nav?.language ?? 'en',\n timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? 'UTC',\n screenWidth: scr?.width ?? 0,\n screenHeight: scr?.height ?? 0,\n pixelRatio: win?.devicePixelRatio ?? 1,\n deviceMemory: (nav as NavigatorWithDeviceMemory | undefined)?.deviceMemory,\n hardwareConcurrency: nav?.hardwareConcurrency,\n };\n}\n\ninterface NavigatorWithDeviceMemory extends Navigator {\n deviceMemory?: number;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const buf = new TextEncoder().encode(input);\n const digest = await crypto.subtle.digest('SHA-256', buf);\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n // Fallback (Node 18+ test envs, very old browsers): non-cryptographic but\n // good enough for the \"are these two requests from the same device\" use\n // case the server makes of this value.\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (hash << 5) - hash + input.charCodeAt(i);\n hash |= 0;\n }\n return `fbk_${(hash >>> 0).toString(16).padStart(8, '0')}`;\n}\n\n/**\n * Returns a stable per-device hash. Cached in localStorage; first call is\n * one SHA-256, subsequent calls are a localStorage read.\n *\n * Returns `null` outside browser-like environments (SSR, web workers\n * without crypto.subtle) so callers can omit the field gracefully.\n */\nexport async function getDeviceFingerprintHash(): Promise<string | null> {\n if (typeof localStorage !== 'undefined') {\n const cached = localStorage.getItem(CACHE_KEY);\n if (cached) return cached;\n }\n\n const inputs = collectInputs();\n const serialised = JSON.stringify(inputs);\n const hash = await sha256Hex(serialised);\n\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(CACHE_KEY, hash);\n } catch {\n // localStorage quota / private mode — caller still gets the hash.\n }\n }\n return hash;\n}\n\n/** Test/diagnostic helper — never include in shipped reports. */\nexport function _resetFingerprintCacheForTests(): void {\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.removeItem(CACHE_KEY);\n } catch {\n // ignore\n }\n }\n}\n","const SESSION_KEY = 'mushi_session_id';\n\nlet cachedSessionId: string | null = null;\n\nexport function getSessionId(): string {\n if (cachedSessionId) return cachedSessionId;\n\n if (typeof sessionStorage !== 'undefined') {\n const existing = sessionStorage.getItem(SESSION_KEY);\n if (existing) {\n cachedSessionId = existing;\n return existing;\n }\n }\n\n const id = generateSessionId();\n cachedSessionId = id;\n\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(SESSION_KEY, id);\n } catch {\n // sessionStorage unavailable\n }\n }\n\n return id;\n}\n\nfunction generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `ms_${timestamp}_${random}`;\n}\n","export interface RateLimiterConfig {\n maxBurst?: number;\n refillRate?: number;\n refillIntervalMs?: number;\n}\n\nexport interface RateLimiter {\n tryConsume(): boolean;\n reset(): void;\n availableTokens(): number;\n}\n\nconst DEFAULT_MAX_BURST = 10;\nconst DEFAULT_REFILL_RATE = 1;\nconst DEFAULT_REFILL_INTERVAL_MS = 5_000;\n\nexport function createRateLimiter(config: RateLimiterConfig = {}): RateLimiter {\n const {\n maxBurst = DEFAULT_MAX_BURST,\n refillRate = DEFAULT_REFILL_RATE,\n refillIntervalMs = DEFAULT_REFILL_INTERVAL_MS,\n } = config;\n\n let tokens = maxBurst;\n let lastRefill = Date.now();\n\n function refill() {\n const now = Date.now();\n const elapsed = now - lastRefill;\n const refills = Math.floor(elapsed / refillIntervalMs);\n if (refills > 0) {\n tokens = Math.min(maxBurst, tokens + refills * refillRate);\n lastRefill = now;\n }\n }\n\n function tryConsume(): boolean {\n refill();\n if (tokens > 0) {\n tokens--;\n return true;\n }\n return false;\n }\n\n function reset(): void {\n tokens = maxBurst;\n lastRefill = Date.now();\n }\n\n function availableTokens(): number {\n refill();\n return tokens;\n }\n\n return { tryConsume, reset, availableTokens };\n}\n","export interface PiiScrubberConfig {\n emails?: boolean;\n phones?: boolean;\n creditCards?: boolean;\n ssns?: boolean;\n ipAddresses?: boolean;\n /**\n * Scrub vendor-shaped secret tokens (AWS access keys, Stripe keys,\n * Slack/GitHub PATs, OpenAI/Anthropic/Google keys, JWTs).\n *\n * Wave S1 / D-15: SDK parity with the server-side scrubber. The server\n * scrubs these on every LLM invocation; the SDK now scrubs them at\n * capture so they never hit the wire in the first place — important for\n * users who `console.log(stripeKey)` during dev and later ship bug\n * reports with the error text attached.\n */\n secretTokens?: boolean;\n /** IPv6 addresses. Defaults off for the same reason IPv4 does. */\n ipv6?: boolean;\n}\n\ninterface PiiPattern {\n key: keyof PiiScrubberConfig;\n regex: RegExp;\n replacement: string;\n}\n\n// Order matters: SSN → CC → vendor secrets → email → phone → IP. Secret\n// tokens are matched *before* the generic email/phone regex because some JWT\n// payloads contain `.` that could be mis-parsed as `xyz.abc.com`.\nconst ORDERED_PATTERNS: PiiPattern[] = [\n { key: 'ssns', regex: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, replacement: '[REDACTED_SSN]' },\n { key: 'creditCards', regex: /\\b(?:\\d[ -]*){12,18}\\d\\b/g, replacement: '[REDACTED_CC]' },\n\n // Vendor secret tokens — mirrors packages/server/.../pii-scrubber.ts exactly.\n { key: 'secretTokens', regex: /\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, replacement: '[REDACTED_AWS_KEY]' },\n { key: 'secretTokens', regex: /(?:aws_secret_access_key|secret_access_key)[\"'\\s:=]+[A-Za-z0-9/+=]{40}\\b/gi, replacement: 'aws_secret_access_key=[REDACTED_AWS_SECRET]' },\n { key: 'secretTokens', regex: /\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\\b/g, replacement: '[REDACTED_STRIPE_KEY]' },\n { key: 'secretTokens', regex: /\\bpk_(?:live|test)_[A-Za-z0-9]{24,}\\b/g, replacement: '[REDACTED_STRIPE_PK]' },\n { key: 'secretTokens', regex: /\\bxox[abpor]-[A-Za-z0-9-]{10,}\\b/g, replacement: '[REDACTED_SLACK_TOKEN]' },\n { key: 'secretTokens', regex: /\\bghp_[A-Za-z0-9]{36}\\b/g, replacement: '[REDACTED_GITHUB_PAT]' },\n { key: 'secretTokens', regex: /\\bgithub_pat_[A-Za-z0-9_]{80,}\\b/g, replacement: '[REDACTED_GITHUB_PAT]' },\n { key: 'secretTokens', regex: /\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b/g, replacement: '[REDACTED_OPENAI_KEY]' },\n { key: 'secretTokens', regex: /\\bsk-ant-[A-Za-z0-9_-]{20,}\\b/g, replacement: '[REDACTED_ANTHROPIC_KEY]' },\n { key: 'secretTokens', regex: /\\bAIza[0-9A-Za-z_-]{35}\\b/g, replacement: '[REDACTED_GOOGLE_KEY]' },\n { key: 'secretTokens', regex: /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g, replacement: '[REDACTED_JWT]' },\n\n { key: 'emails', regex: /\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b/g, replacement: '[REDACTED_EMAIL]' },\n { key: 'phones', regex: /(?:\\+\\d{1,3}[\\s.-])?\\(?\\d{2,4}\\)?[\\s.-]\\d{3,4}[\\s.-]\\d{3,4}\\b/g, replacement: '[REDACTED_PHONE]' },\n { key: 'ipAddresses', regex: /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g, replacement: '[REDACTED_IP]' },\n { key: 'ipv6', regex: /\\b(?:[A-Fa-f0-9]{1,4}:){2,7}[A-Fa-f0-9]{0,4}\\b/g, replacement: '[REDACTED_IPV6]' },\n];\n\nconst DEFAULT_CONFIG: PiiScrubberConfig = {\n emails: true,\n phones: true,\n creditCards: true,\n ssns: true,\n ipAddresses: false,\n // Secret tokens default ON — if they leak into a bug report there's no\n // good reason to ship them to our servers. Cheaper to scrub client-side.\n secretTokens: true,\n ipv6: false,\n};\n\nexport function createPiiScrubber(config: PiiScrubberConfig = {}) {\n const merged = { ...DEFAULT_CONFIG, ...config };\n\n const activePatterns = ORDERED_PATTERNS.filter((p) => merged[p.key]);\n\n function scrub(text: string): string {\n if (!text) return text;\n let result = text;\n for (const { regex, replacement } of activePatterns) {\n result = result.replace(new RegExp(regex.source, regex.flags), replacement);\n }\n return result;\n }\n\n function scrubObject<T extends Record<string, unknown>>(obj: T, keys: string[]): T {\n const copy = { ...obj };\n for (const key of keys) {\n if (typeof copy[key] === 'string') {\n (copy as Record<string, unknown>)[key] = scrub(copy[key] as string);\n }\n }\n return copy;\n }\n\n return { scrub, scrubObject };\n}\n\nexport function scrubPii(text: string, config?: PiiScrubberConfig): string {\n return createPiiScrubber(config).scrub(text);\n}\n","import type { MushiBreadcrumb } from './types';\n\n/**\n * Ring-buffer breadcrumb store. Capped at `max` entries (default 50);\n * once full, every new add evicts the oldest. We deliberately don't\n * use a Map — order matters and is the only thing we ever read, so a\n * plain array we slice-copy on snapshot is the right shape.\n *\n * Design notes:\n * - `add()` is O(1) on the steady-state hot path (just `push`). When\n * we hit `max` we evict the oldest with `shift()` — that's O(n)\n * in the worst case, but with `max=50` the constant is tiny and\n * it only fires once per insert past the cap. We deliberately\n * append-then-shift (rather than head-insert) so `getAll()` can\n * return the underlying array in oldest-first order without an\n * extra reverse copy on every snapshot.\n * - `getAll()` returns a *copy* so callers can't mutate the buffer\n * after a report is composed. Reports send the snapshot, not the\n * live ring.\n * - Long messages are truncated at 500 chars *at insert time*\n * because a runaway log line shouldn't push useful breadcrumbs\n * out of the buffer just by virtue of taking the whole entry.\n * - PII concerns: this buffer is intentionally *not* scrubbed at\n * insert time — `getBreadcrumbs()` should return the host's own\n * values verbatim so they're useful for in-app debugging. The\n * scrubbing pass runs at *report-snapshot time* in\n * `packages/web/src/mushi.ts`, applying the same `createPiiScrubber()`\n * used on `description` to every breadcrumb message + every string\n * field in `data`. That way emails / Stripe keys / JWTs in a\n * breadcrumb never leave the SDK process.\n */\nexport interface BreadcrumbBuffer {\n /** Append a single breadcrumb; auto-fills `timestamp` when omitted. */\n add(crumb: Omit<MushiBreadcrumb, 'timestamp'> & { timestamp?: number }): void;\n /** Return a copy of every retained breadcrumb, oldest first. */\n getAll(): MushiBreadcrumb[];\n /** Drop every entry. Useful for tests and `Mushi.destroy()`. */\n clear(): void;\n /** Number of entries currently held. */\n size(): number;\n}\n\nexport interface BreadcrumbBufferOptions {\n /** Hard cap on retained entries. Default 50. */\n max?: number;\n /** Hard cap on `message` length, in chars. Default 500. */\n maxMessageLength?: number;\n}\n\nconst DEFAULT_MAX = 50;\nconst DEFAULT_MAX_MESSAGE = 500;\n\nexport function createBreadcrumbBuffer(options: BreadcrumbBufferOptions = {}): BreadcrumbBuffer {\n const max = Math.max(1, options.max ?? DEFAULT_MAX);\n const maxMsg = Math.max(50, options.maxMessageLength ?? DEFAULT_MAX_MESSAGE);\n let entries: MushiBreadcrumb[] = [];\n\n return {\n add(input) {\n const ts = typeof input.timestamp === 'number' ? input.timestamp : Date.now();\n const message =\n typeof input.message === 'string' && input.message.length > maxMsg\n ? `${input.message.slice(0, maxMsg)}…`\n : input.message;\n const crumb: MushiBreadcrumb = {\n timestamp: ts,\n category: input.category,\n level: input.level ?? 'info',\n message: message ?? '',\n ...(input.data ? { data: input.data } : {}),\n };\n entries.push(crumb);\n // Evict the oldest entries when we're over the cap. Done in a\n // loop instead of `entries = entries.slice(-max)` so we don't\n // allocate a fresh array on every add when the buffer is at the\n // steady-state cap (the common case in long-lived sessions).\n while (entries.length > max) entries.shift();\n },\n\n getAll() {\n return entries.slice();\n },\n\n clear() {\n entries = [];\n },\n\n size() {\n return entries.length;\n },\n };\n}\n","/**\n * Normalise *anything* a host might throw — `Error`, string, plain\n * object, `null`, frozen DOMException — into the shape Mushi reports\n * use. Mirrors Sentry's own internal normaliser; lets `captureException`\n * be a thin sugar layer over `captureEvent`.\n *\n * Truncates the stack at 8 KB so a runaway long stack (recursive React\n * render error during a hot reload, for example) doesn't blow the\n * description budget when callers fall back to the stack as the body.\n */\nexport interface NormalisedException {\n name: string;\n message: string;\n stack?: string;\n cause?: unknown;\n}\n\nconst STACK_LIMIT = 8 * 1024;\nconst FALLBACK_JSON_LIMIT = 1000;\n\nexport function normaliseThrown(thrown: unknown): NormalisedException {\n if (thrown instanceof Error) {\n const name = thrown.name || 'Error';\n const message = thrown.message || String(thrown);\n const stack =\n typeof thrown.stack === 'string' && thrown.stack.length > 0\n ? thrown.stack.slice(0, STACK_LIMIT)\n : undefined;\n const cause = (thrown as { cause?: unknown }).cause;\n return {\n name,\n message,\n ...(stack ? { stack } : {}),\n ...(cause !== undefined\n ? { cause: cause instanceof Error ? cause.message : cause }\n : {}),\n };\n }\n if (typeof thrown === 'string') {\n return { name: 'Error', message: thrown };\n }\n if (thrown && typeof thrown === 'object') {\n const obj = thrown as Record<string, unknown>;\n const name = typeof obj.name === 'string' ? obj.name : 'Error';\n const message =\n typeof obj.message === 'string'\n ? obj.message\n : (() => {\n try {\n return JSON.stringify(obj).slice(0, FALLBACK_JSON_LIMIT);\n } catch {\n return String(obj);\n }\n })();\n const stack = typeof obj.stack === 'string' ? obj.stack.slice(0, STACK_LIMIT) : undefined;\n return { name, message, ...(stack ? { stack } : {}) };\n }\n // `String(null)` → `\"null\"`, `String(undefined)` → `\"undefined\"`.\n // We special-case `undefined` to read as \"unknown\" because that's\n // how it shows up in the most common case (a `throw` without an\n // argument, or `Promise.reject()`).\n if (thrown === undefined) return { name: 'Error', message: 'unknown' };\n return { name: 'Error', message: String(thrown) };\n}\n","/**\n * FILE: packages/core/src/design-tokens.ts\n * PURPOSE: The single cross-platform source of truth for Mushi widget design.\n *\n * Every platform SDK (web Shadow-DOM CSS, React Native components, Capacitor\n * native sheet) reads its colours, spacing, radii, typography, z-index scale,\n * motion, launcher geometry, and default copy from this module so the widget\n * renders coherently everywhere. `@mushi-mushi/core` is already a dependency\n * of every platform package, which is why the tokens live here rather than in\n * a separate published package — one import path, no extra build wiring.\n *\n * Colour values mirror the historical washi/vermillion palette previously\n * inlined in `@mushi-mushi/web`'s styles.ts so the visual identity is\n * unchanged; the difference is that RN and Capacitor now share the exact\n * same constants instead of re-deriving their own.\n */\n\nexport type MushiThemeMode = 'light' | 'dark';\n\nexport interface MushiColorPalette {\n /** washi cream / dark wash — primary surface */\n paper: string;\n /** elevated surface (panels, sheets) */\n paperRaised: string;\n /** sumi black / cream type — primary text */\n ink: string;\n /** captions, descriptions */\n inkMuted: string;\n /** disabled, separators */\n inkFaint: string;\n /** dim text */\n inkDim: string;\n /** hairline rules */\n rule: string;\n /** stronger rules / borders */\n ruleStrong: string;\n /** 朱 hanko red — signature accent */\n accent: string;\n /** ~8–12% accent wash */\n accentWash: string;\n /** accessible text on the accent wash */\n accentInk: string;\n /** success */\n ok: string;\n /** danger / destructive */\n danger: string;\n}\n\n/** Light-mode palette. */\nexport const MUSHI_COLORS_LIGHT: MushiColorPalette = {\n paper: '#F8F4ED',\n paperRaised: '#FFFFFF',\n ink: '#0E0D0B',\n inkMuted: '#5C5852',\n inkFaint: '#9A9489',\n inkDim: '#6E6760',\n rule: 'rgba(14,13,11,0.10)',\n ruleStrong: 'rgba(14,13,11,0.16)',\n accent: '#E03C2C',\n accentWash: 'rgba(224,60,44,0.08)',\n accentInk: '#7A1F15',\n ok: '#16A34A',\n danger: '#DC2626',\n};\n\n/** Dark-mode palette. */\nexport const MUSHI_COLORS_DARK: MushiColorPalette = {\n paper: '#0F0E0C',\n paperRaised: '#1A1815',\n ink: '#F2EBDD',\n inkMuted: '#928B7E',\n inkFaint: '#5A5650',\n inkDim: '#7A7268',\n rule: 'rgba(242,235,221,0.10)',\n ruleStrong: 'rgba(242,235,221,0.18)',\n accent: '#FF5A47',\n accentWash: 'rgba(255,90,71,0.12)',\n accentInk: '#FFE5E0',\n ok: '#4ADE80',\n danger: '#F87171',\n};\n\n/** Resolve the palette for a theme mode. */\nexport function mushiPalette(mode: MushiThemeMode): MushiColorPalette {\n return mode === 'dark' ? MUSHI_COLORS_DARK : MUSHI_COLORS_LIGHT;\n}\n\n/**\n * Spacing scale (px). Named by feel, matching the editorial design system so\n * the same rhythm reads across web and native.\n */\nexport const MUSHI_SPACING = {\n hairline: 2,\n tight: 4,\n snug: 8,\n comfy: 12,\n roomy: 16,\n lounge: 20,\n open: 24,\n wide: 32,\n} as const;\n\n/** Corner radii (px). Tables/strips stay sharp; controls get soft corners. */\nexport const MUSHI_RADIUS = {\n none: 0,\n control: 4,\n card: 10,\n sheet: 16,\n pill: 999,\n} as const;\n\n/** Typography stacks shared by every platform (system-first, no web-font fetch). */\nexport const MUSHI_TYPE = {\n fontDisplay: `'Iowan Old Style', 'Palatino Linotype', 'Palatino', 'Book Antiqua', 'Cambria', Georgia, 'Times New Roman', serif`,\n fontBody: `system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Display', 'Segoe UI', sans-serif`,\n fontMono: `ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, 'Liberation Mono', monospace`,\n sizeBody: 14,\n sizeLabel: 12,\n sizeTitle: 16,\n lineBody: 1.55,\n} as const;\n\n/**\n * z-index scale. The host element is pass-through; only interactive surfaces\n * opt back into pointer events. Banner sits just under the FAB; panel above.\n */\nexport const MUSHI_Z = {\n base: 99999,\n /** banner sits one below the trigger so an open FAB overlaps it */\n banner: 99998,\n /** report/assistant panel sits one above the trigger */\n panel: 100000,\n /** element-selector overlay — always on top */\n overlay: 2147483647,\n} as const;\n\n/** Motion signature — a soft back-out \"stamp press\". */\nexport const MUSHI_MOTION = {\n easeStamp: 'cubic-bezier(0.22, 1, 0.36, 1)',\n durationFast: 200,\n durationPanel: 300,\n} as const;\n\n/**\n * Launcher geometry — the numbers that previously diverged between platforms\n * (banner height, FAB size, default gutter, panel width). Centralising them\n * is what fixes the \"different on every app\" + safe-area bleed problems.\n */\nexport const MUSHI_GEOMETRY = {\n bannerHeight: 36,\n fabSize: 52,\n edgeTabWidth: 28,\n /** default gutter from the screen edge (added on top of safe-area insets) */\n gutter: 24,\n panelWidth: 384,\n /** below this viewport width the panel becomes a full-width bottom sheet */\n panelSheetBreakpoint: 480,\n} as const;\n\n/**\n * Default user-facing copy. Centralised so apps stop drifting on the banner\n * label / CTA wording (seen as inconsistent across the four host apps).\n */\nexport const MUSHI_COPY = {\n bannerLabel: 'Beta',\n bannerMessage: 'Help us improve — your feedback shapes what we ship.',\n bugCta: 'Report a bug',\n featureCta: 'Feature request',\n triggerText: '🐛',\n panelTitle: 'Send feedback',\n myReportsTab: 'My reports',\n assistantTab: 'Ask',\n} as const;\n\n/** A flat, serialisable snapshot of every token for a given theme mode. */\nexport interface MushiTokenSnapshot {\n mode: MushiThemeMode;\n colors: MushiColorPalette;\n spacing: typeof MUSHI_SPACING;\n radius: typeof MUSHI_RADIUS;\n type: typeof MUSHI_TYPE;\n z: typeof MUSHI_Z;\n motion: typeof MUSHI_MOTION;\n geometry: typeof MUSHI_GEOMETRY;\n copy: typeof MUSHI_COPY;\n}\n\n/** Build a full token snapshot for a theme mode (used by RN/Capacitor). */\nexport function mushiTokens(mode: MushiThemeMode): MushiTokenSnapshot {\n return {\n mode,\n colors: mushiPalette(mode),\n spacing: MUSHI_SPACING,\n radius: MUSHI_RADIUS,\n type: MUSHI_TYPE,\n z: MUSHI_Z,\n motion: MUSHI_MOTION,\n geometry: MUSHI_GEOMETRY,\n copy: MUSHI_COPY,\n };\n}\n","/**\n * FILE: packages/core/src/identity.ts\n * PURPOSE: The signed-JWT end-user identity contract shared between the SDK\n * and the Mushi backend.\n *\n * The host app's server mints a short-lived JWT (HS256, signed with the\n * project's identity secret obtained from the console) describing the\n * currently-logged-in end user, and hands it to the SDK via\n * `Mushi.identifyWithToken(jwt)`. The SDK never verifies the signature — it\n * only base64url-decodes the payload to show the user's name locally and\n * forwards the raw token to the backend, which verifies it against the\n * per-project secret before trusting any claim. This mirrors the Featurebase\n * `featurebaseJwt` model and is the trust anchor for \"My Reports\", rewards,\n * and the per-user assistant data index.\n *\n * Anonymous reporters (logged-out) keep using the random reporter token; the\n * signed JWT is purely additive.\n */\n\n/** Claims carried by a Mushi end-user identity token. */\nexport interface MushiIdentityClaims {\n /** Mushi external project id this token is scoped to. */\n projectId: string;\n /** The host app's stable id for this end user (becomes `external_user_id`). */\n sub: string;\n /** Optional display email (never stored raw server-side — hashed). */\n email?: string;\n /** Optional display name. */\n name?: string;\n /** Issued-at (seconds since epoch). */\n iat?: number;\n /** Expiry (seconds since epoch). Tokens should be short-lived (<= 1h). */\n exp?: number;\n}\n\n/**\n * Sentinel so callers can distinguish a Mushi identity token from the random\n * anonymous reporter token (`mushi_<uuid>`). Identity tokens are standard JWTs\n * (three dot-separated base64url segments), so this prefix is informational\n * only and not embedded in the wire format.\n */\nexport const MUSHI_IDENTITY_TOKEN_PREFIX = 'mushi.identity';\n\n/**\n * Build the canonical claims object a host server should sign. Exposed so the\n * `@mushi-mushi/node` SDK and docs share one definition of the payload shape.\n */\nexport function buildIdentityClaims(input: {\n projectId: string;\n userId: string;\n email?: string;\n name?: string;\n ttlSeconds?: number;\n}): Required<Pick<MushiIdentityClaims, 'projectId' | 'sub' | 'iat' | 'exp'>> &\n Pick<MushiIdentityClaims, 'email' | 'name'> {\n const now = Math.floor(Date.now() / 1000);\n const ttl = input.ttlSeconds && input.ttlSeconds > 0 ? Math.min(input.ttlSeconds, 3600) : 600;\n return {\n projectId: input.projectId,\n sub: input.userId,\n ...(input.email ? { email: input.email } : {}),\n ...(input.name ? { name: input.name } : {}),\n iat: now,\n exp: now + ttl,\n };\n}\n\nfunction base64UrlDecode(segment: string): string {\n const pad = segment.length % 4 === 0 ? '' : '='.repeat(4 - (segment.length % 4));\n const base64 = segment.replace(/-/g, '+').replace(/_/g, '/') + pad;\n if (typeof atob === 'function') return atob(base64);\n // Node / RN without atob\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const B = (globalThis as any).Buffer;\n if (B) return B.from(base64, 'base64').toString('binary');\n return '';\n}\n\n/**\n * Decode (WITHOUT verifying) the claims of an identity JWT. Returns null if the\n * token is malformed. CLIENT-SIDE DISPLAY ONLY — never trust these claims for\n * authorisation; the server re-verifies the signature.\n */\nexport function parseIdentityToken(token: string): MushiIdentityClaims | null {\n if (typeof token !== 'string') return null;\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n try {\n const json = base64UrlDecode(parts[1]);\n const payload = JSON.parse(json) as Record<string, unknown>;\n const projectId = typeof payload.projectId === 'string' ? payload.projectId : undefined;\n const sub = typeof payload.sub === 'string' ? payload.sub : undefined;\n if (!projectId || !sub) return null;\n return {\n projectId,\n sub,\n ...(typeof payload.email === 'string' ? { email: payload.email } : {}),\n ...(typeof payload.name === 'string' ? { name: payload.name } : {}),\n ...(typeof payload.iat === 'number' ? { iat: payload.iat } : {}),\n ...(typeof payload.exp === 'number' ? { exp: payload.exp } : {}),\n };\n } catch {\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/payload-guard.ts","../src/api-client.ts","../src/region.ts","../src/env-config.ts","../src/pre-filter.ts","../src/logger.ts","../src/queue-crypto.ts","../src/queue.ts","../src/environment.ts","../src/reporter-token.ts","../src/uuid.ts","../src/fingerprint.ts","../src/session.ts","../src/rate-limiter.ts","../src/pii-scrubber.ts","../src/breadcrumbs.ts","../src/exception-normaliser.ts","../src/design-tokens.ts","../src/identity.ts","../src/favicon.ts"],"names":["getBackoffDelay","sleep","sha256Hex"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Client-side payload size guards — prevents silent edge-function failures\n * when screenshots or log buffers inflate the report body past gateway limits.\n */\n\n/** Supabase edge functions tolerate ~6 MB; stay under 4 MB for headroom. */\nexport const MAX_REPORT_PAYLOAD_BYTES = 4 * 1024 * 1024\n\n/** Screenshot data URLs above this are downscaled or dropped before POST. */\nexport const MAX_SCREENSHOT_DATA_URL_BYTES = 1.5 * 1024 * 1024\n\nexport interface PayloadGuardResult {\n ok: boolean\n bytes: number\n maxBytes: number\n reason?: string\n /**\n * True when the payload could not be serialized at all (e.g. a circular\n * reference in `metadata`). This is a distinct failure from \"too large\" —\n * the caller should surface a `SERIALIZE_FAILED` rather than a misleading\n * \"payload too large\" message.\n */\n serializeFailed?: boolean\n}\n\nfunction safeStringify(value: unknown): string | null {\n try {\n return JSON.stringify(value)\n } catch {\n return null\n }\n}\n\nexport function estimateJsonBytes(value: unknown): number {\n const json = safeStringify(value)\n return json === null\n ? Number.MAX_SAFE_INTEGER\n : new TextEncoder().encode(json).length\n}\n\nexport function checkReportPayloadSize(\n payload: unknown,\n maxBytes = MAX_REPORT_PAYLOAD_BYTES,\n): PayloadGuardResult {\n const json = safeStringify(payload)\n if (json === null) {\n return {\n ok: false,\n bytes: 0,\n maxBytes,\n serializeFailed: true,\n reason: 'Report could not be serialized (circular reference in metadata?)',\n }\n }\n const bytes = new TextEncoder().encode(json).length\n if (bytes <= maxBytes) {\n return { ok: true, bytes, maxBytes }\n }\n return {\n ok: false,\n bytes,\n maxBytes,\n reason: `Report payload ${formatBytes(bytes)} exceeds limit ${formatBytes(maxBytes)}`,\n }\n}\n\nexport function formatBytes(n: number): string {\n if (n < 1024) return `${n} B`\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`\n return `${(n / (1024 * 1024)).toFixed(2)} MB`\n}\n","import type {\n MushiApiClient,\n MushiApiResponse,\n MushiAssistantReply,\n MushiCrossAppReport,\n MushiLeaderboardEntry,\n MushiPageContext,\n MushiReport,\n MushiReportStatus,\n MushiReporterComment,\n MushiReporterReport,\n MushiRuntimeSdkConfig,\n MushiSdkVersionInfo,\n MushiTesterReputation,\n MushiTierResult,\n} from './types';\nimport { checkReportPayloadSize } from './payload-guard';\n\n// One-time credential-failure warning gate — emitted at most once per JS\n// process so it's visible without flooding the console on every queued retry.\nlet _credWarningEmitted = false;\n\n/** Header carrying the signed end-user identity token (verified server-side). */\nexport const MUSHI_USER_TOKEN_HEADER = 'X-Mushi-User-Token';\n/** Project scope header — paired with the API key on every SDK request. */\nexport const MUSHI_PROJECT_HEADER = 'X-Mushi-Project';\n/** Build-time SDK package identity — recorded on every authenticated heartbeat. */\nexport const MUSHI_SDK_PACKAGE_HEADER = 'X-Mushi-SDK-Package';\nexport const MUSHI_SDK_VERSION_HEADER = 'X-Mushi-SDK-Version';\n\n/** Build the standard authenticated SDK ingest headers (shared by api-client + offline flush). */\nexport function buildSdkIngestHeaders(opts: {\n apiKey: string;\n projectId: string;\n sdkPackage?: string;\n sdkVersion?: string;\n userToken?: string | null;\n internalKind?: MushiInternalRequestKind;\n}): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Mushi-Api-Key': opts.apiKey,\n [MUSHI_PROJECT_HEADER]: opts.projectId,\n };\n if (opts.sdkPackage) headers[MUSHI_SDK_PACKAGE_HEADER] = opts.sdkPackage;\n if (opts.sdkVersion) headers[MUSHI_SDK_VERSION_HEADER] = opts.sdkVersion;\n if (opts.userToken) headers[MUSHI_USER_TOKEN_HEADER] = opts.userToken;\n if (opts.internalKind) headers[MUSHI_INTERNAL_HEADER] = opts.internalKind;\n return headers;\n}\n\nexport interface ApiClientOptions {\n projectId: string;\n apiKey: string;\n /**\n * Override the API endpoint. Defaults to the canonical Cloud URL\n * (DEFAULT_API_ENDPOINT). Self-hosted users MUST set this.\n */\n apiEndpoint?: string;\n timeout?: number;\n maxRetries?: number;\n /** When set, sent on every request so heartbeats record the running SDK version. */\n sdkPackage?: string;\n sdkVersion?: string;\n /**\n * Returns the current signed end-user identity JWT, or null when the user is\n * anonymous. When present it is sent on the X-Mushi-User-Token header so the\n * backend can verify it and scope identity-bound features to that user.\n */\n getUserToken?: () => string | null | undefined;\n}\n\n// V5.3 (M-cross-cutting): canonical Cloud URL — the older `api.mushimushi.dev`\n// hostname was never wired up. Self-hosted users MUST override `apiEndpoint`.\nexport const DEFAULT_API_ENDPOINT = 'https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api';\nexport const MUSHI_INTERNAL_HEADER = 'X-Mushi-Internal';\nexport const MUSHI_INTERNAL_INIT_MARKER = '__mushiInternal';\n\nexport type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\nexport function createApiClient(options: ApiClientOptions): MushiApiClient {\n const {\n projectId,\n apiKey,\n apiEndpoint = DEFAULT_API_ENDPOINT,\n timeout = DEFAULT_TIMEOUT,\n maxRetries = DEFAULT_MAX_RETRIES,\n getUserToken,\n sdkPackage,\n sdkVersion,\n } = options;\n\n let baseUrl = apiEndpoint.replace(/\\/$/, '');\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n retries = maxRetries,\n internalKind?: MushiInternalRequestKind,\n extraHeaders?: Record<string, string>,\n ): Promise<MushiApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n const userToken = getUserToken?.() ?? null;\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n ...buildSdkIngestHeaders({\n apiKey,\n projectId,\n sdkPackage,\n sdkVersion,\n userToken,\n internalKind,\n }),\n ...extraHeaders,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n ...(internalKind ? { [MUSHI_INTERNAL_INIT_MARKER]: internalKind } : {}),\n } as RequestInit & { [MUSHI_INTERNAL_INIT_MARKER]?: MushiInternalRequestKind });\n\n clearTimeout(timer);\n\n // C7: data residency — follow a one-shot redirect when the\n // gateway tells us the project lives in a different region. Cache the\n // new base URL so subsequent calls go straight to the right cluster.\n if (response.status === 307 || response.status === 308) {\n const target = response.headers.get('Location');\n if (target && retries > 0) {\n const targetBase = target.replace(/\\/v1\\/.*$/, '').replace(/\\/$/, '');\n if (targetBase !== baseUrl) {\n baseUrl = targetBase;\n return request<T>(method, path, body, retries - 1, internalKind, extraHeaders);\n }\n }\n }\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n\n // Surface credential failures immediately — they'll never succeed on\n // retry and silently queuing them offline misleads the developer.\n if ((response.status === 401 || response.status === 403) && !_credWarningEmitted) {\n _credWarningEmitted = true;\n // Only point to the hosted console when this client is actually using\n // the hosted Cloud endpoint — self-hosted deployments (custom\n // apiEndpoint) have their own console at an address we don't know.\n // Compare the slash-normalized `baseUrl`, not the raw `apiEndpoint`, so\n // a copy-pasted Cloud URL with a trailing slash still counts as Cloud.\n const where =\n baseUrl === DEFAULT_API_ENDPOINT\n ? 'Get the correct values at: https://kensaur.us/mushi-mushi/admin/projects'\n : \"Get the correct values from your Mushi console's Projects page.\";\n // eslint-disable-next-line no-console\n console.error(\n `[Mushi] Credentials rejected (HTTP ${response.status}). ` +\n `Check your Project ID and API key scope (must be \"report:write\"). ` +\n where,\n );\n }\n\n if (response.status >= 500 && retries > 0) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1, internalKind, extraHeaders);\n }\n return {\n ok: false,\n error: {\n code:\n (errorBody as { error?: { code?: string } }).error?.code ||\n `HTTP_${response.status}`,\n message:\n (errorBody as { message?: string; error?: { message?: string } }).error?.message ||\n (errorBody as { message?: string }).message ||\n `HTTP ${response.status} error`,\n },\n };\n }\n\n const payload = await response.json();\n const data = payload && typeof payload === 'object' && 'ok' in payload && 'data' in payload\n ? (payload as { data: T }).data\n : payload as T;\n return { ok: true, data };\n } catch (error) {\n clearTimeout(timer);\n\n if (retries > 0 && isRetryable(error)) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1, internalKind);\n }\n\n return {\n ok: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Unknown network error',\n },\n };\n }\n }\n\n async function requestForReporter<T>(\n method: string,\n path: string,\n reporterToken: string,\n body?: unknown,\n ): Promise<MushiApiResponse<T>> {\n const tokenHash = await sha256Hex(reporterToken);\n const ts = String(Date.now());\n const hmac = await hmacSha256Hex(apiKey, `${projectId}.${ts}.${tokenHash}`);\n const url = `${baseUrl}${path}`;\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'X-Mushi-Api-Key': apiKey,\n 'X-Mushi-Project': projectId,\n ...(sdkPackage ? { [MUSHI_SDK_PACKAGE_HEADER]: sdkPackage } : {}),\n ...(sdkVersion ? { [MUSHI_SDK_VERSION_HEADER]: sdkVersion } : {}),\n [MUSHI_INTERNAL_HEADER]: 'reporter-poll',\n 'X-Reporter-Token-Hash': tokenHash,\n 'X-Reporter-Ts': ts,\n 'X-Reporter-Hmac': hmac,\n },\n body: body ? JSON.stringify(body) : undefined,\n [MUSHI_INTERNAL_INIT_MARKER]: 'reporter-poll',\n } as RequestInit & { [MUSHI_INTERNAL_INIT_MARKER]?: MushiInternalRequestKind });\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n return {\n ok: false,\n error: {\n code: `HTTP_${response.status}`,\n message: (errorBody as { error?: { message?: string }; message?: string }).error?.message\n ?? (errorBody as { message?: string }).message\n ?? `HTTP ${response.status} error`,\n },\n };\n }\n const payload = await response.json();\n return { ok: true, data: (payload as { data: T }).data ?? (payload as T) };\n }\n\n return {\n async submitReport(report: MushiReport) {\n const guard = checkReportPayloadSize(report);\n if (!guard.ok) {\n return {\n ok: false,\n error: {\n code: guard.serializeFailed ? 'SERIALIZE_FAILED' : 'PAYLOAD_TOO_LARGE',\n message: guard.reason ?? 'Report payload exceeds size limit',\n },\n };\n }\n return request<{ reportId: string }>('POST', '/v1/reports', report, maxRetries, 'report-submit');\n },\n\n async getReportStatus(reportId: string) {\n return request<{ status: MushiReportStatus }>('GET', `/v1/reports/${reportId}/status`, undefined, maxRetries, 'report-status');\n },\n\n async getSdkConfig() {\n return request<MushiRuntimeSdkConfig>('GET', '/v1/sdk/config', undefined, maxRetries, 'sdk-config');\n },\n\n async askAssistant(input: { message: string; threadId?: string | null; context?: MushiPageContext | null }) {\n return request<MushiAssistantReply>(\n 'POST',\n '/v1/sdk/assistant',\n {\n message: input.message,\n threadId: input.threadId ?? null,\n context: input.context ?? null,\n },\n 1,\n 'community',\n );\n },\n\n async getLatestSdkVersion(packageName: string) {\n const query = new URLSearchParams({ package: packageName }).toString();\n return request<MushiSdkVersionInfo>('GET', `/v1/sdk/latest-version?${query}`, undefined, maxRetries, 'sdk-config');\n },\n\n async postDiscoveryEvent(event) {\n // Discovery is best-effort — only one retry on transient failure\n // and a tighter timeout than report submission. We don't queue\n // these offline because a stale observation is more likely to\n // misinform the proposer than it is to be useful.\n return request<{ accepted: boolean }>(\n 'POST',\n '/v1/sdk/discovery',\n event,\n 1,\n 'discovery',\n );\n },\n\n async listReporterReports(reporterToken: string) {\n return requestForReporter<{ reports: MushiReporterReport[] }>('GET', '/v1/reporter/reports', reporterToken);\n },\n\n async listReporterComments(reportId: string, reporterToken: string) {\n return requestForReporter<{ comments: MushiReporterComment[] }>(\n 'GET',\n `/v1/reporter/reports/${reportId}/comments`,\n reporterToken,\n );\n },\n\n async replyToReporterReport(\n reportId: string,\n reporterToken: string,\n body: string,\n feedbackSignal?: string,\n ) {\n return requestForReporter<{ comment: MushiReporterComment; feedback?: Record<string, unknown> }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reply`,\n reporterToken,\n { body, ...(feedbackSignal ? { feedback_signal: feedbackSignal } : {}) },\n );\n },\n\n async reopenReporterReport(reportId: string, reporterToken: string, note?: string) {\n return requestForReporter<{ outcome: Record<string, unknown> }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reopen`,\n reporterToken,\n { note: note ?? '' },\n );\n },\n\n async listNotifications(reporterToken: string, opts?: { since?: string; limit?: number }) {\n const qs = new URLSearchParams();\n if (opts?.since) qs.set('since', opts.since);\n if (opts?.limit) qs.set('limit', String(opts.limit));\n const suffix = qs.size ? `?${qs.toString()}` : '';\n return requestForReporter<{ notifications: Array<Record<string, unknown>> }>(\n 'GET',\n `/v1/notifications${suffix}`,\n reporterToken,\n );\n },\n\n async markNotificationRead(notificationId: string, reporterToken: string) {\n return requestForReporter<{ ok: boolean }>(\n 'POST',\n `/v1/notifications/${notificationId}/read`,\n reporterToken,\n {},\n );\n },\n\n async listReporterFeatureBoard(reporterToken: string) {\n return requestForReporter<{ tickets: Array<Record<string, unknown>> }>(\n 'GET',\n '/v1/reporter/feature-board',\n reporterToken,\n );\n },\n\n async voteReporterFeatureBoard(requestId: string, reporterToken: string) {\n return requestForReporter<{ voted: boolean; action: string }>(\n 'POST',\n `/v1/reporter/feature-board/${requestId}/vote`,\n reporterToken,\n {},\n );\n },\n\n // ─── Rewards program (P1) ──────────────────────────────────\n\n async submitActivity(userId, events, opts?: { userTraits?: { email?: string; name?: string; provider?: string }; reporterTokenHash?: string; optedIn?: boolean; hostJwt?: string }) {\n return request<{ accepted: number; total: number }>(\n 'POST',\n '/v1/sdk/activity',\n {\n user_id: userId,\n user_traits: opts?.userTraits,\n opted_in: opts?.optedIn,\n reporter_token_hash: opts?.reporterTokenHash,\n // P2: JWT for monetary verification; omitted when null\n ...(opts?.hostJwt ? { host_jwt: opts.hostJwt } : {}),\n events,\n },\n 1, // best-effort, 1 retry\n 'discovery',\n );\n },\n\n async getMyPoints(userId) {\n return request<{ total_points: number; points_30d: number; points_lifetime: number; tier: MushiTierResult | null }>(\n 'GET',\n `/v1/sdk/me/points?userId=${encodeURIComponent(userId)}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getMyTier(userId) {\n return request<MushiTierResult | null>(\n 'GET',\n `/v1/sdk/me/tier?userId=${encodeURIComponent(userId)}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getMyHistory(userId, opts) {\n const qs = new URLSearchParams({ userId, ...(opts?.limit ? { limit: String(opts.limit) } : {}) });\n return request<{ items: unknown[]; total: number }>(\n 'GET',\n `/v1/sdk/me/history?${qs}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getHallOfFame(limit = 10) {\n return request<{\n data: Array<{\n display_name: string;\n email_hash: string | null;\n tier_slug: string | null;\n tier_name: string | null;\n points_30d: number;\n total_points: number;\n }>;\n meta: { project_name: string };\n }>(\n 'GET',\n `/v1/sdk/hall-of-fame?limit=${limit}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n // ─── Cross-app community (in-widget tester identity) ──────────\n\n async sendMagicLink(email: string) {\n return request<{ ok: boolean }>(\n 'POST',\n '/v1/tester/magic-link',\n { email },\n 1,\n 'community',\n );\n },\n\n async linkReporterToken(reporterTokenHash: string, jwt: string) {\n return request<{ ok: boolean; linked: number }>(\n 'POST',\n '/v1/tester/link-reporter',\n { reporter_token_hash: reporterTokenHash },\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getCrossAppReports(jwt: string, opts?: { limit?: number; offset?: number }) {\n const qs = new URLSearchParams();\n if (opts?.limit) qs.set('limit', String(opts.limit));\n if (opts?.offset) qs.set('offset', String(opts.offset));\n const suffix = qs.size ? `?${qs.toString()}` : '';\n return request<{ reports: MushiCrossAppReport[] }>(\n 'GET',\n `/v1/tester/cross-app-reports${suffix}`,\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getMyReputation(jwt: string) {\n return request<{ reputation: MushiTesterReputation | null }>(\n 'GET',\n '/v1/tester/reputation',\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n\n async getPublicLeaderboard(limit = 20) {\n return request<{ leaderboard: MushiLeaderboardEntry[] }>(\n 'GET',\n `/v1/public/tester-leaderboard?limit=${limit}`,\n undefined,\n 1,\n 'reporter-poll',\n );\n },\n\n async getTesterStatus(jwt: string) {\n return request<{ is_tester: boolean; tester_id: string | null; public_handle: string | null; display_name: string | null }>(\n 'GET',\n '/v1/me/tester-status',\n undefined,\n 1,\n 'community',\n { Authorization: `Bearer ${jwt}` },\n );\n },\n };\n}\n\nasync function sha256Hex(value: string): Promise<string> {\n const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nasync function hmacSha256Hex(secret: string, value: string): Promise<string> {\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const buffer = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(value));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, 10_000);\n}\n\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof TypeError) return true; // network failures\n return false;\n}\n","/**\n * C7: Data residency region resolution.\n *\n * The SDK supports four regional clouds:\n * - 'us' → United States (default; legacy `dxptnwrhwsqckaftyymj`)\n * - 'eu' → European Union (Frankfurt)\n * - 'jp' → Japan (Tokyo)\n * - 'self' → self-hosted / BYO Supabase\n *\n * Customers choose a region at project creation time, and the gateway will\n * 307-redirect any cross-region calls to the correct host. The SDK caches\n * the resolved hostname in `localStorage` (browser) so that subsequent\n * sessions skip the redirect.\n */\n\nexport type MushiRegion = 'us' | 'eu' | 'jp' | 'self';\n\nexport const REGION_ENDPOINTS: Record<Exclude<MushiRegion, 'self'>, string> = {\n us: 'https://api.us.mushimushi.dev/functions/v1/api',\n eu: 'https://api.eu.mushimushi.dev/functions/v1/api',\n jp: 'https://api.jp.mushimushi.dev/functions/v1/api',\n};\n\nconst ROUTING_CACHE_KEY = 'mushi_region_v1';\nconst ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\ninterface RegionCacheEntry {\n region: MushiRegion;\n endpoint: string;\n ts: number;\n}\n\n/**\n * Resolve the regional endpoint for a project. Looks up the public\n * `region_routing` table on the legacy US gateway (the catalog of record),\n * then caches the result.\n *\n * Falls back to the explicit `apiEndpoint` if anything goes wrong — failure\n * here must never block report submission.\n */\nexport async function resolveRegionEndpoint(opts: {\n projectId: string;\n apiEndpoint: string;\n region?: MushiRegion;\n storage?: Storage;\n fetcher?: typeof fetch;\n}): Promise<string> {\n const explicit = opts.region;\n if (explicit && explicit !== 'self' && REGION_ENDPOINTS[explicit]) {\n return REGION_ENDPOINTS[explicit];\n }\n\n const storage = opts.storage ?? safeLocalStorage();\n const cached = readCache(storage, opts.projectId);\n if (cached) return cached;\n\n try {\n const fetcher = opts.fetcher ?? fetch;\n const url = `${opts.apiEndpoint.replace(/\\/$/, '')}/v1/region/resolve?project_id=${encodeURIComponent(opts.projectId)}`;\n const res = await fetcher(url, { method: 'GET' });\n if (!res.ok) return opts.apiEndpoint;\n const body = (await res.json()) as { region?: MushiRegion; endpoint?: string };\n if (!body.region || !body.endpoint) return opts.apiEndpoint;\n writeCache(storage, opts.projectId, { region: body.region, endpoint: body.endpoint, ts: Date.now() });\n return body.endpoint;\n } catch {\n return opts.apiEndpoint;\n }\n}\n\nfunction safeLocalStorage(): Storage | undefined {\n try {\n return typeof globalThis !== 'undefined' && 'localStorage' in globalThis\n ? (globalThis as { localStorage: Storage }).localStorage\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readCache(storage: Storage | undefined, projectId: string): string | null {\n if (!storage) return null;\n try {\n const raw = storage.getItem(`${ROUTING_CACHE_KEY}:${projectId}`);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as RegionCacheEntry;\n if (Date.now() - parsed.ts > ROUTING_CACHE_TTL_MS) return null;\n return parsed.endpoint;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(storage: Storage | undefined, projectId: string, entry: RegionCacheEntry): void {\n if (!storage) return;\n try {\n storage.setItem(`${ROUTING_CACHE_KEY}:${projectId}`, JSON.stringify(entry));\n } catch {\n /* no-op: quota exceeded etc. */\n }\n}\n","/**\n * FILE: packages/core/src/env-config.ts\n * PURPOSE: Reads Mushi credentials from the environment when they are not\n * supplied explicitly. This lets every framework init work with\n * zero-config — just run `npx mushi-mushi` once, add the .env.local\n * line, and the provider/plugin/init works without props.\n *\n * Resolution order per field:\n * 1. Vite / SvelteKit / Angular (VITE_MUSHI_*)\n * 2. Next.js (NEXT_PUBLIC_MUSHI_*)\n * 3. Nuxt (NUXT_PUBLIC_MUSHI_*)\n * 4. Expo managed workflow (EXPO_PUBLIC_MUSHI_*)\n * 5. Node / React Native / server (bare MUSHI_*)\n *\n * Vite statically replaces `import.meta.env.VITE_*` at build time, so the\n * literal key references here are intentional — they make bundlers replace\n * the values even when accessed indirectly.\n *\n * Next.js and Expo, by contrast, do STATIC string replacement that only\n * inlines literal `process.env.NEXT_PUBLIC_*` / `process.env.EXPO_PUBLIC_*`\n * dot-notation references. A dynamic `process.env[key]` lookup is explicitly\n * unsupported and silently resolves to `undefined` in production client\n * bundles (Expo even ships an ESLint rule against it). Every `process.env`\n * read below is therefore a literal, statically-analyzable reference.\n */\n\nexport interface ResolvedEnvConfig {\n projectId?: string;\n apiKey?: string;\n apiEndpoint?: string;\n}\n\nfunction first(...values: (string | undefined)[]): string | undefined {\n return values.find((v) => v !== undefined && v !== '');\n}\n\nfunction tryImportMetaEnv(key: string): string | undefined {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const env = (import.meta as any).env;\n return typeof env === 'object' && env !== null ? (env[key] as string | undefined) : undefined;\n } catch {\n return undefined;\n }\n}\n\n// `process` is declared locally because the core package intentionally omits\n// `@types/node` to stay browser-safe. The reads below MUST use literal\n// `process.env.<KEY>` dot-notation (never `process.env[key]`) so Next.js and\n// Expo can inline the values during their build-time static replacement pass.\ndeclare const process: { env: Record<string, string | undefined> };\n\n/**\n * Evaluate a literal `process.env.<KEY>` read, degrading to `undefined` when\n * `process` is not defined (a pure browser runtime where the bundler did not\n * inline the value) instead of throwing a ReferenceError.\n */\nfunction readProcessEnv(read: () => string | undefined): string | undefined {\n try {\n return read();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Reads Mushi projectId, apiKey, and (optionally) apiEndpoint from\n * the environment. Returns only the fields that are present so callers\n * can cleanly spread: `{ ...resolveEnvConfig(), ...explicitConfig }`.\n */\nexport function resolveEnvConfig(): ResolvedEnvConfig {\n const projectId = first(\n tryImportMetaEnv('VITE_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_PROJECT_ID'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_PROJECT_ID'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_PROJECT_ID),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_PROJECT_ID),\n readProcessEnv(() => process.env.MUSHI_PROJECT_ID),\n );\n\n const apiKey = first(\n tryImportMetaEnv('VITE_MUSHI_API_KEY'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_API_KEY'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_API_KEY'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_API_KEY'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_KEY),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_KEY),\n readProcessEnv(() => process.env.MUSHI_API_KEY),\n );\n\n const apiEndpoint = first(\n tryImportMetaEnv('VITE_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('NEXT_PUBLIC_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('NUXT_PUBLIC_MUSHI_API_ENDPOINT'),\n tryImportMetaEnv('EXPO_PUBLIC_MUSHI_API_ENDPOINT'),\n readProcessEnv(() => process.env.NEXT_PUBLIC_MUSHI_API_ENDPOINT),\n readProcessEnv(() => process.env.EXPO_PUBLIC_MUSHI_API_ENDPOINT),\n readProcessEnv(() => process.env.MUSHI_API_ENDPOINT),\n );\n\n const result: ResolvedEnvConfig = {};\n if (projectId) result.projectId = projectId;\n if (apiKey) result.apiKey = apiKey;\n if (apiEndpoint) result.apiEndpoint = apiEndpoint;\n return result;\n}\n","import type { MushiPreFilterConfig } from './types';\n\nexport interface PreFilterResult {\n passed: boolean;\n reason?: string;\n}\n\nconst DEFAULT_MIN_LENGTH = 10;\nconst DEFAULT_MAX_LENGTH = 2000;\n\nconst SPAM_PATTERNS: RegExp[] = [\n /^(.)\\1{10,}$/, // repeated single character\n /^[A-Z\\s!?]{20,}$/, // all caps shouting\n /^[\\d\\s]+$/, // numbers only\n /^[^a-zA-Z\\u00C0-\\u024F\\u4E00-\\u9FFF\\u3040-\\u309F\\u30A0-\\u30FF]{10,}$/, // no real letters\n // \"test\" removed — users legitimately write \"I was testing…\" in real reports.\n // Keep clearly-nonsense patterns that are never real sentences.\n /^(asdf|qwerty|lorem ipsum)[.,!?\\s]*$/i, // standalone keyboard-mash or placeholder\n];\n\nconst GIBBERISH_PATTERN = /^[bcdfghjklmnpqrstvwxz]{6,}/i; // consonant-only strings\n\nexport function createPreFilter(config: MushiPreFilterConfig = {}) {\n const {\n enabled = true,\n blockObviousSpam = true,\n minDescriptionLength = DEFAULT_MIN_LENGTH,\n maxDescriptionLength = DEFAULT_MAX_LENGTH,\n } = config;\n\n function check(description: string): PreFilterResult {\n if (!enabled) {\n return { passed: true };\n }\n\n const trimmed = description.trim();\n\n if (trimmed.length < minDescriptionLength) {\n return { passed: false, reason: `Too short (min ${minDescriptionLength} characters)` };\n }\n\n if (trimmed.length > maxDescriptionLength) {\n return { passed: false, reason: `Too long (max ${maxDescriptionLength} characters)` };\n }\n\n if (blockObviousSpam) {\n for (const pattern of SPAM_PATTERNS) {\n if (pattern.test(trimmed)) {\n return { passed: false, reason: 'Detected as spam' };\n }\n }\n\n if (GIBBERISH_PATTERN.test(trimmed)) {\n return { passed: false, reason: 'Detected as gibberish' };\n }\n\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 1);\n if (words.length < 2) {\n return { passed: false, reason: 'Description needs at least 2 words' };\n }\n }\n\n return { passed: true };\n }\n\n function truncate(description: string): string {\n const trimmed = description.trim();\n if (trimmed.length <= maxDescriptionLength) return trimmed;\n return trimmed.slice(0, maxDescriptionLength) + '...';\n }\n\n return { check, truncate };\n}\n","/**\n * FILE: logger.ts\n * PURPOSE: Zero-dependency structured logger for the mushi-mushi SDK ecosystem.\n *\n * OVERVIEW:\n * - Production-grade logging with levels, scoped namespaces, and child loggers\n * - JSON output for server/production, pretty-formatted output for development\n * - Automatic environment detection (browser vs Node vs Deno)\n * - Structured metadata on every log entry\n * - No external dependencies — safe to ship in any SDK bundle\n *\n * USAGE:\n * import { createLogger } from '@mushi-mushi/core'\n * const log = createLogger({ scope: 'mushi:api' })\n * log.info('Request received', { method: 'POST', path: '/v1/reports' })\n * const child = log.child('ingest', { reportId: 'abc' })\n * child.warn('Slow query', { latencyMs: 420 })\n *\n * TECHNICAL DETAILS:\n * - Log levels: debug(10) < info(20) < warn(30) < error(40) < fatal(50) < silent(99)\n * - Format auto-detected: JSON in production/server, pretty in development\n * - Pretty format uses ANSI colors when supported (Node/Deno TTY)\n * - Child loggers inherit parent scope + metadata, can override level\n * - Timestamps are ISO 8601 with millisecond precision\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent'\n\nexport type LogFormat = 'json' | 'pretty' | 'auto'\n\nexport interface LoggerOptions {\n scope: string\n level?: LogLevel\n meta?: Record<string, unknown>\n format?: LogFormat\n /**\n * Where to write log output.\n * - `'stdout'` (default): normal servers, browsers.\n * - `'stderr'`: use for stdio MCP servers where stdout is the JSON-RPC\n * protocol pipe; any non-JSON-RPC bytes there corrupt the connection.\n */\n destination?: 'stdout' | 'stderr'\n}\n\nexport interface Logger {\n debug(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n error(msg: string, meta?: Record<string, unknown>): void\n fatal(msg: string, meta?: Record<string, unknown>): void\n child(scope: string, meta?: Record<string, unknown>): Logger\n setLevel(level: LogLevel): void\n}\n\nexport interface LogEntry {\n ts: string\n level: LogLevel\n scope: string\n msg: string\n [key: string]: unknown\n}\n\nconst LEVEL_VALUE: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n fatal: 50,\n silent: 99,\n}\n\nconst LEVEL_LABEL: Record<string, string> = {\n debug: 'DBG',\n info: 'INF',\n warn: 'WRN',\n error: 'ERR',\n fatal: 'FTL',\n}\n\nconst ANSI = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n white: '\\x1b[37m',\n bgRed: '\\x1b[41m',\n} as const\n\nconst LEVEL_COLOR: Record<string, string> = {\n debug: ANSI.dim,\n info: ANSI.green,\n warn: ANSI.yellow,\n error: ANSI.red,\n fatal: `${ANSI.bgRed}${ANSI.white}${ANSI.bold}`,\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nfunction detectFormat(): 'json' | 'pretty' {\n try {\n if (typeof (globalThis as any).Deno !== 'undefined') return 'json'\n } catch { /* not Deno */ }\n\n const proc = typeof (globalThis as any).process !== 'undefined'\n ? (globalThis as any).process\n : undefined\n\n if (proc?.env) {\n if (proc.env.NODE_ENV === 'production') return 'json'\n if (proc.env.LOG_FORMAT === 'json') return 'json'\n if (proc.env.LOG_FORMAT === 'pretty') return 'pretty'\n if (proc.stdout?.isTTY) return 'pretty'\n }\n\n if (typeof (globalThis as any).window !== 'undefined') return 'pretty'\n\n return 'json'\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nfunction flattenMeta(meta: Record<string, unknown>): string {\n const parts: string[] = []\n for (const [k, v] of Object.entries(meta)) {\n if (v === undefined || v === null) continue\n if (typeof v === 'object') {\n parts.push(`${k}=${JSON.stringify(v)}`)\n } else {\n parts.push(`${k}=${String(v)}`)\n }\n }\n return parts.join(' ')\n}\n\nfunction formatPretty(entry: LogEntry): string {\n const { ts, level, scope, msg, ...rest } = entry\n const time = ts.slice(11, 23)\n const color = LEVEL_COLOR[level] ?? ''\n const label = LEVEL_LABEL[level] ?? level.toUpperCase()\n const metaStr = Object.keys(rest).length > 0 ? ` ${ANSI.dim}${flattenMeta(rest)}${ANSI.reset}` : ''\n\n return `${ANSI.dim}${time}${ANSI.reset} ${color}${label}${ANSI.reset} ${ANSI.cyan}[${scope}]${ANSI.reset} ${msg}${metaStr}`\n}\n\nfunction formatJson(entry: LogEntry): string {\n return JSON.stringify(entry)\n}\n\n/* eslint-disable no-console */\nfunction makeEmitter(destination: 'stdout' | 'stderr') {\n if (destination === 'stderr') {\n // Write everything to stderr — required for stdio MCP servers.\n return (level: LogLevel, formatted: string): void => {\n void level\n console.error(formatted)\n }\n }\n return (level: LogLevel, formatted: string): void => {\n switch (level) {\n case 'error':\n case 'fatal':\n console.error(formatted)\n break\n case 'warn':\n console.warn(formatted)\n break\n default:\n console.log(formatted)\n }\n }\n}\n/* eslint-enable no-console */\n\nfunction buildLogger(\n scope: string,\n minLevel: LogLevel,\n baseMeta: Record<string, unknown>,\n formatter: (entry: LogEntry) => string,\n emit: (level: LogLevel, formatted: string) => void,\n): Logger {\n let currentLevel = minLevel\n\n function log(level: LogLevel, msg: string, meta?: Record<string, unknown>): void {\n if (LEVEL_VALUE[level] < LEVEL_VALUE[currentLevel]) return\n\n const entry: LogEntry = {\n ts: new Date().toISOString(),\n level,\n scope,\n msg,\n ...baseMeta,\n ...meta,\n }\n\n emit(level, formatter(entry))\n }\n\n return {\n debug: (msg, meta?) => log('debug', msg, meta),\n info: (msg, meta?) => log('info', msg, meta),\n warn: (msg, meta?) => log('warn', msg, meta),\n error: (msg, meta?) => log('error', msg, meta),\n fatal: (msg, meta?) => log('fatal', msg, meta),\n\n child(childScope: string, childMeta?: Record<string, unknown>): Logger {\n return buildLogger(\n `${scope}:${childScope}`,\n currentLevel,\n { ...baseMeta, ...childMeta },\n formatter,\n emit,\n )\n },\n\n setLevel(level: LogLevel) {\n currentLevel = level\n },\n }\n}\n\n/**\n * Create a structured logger instance.\n *\n * @example\n * const log = createLogger({ scope: 'mushi:api', level: 'info' })\n * log.info('Server started', { port: 3000 })\n *\n * const child = log.child('auth', { userId: 'u-123' })\n * child.warn('Token expired')\n */\nexport function createLogger(options: LoggerOptions): Logger {\n const {\n scope,\n level = 'info',\n meta = {},\n format = 'auto',\n destination = 'stdout',\n } = options\n\n const resolvedFormat = format === 'auto' ? detectFormat() : format\n const formatter = resolvedFormat === 'json' ? formatJson : formatPretty\n const emit = makeEmitter(destination)\n\n return buildLogger(scope, level, meta, formatter, emit)\n}\n\n/**\n * Noop logger that discards all output.\n * Useful when logging should be completely disabled.\n */\nexport const noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {},\n child: () => noopLogger,\n setLevel: () => {},\n}\n","/**\n * AES-GCM at-rest encryption for the offline queue (Wave S1 / D-16).\n *\n * Why this exists: on shared devices (kiosks, support-agent laptops) a\n * queued bug report sits in plaintext IndexedDB until the next flush.\n * Browser extensions, other tabs on the same origin, and forensic tools\n * with disk access can all read it. For a QA/bug-reporting SDK that\n * encourages users to paste sensitive data into descriptions, that's\n * unacceptable.\n *\n * Design:\n * - Generate a non-extractable AES-GCM key on first call (256-bit).\n * - Persist the `CryptoKey` object itself (Web Crypto allows IDB round-\n * trip of `CryptoKey` without ever serialising the raw bytes).\n * - Use a 12-byte random IV per payload; prepend it to ciphertext so\n * decrypt() needs no out-of-band state.\n * - Never block the caller — all errors bubble up so the queue can fall\n * back to plaintext storage with a debug log (see queue.ts).\n *\n * The key is tied to the browser origin (same-origin IDB). It does NOT\n * protect against an attacker with admin shell on the device: the browser\n * WILL decrypt on demand for anyone with origin access. That's the same\n * guarantee every origin-bound browser secret has and is the correct\n * threat model for offline bug reports.\n */\n\nconst KEY_DB = 'mushi-mushi-keyring';\nconst KEY_STORE = 'keys';\nconst KEY_RECORD_ID = 'offline-queue/v1';\n\nlet cachedKey: CryptoKey | null = null;\nlet cachedKeyPromise: Promise<CryptoKey> | null = null;\n\nfunction hasWebCrypto(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as unknown as { crypto?: Crypto }).crypto !== 'undefined' &&\n typeof (globalThis as unknown as { crypto: Crypto }).crypto.subtle !== 'undefined' &&\n typeof indexedDB !== 'undefined'\n );\n}\n\nfunction openKeyDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(KEY_DB, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(KEY_STORE)) {\n db.createObjectStore(KEY_STORE);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function loadKey(): Promise<CryptoKey | null> {\n const db = await openKeyDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(KEY_STORE, 'readonly');\n const req = tx.objectStore(KEY_STORE).get(KEY_RECORD_ID);\n req.onsuccess = () => resolve((req.result as CryptoKey) ?? null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function storeKey(key: CryptoKey): Promise<void> {\n const db = await openKeyDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(KEY_STORE, 'readwrite');\n tx.objectStore(KEY_STORE).put(key, KEY_RECORD_ID);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Lazily get (or generate once + persist) the AES-GCM key for this origin.\n * `extractable: false` — so a script-level attacker can't `exportKey()` and\n * ship the raw bytes to their server, only use it via `encrypt`/`decrypt`.\n */\nexport async function getOfflineQueueKey(): Promise<CryptoKey> {\n if (cachedKey) return cachedKey;\n if (cachedKeyPromise) return cachedKeyPromise;\n if (!hasWebCrypto()) {\n throw new Error('Web Crypto + IndexedDB required for offline queue encryption');\n }\n cachedKeyPromise = (async () => {\n const existing = await loadKey();\n if (existing) {\n cachedKey = existing;\n return existing;\n }\n const key = await crypto.subtle.generateKey(\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n await storeKey(key);\n cachedKey = key;\n return key;\n })();\n return cachedKeyPromise;\n}\n\nexport interface EncryptedPayload {\n /** Magic marker so decrypt() can tell encrypted vs legacy plaintext rows. */\n readonly _mme: 1;\n readonly iv: string;\n readonly ct: string;\n}\n\nfunction bytesToB64(bytes: Uint8Array): string {\n let s = '';\n for (const b of bytes) s += String.fromCharCode(b);\n return btoa(s);\n}\n\nfunction b64ToBytes(s: string): Uint8Array<ArrayBuffer> {\n const bin = atob(s);\n const out = new Uint8Array(new ArrayBuffer(bin.length));\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport async function encryptJson(plain: unknown): Promise<EncryptedPayload> {\n const key = await getOfflineQueueKey();\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const data = new TextEncoder().encode(JSON.stringify(plain));\n const cipher = new Uint8Array(await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data));\n return { _mme: 1, iv: bytesToB64(iv), ct: bytesToB64(cipher) };\n}\n\nexport function isEncryptedPayload(v: unknown): v is EncryptedPayload {\n return (\n !!v &&\n typeof v === 'object' &&\n (v as EncryptedPayload)._mme === 1 &&\n typeof (v as EncryptedPayload).iv === 'string' &&\n typeof (v as EncryptedPayload).ct === 'string'\n );\n}\n\nexport async function decryptJson<T = unknown>(payload: EncryptedPayload): Promise<T> {\n const key = await getOfflineQueueKey();\n const iv = b64ToBytes(payload.iv);\n const ct = b64ToBytes(payload.ct);\n const plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct);\n return JSON.parse(new TextDecoder().decode(plain)) as T;\n}\n","import type { MushiApiClient, MushiOfflineConfig, MushiReport } from './types';\nimport { createLogger } from './logger';\nimport {\n encryptJson,\n decryptJson,\n isEncryptedPayload,\n type EncryptedPayload,\n} from './queue-crypto';\n\nconst queueLog = createLogger({ scope: 'mushi:queue', level: 'warn' });\n\n// Wave S1 / D-16: opaque at-rest wrapper. Each queue row is either:\n// - a legacy plaintext `MushiReport` (pre-encryption; still readable)\n// - an `EncryptedRecord` with a bare `id` (so count / delete can operate\n// without decrypting every row) plus the encrypted payload blob.\ninterface EncryptedRecord {\n id: string;\n queuedAt: string;\n payload: EncryptedPayload;\n}\n\ntype StoredRow = MushiReport | EncryptedRecord;\n\nconst DB_NAME = 'mushi-mushi';\nconst STORE_NAME = 'offline-reports';\nconst DB_VERSION = 1;\nconst LS_KEY = 'mushi_offline_queue';\nconst BATCH_SIZE = 10;\nconst MAX_BACKOFF_MS = 60_000;\nconst AUTO_FLUSH_INTERVAL_MS = 30_000;\n// A queued report that can never be delivered (corrupt payload, a permanently\n// offline host, or a network layer that keeps rejecting the POST) must not\n// loop forever — otherwise it hammers the API and floods the console on every\n// flush tick and page load. Two independent give-up gates bound the retry\n// surface:\n// - MAX_DELIVERY_ATTEMPTS: drop a row after this many transient failures.\n// - MAX_QUEUE_AGE_MS: hard backstop — evict any row older than this on the\n// next flush regardless of attempt count (also clears legacy rows that\n// predate the per-row attempt counter so they stop re-flushing).\nconst MAX_DELIVERY_ATTEMPTS = 8;\nconst MAX_QUEUE_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport interface OfflineQueue {\n enqueue(report: MushiReport): Promise<void>;\n flush(client: MushiApiClient): Promise<{ sent: number; failed: number }>;\n size(): Promise<number>;\n clear(): Promise<void>;\n startAutoSync(client: MushiApiClient): void;\n stopAutoSync(): void;\n}\n\ntype StorageBackend = 'indexeddb' | 'localstorage' | 'none';\n\nexport function createOfflineQueue(config: MushiOfflineConfig = {}): OfflineQueue {\n const { enabled = true, maxQueueSize = 50, syncOnReconnect = true, encryptAtRest = true } = config;\n\n let syncCleanup: (() => void) | null = null;\n let flushInterval: ReturnType<typeof setInterval> | null = null;\n let backendType: StorageBackend | null = null;\n\n async function wrapForStorage(report: MushiReport): Promise<StoredRow> {\n const queuedAt = new Date().toISOString();\n if (!encryptAtRest) {\n return { ...report, queuedAt } as MushiReport;\n }\n try {\n const payload = await encryptJson(report);\n return { id: report.id, queuedAt, payload } satisfies EncryptedRecord;\n } catch (err) {\n // Encryption failure is non-fatal — queue integrity matters more than\n // at-rest confidentiality. We fall back to plaintext and warn.\n queueLog.warn('Offline queue: encryption failed, storing plaintext', { err: String(err) });\n return { ...report, queuedAt } as MushiReport;\n }\n }\n\n async function unwrapForSend(row: StoredRow): Promise<MushiReport | null> {\n if (isEncryptedRecord(row)) {\n try {\n return await decryptJson<MushiReport>(row.payload);\n } catch (err) {\n queueLog.warn('Offline queue: decrypt failed, dropping row', { err: String(err), id: row.id });\n return null;\n }\n }\n return row;\n }\n\n function isEncryptedRecord(row: StoredRow): row is EncryptedRecord {\n return !!(row as EncryptedRecord).payload && isEncryptedPayload((row as EncryptedRecord).payload);\n }\n\n // The delivery-attempt counter lives on the OUTER row (alongside `id` /\n // `queuedAt`), so it can be read and bumped for an encrypted record without\n // decrypting the payload.\n function rowAttempts(row: StoredRow): number {\n const n = (row as { attempts?: number }).attempts;\n return typeof n === 'number' && Number.isFinite(n) ? n : 0;\n }\n\n // True when a row has outlived MAX_QUEUE_AGE_MS. Rows without a parseable\n // `queuedAt` are never age-evicted here — the attempt counter is their gate.\n function isExpired(row: StoredRow, now: number): boolean {\n const queuedAt = (row as { queuedAt?: string }).queuedAt;\n if (!queuedAt) return false;\n const ts = Date.parse(queuedAt);\n if (Number.isNaN(ts)) return false;\n return now - ts > MAX_QUEUE_AGE_MS;\n }\n\n function detectBackend(): StorageBackend {\n if (backendType) return backendType;\n if (typeof indexedDB !== 'undefined') {\n backendType = 'indexeddb';\n } else if (typeof localStorage !== 'undefined') {\n backendType = 'localstorage';\n } else {\n backendType = 'none';\n }\n return backendType;\n }\n\n // --- IndexedDB backend ---\n\n function openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n backendType = 'localstorage';\n reject(request.error);\n };\n });\n }\n\n async function idbEnqueue(report: MushiReport): Promise<void> {\n const db = await openDb();\n const row = await wrapForStorage(report);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).put(row);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbGetAll(): Promise<StoredRow[]> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).getAll();\n request.onsuccess = () => resolve(request.result as StoredRow[]);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbDelete(id: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).delete(id);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // Overwrite an existing row in place (keyed by `id`) — used to persist the\n // incremented attempt counter after a transient failure.\n async function idbPutRow(row: StoredRow): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).put(row);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbSize(): Promise<number> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).count();\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbClear(): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // --- localStorage fallback ---\n\n function lsRead(): StoredRow[] {\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? (JSON.parse(raw) as StoredRow[]) : [];\n } catch {\n return [];\n }\n }\n\n function lsWrite(rows: StoredRow[]): void {\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(rows));\n } catch {\n // localStorage full or unavailable\n }\n }\n\n async function lsEnqueue(report: MushiReport): Promise<void> {\n const rows = lsRead();\n rows.push(await wrapForStorage(report));\n lsWrite(rows);\n }\n\n function lsDelete(id: string): void {\n const rows = lsRead().filter((r) => r.id !== id);\n lsWrite(rows);\n }\n\n // Replace an existing row in place (matched by `id`) — used to persist the\n // incremented attempt counter after a transient failure.\n function lsUpdateRow(row: StoredRow): void {\n const rows = lsRead();\n const idx = rows.findIndex((r) => (r as { id: string }).id === (row as { id: string }).id);\n if (idx >= 0) {\n rows[idx] = row;\n lsWrite(rows);\n }\n }\n\n // --- Backend-aware row mutators ---\n //\n // A queue row lives in exactly one backend (chosen once per session by\n // detectBackend). We must NOT cross-write to the other backend on failure: a\n // row read from IndexedDB does not exist in localStorage, so an `lsDelete` /\n // `lsUpdateRow` fallback is a guaranteed silent no-op. The earlier\n // `catch { lsUpdateRow(row) }` form meant a failed IndexedDB attempt-counter\n // write never persisted, so the row re-flushed forever (bypassing\n // MAX_DELIVERY_ATTEMPTS) until the 24h age sweep — see Sentry 14751132/0.\n\n // Remove a row from the active backend. A failure is non-fatal: the row\n // survives to the next flush, where the MAX_QUEUE_AGE_MS sweep is the\n // backstop. No cross-backend fallback (see note above).\n async function removeRow(backend: StorageBackend, rowId: string): Promise<void> {\n try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch (err) {\n queueLog.debug('Offline queue: row removal failed (will age out)', {\n id: rowId,\n err: String(err),\n });\n }\n }\n\n // Persist a row in place to save its bumped attempt counter. Returns false\n // when the write could not land, so the caller can give up on the row rather\n // than loop forever on a counter that never advances. No cross-backend\n // fallback (see note above).\n async function persistRow(backend: StorageBackend, row: StoredRow): Promise<boolean> {\n try {\n if (backend === 'indexeddb') await idbPutRow(row);\n else lsUpdateRow(row);\n return true;\n } catch (err) {\n queueLog.debug('Offline queue: row persist failed', {\n id: (row as { id: string }).id,\n err: String(err),\n });\n return false;\n }\n }\n\n // --- Unified interface ---\n\n async function enqueue(report: MushiReport): Promise<void> {\n if (!enabled) return;\n\n const currentSize = await size();\n if (currentSize >= maxQueueSize) {\n queueLog.warn('Offline queue full — dropping report', { maxQueueSize });\n return;\n }\n\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbEnqueue(report);\n return;\n } catch {\n // IndexedDB failed, fall through to localStorage\n backendType = 'localstorage';\n }\n }\n\n if (backend === 'localstorage' || backendType === 'localstorage') {\n await lsEnqueue(report);\n return;\n }\n }\n\n function getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, MAX_BACKOFF_MS);\n }\n\n function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async function flush(client: MushiApiClient): Promise<{ sent: number; failed: number }> {\n if (!enabled) return { sent: 0, failed: 0 };\n\n let rows: StoredRow[];\n const backend = detectBackend();\n\n if (backend === 'indexeddb') {\n try {\n rows = await idbGetAll();\n } catch {\n rows = lsRead();\n }\n } else {\n rows = lsRead();\n }\n\n // Backstop: evict any row that has outlived MAX_QUEUE_AGE_MS before we\n // spend a network attempt on it. This sweeps the whole queue (IndexedDB\n // getAll() is key-ordered, not FIFO, so a stale row may not be in the\n // batch window) and clears legacy rows that predate the attempt counter so\n // they can't re-flush forever on every page load.\n const now = Date.now();\n const fresh: StoredRow[] = [];\n for (const row of rows) {\n if (isExpired(row, now)) {\n const rowId = (row as { id: string }).id;\n await removeRow(backend, rowId);\n queueLog.debug('Offline queue: evicting stale report', { id: rowId });\n } else {\n fresh.push(row);\n }\n }\n rows = fresh;\n\n const batch = rows.slice(0, BATCH_SIZE);\n let sent = 0;\n let failed = 0;\n\n for (let i = 0; i < batch.length; i++) {\n const row = batch[i];\n const rowId = (row as { id: string }).id;\n const report = await unwrapForSend(row);\n\n if (!report) {\n // Undecryptable row — drop so it doesn't re-poison the queue forever.\n await removeRow(backend, rowId);\n failed++;\n continue;\n }\n\n const result = await client.submitReport(report);\n\n if (result.ok) {\n await removeRow(backend, rowId);\n sent++;\n } else {\n const permanent =\n result.error?.code === 'HTTP_400' ||\n result.error?.code === 'HTTP_413' ||\n result.error?.code === 'HTTP_422' ||\n result.error?.code === 'INGEST_ERROR' ||\n result.error?.code === 'VALIDATION_ERROR' ||\n // A payload that exceeds the size guard will never shrink on its own;\n // retrying re-serialises the multi-MB body every sync tick and wedges\n // the queue (it matches neither permanent nor transient otherwise).\n // SERIALIZE_FAILED (circular ref) is likewise unrecoverable on retry.\n result.error?.code === 'PAYLOAD_TOO_LARGE' ||\n result.error?.code === 'SERIALIZE_FAILED' ||\n (typeof result.error?.message === 'string' &&\n /invalid payload|description must be at least|validation/i.test(\n result.error.message,\n ));\n const transient =\n !permanent &&\n (result.error?.code === 'NETWORK_ERROR' ||\n result.error?.code === 'HTTP_403' ||\n result.error?.code === 'HTTP_429' ||\n result.error?.code === 'HTTP_502' ||\n result.error?.code === 'HTTP_503' ||\n result.error?.code === 'HTTP_504' ||\n (typeof result.error?.code === 'string' && result.error.code.startsWith('HTTP_5')));\n if (permanent) {\n await removeRow(backend, rowId);\n } else if (transient) {\n // Bump the per-row attempt counter and give up once it crosses the\n // ceiling, so a report the network keeps rejecting eventually leaves\n // the queue instead of retrying forever on every flush + page load.\n const nextAttempts = rowAttempts(row) + 1;\n if (nextAttempts >= MAX_DELIVERY_ATTEMPTS) {\n await removeRow(backend, rowId);\n queueLog.warn('Offline queue: giving up on report after repeated failures', {\n id: rowId,\n attempts: nextAttempts,\n code: result.error?.code,\n });\n } else {\n (row as { attempts?: number }).attempts = nextAttempts;\n const persisted = await persistRow(backend, row);\n if (persisted) {\n queueLog.debug('Offline queue: transient failure, will retry', {\n id: rowId,\n attempts: nextAttempts,\n code: result.error?.code,\n });\n } else {\n // The bumped counter could not be saved (e.g. an IndexedDB write\n // failure). Leaving the row would re-flush it forever with a\n // counter that never advances, defeating MAX_DELIVERY_ATTEMPTS —\n // so drop it now rather than wait 24h for the age sweep.\n await removeRow(backend, rowId);\n queueLog.warn('Offline queue: dropping report (attempt counter unpersistable)', {\n id: rowId,\n code: result.error?.code,\n });\n }\n }\n }\n failed++;\n if (i < batch.length - 1) {\n await sleep(getBackoffDelay(i));\n }\n }\n }\n\n return { sent, failed };\n }\n\n async function size(): Promise<number> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n return await idbSize();\n } catch {\n return lsRead().length;\n }\n }\n return lsRead().length;\n }\n\n async function clear(): Promise<void> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbClear();\n } catch {\n // fall through\n }\n }\n try {\n localStorage.removeItem(LS_KEY);\n } catch {\n // unavailable\n }\n }\n\n function startAutoSync(client: MushiApiClient): void {\n if (!enabled || !syncOnReconnect || typeof window === 'undefined') return;\n\n const tryFlush = () => {\n if (navigator.onLine) {\n flush(client).catch(() => {});\n }\n };\n\n window.addEventListener('online', tryFlush);\n flushInterval = setInterval(() => {\n void size().then((n) => {\n if (n > 0) tryFlush();\n });\n }, AUTO_FLUSH_INTERVAL_MS);\n syncCleanup = () => {\n window.removeEventListener('online', tryFlush);\n if (flushInterval) {\n clearInterval(flushInterval);\n flushInterval = null;\n }\n };\n }\n\n function stopAutoSync(): void {\n syncCleanup?.();\n syncCleanup = null;\n }\n\n return { enqueue, flush, size, clear, startAutoSync, stopAutoSync };\n}\n","import type { MushiEnvironment } from './types';\n\n/**\n * Capture a snapshot of the runtime environment. Called once per\n * report submission, so every read here must be:\n *\n * 1. Synchronous (UA-Client Hints `getHighEntropyValues()` is the\n * sole exception — see `kickOffUserAgentData` below; the result\n * is memoised and folded back in on the next capture).\n * 2. SSR-safe (every `window`/`document`/`navigator` access must be\n * gated on `typeof X !== 'undefined'` because the SDK is\n * imported by Next.js / Remix server bundles).\n * 3. Tolerant of missing APIs (Safari doesn't have `Network\n * Information`, Firefox doesn't have UA-CH, screen.orientation is\n * flaky on iOS) — every individual field is optional so a\n * partially-supported browser still produces a useful payload.\n */\nexport function captureEnvironment(): MushiEnvironment {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined;\n const win = typeof window !== 'undefined' ? window : undefined;\n const doc = typeof document !== 'undefined' ? document : undefined;\n const scr = typeof screen !== 'undefined' ? screen : undefined;\n\n // Trigger UA-CH high-entropy resolution in the background. The first\n // capture lands without it; the second one (and every subsequent one)\n // gets the cached values folded in. We tolerate the gap because the\n // alternative is making `captureEnvironment` async — and that would\n // ripple into every call site (the offline queue, the diagnostics\n // worker, the proactive trigger pipeline) for a field that's only\n // useful when the browser happens to be Chromium.\n void kickOffUserAgentData(nav);\n\n const connection = nav && 'connection' in nav ? (nav as NavigatorWithConnection).connection : undefined;\n\n return {\n userAgent: nav?.userAgent ?? 'unknown',\n platform: nav?.platform ?? 'unknown',\n language: nav?.language ?? 'en',\n viewport: {\n width: win?.innerWidth ?? 0,\n height: win?.innerHeight ?? 0,\n },\n url: win?.location?.href ?? '',\n referrer: doc?.referrer ?? '',\n timestamp: new Date().toISOString(),\n timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? 'UTC',\n connection: connection\n ? {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n }\n : undefined,\n deviceMemory: (nav as NavigatorWithDeviceMemory)?.deviceMemory,\n hardwareConcurrency: nav?.hardwareConcurrency,\n route: win?.location?.pathname,\n nearestTestid: findNearestTestidFromActive(doc),\n\n userAgentData: captureUserAgentData(nav),\n screen: captureScreen(scr, win),\n prefersColorScheme: matchScheme(win),\n prefersReducedMotion: matchMedia(win, '(prefers-reduced-motion: reduce)'),\n prefersReducedData: matchMedia(win, '(prefers-reduced-data: reduce)'),\n prefersContrast: matchContrast(win),\n forcedColors: matchMedia(win, '(forced-colors: active)'),\n online: typeof nav?.onLine === 'boolean' ? nav.onLine : undefined,\n displayMode: matchDisplayMode(win),\n documentTitle: doc?.title?.slice(0, 200),\n buildId: readBuildIdMeta(doc),\n pageLoadTiming: capturePageLoadTiming(win),\n };\n}\n\n/**\n * Best-effort `data-testid` resolver for freeform reports — when the user\n * opens the widget without first using the element selector we still want\n * to map the report to an Action. We start from `document.activeElement`\n * (which is the most-recently-focused interactive element on most browsers)\n * and walk up. Falls back to undefined when no testid is in scope.\n *\n * Mirrors the walk in `packages/web/src/capture/element-selector.ts` so\n * both code paths produce the same value for the same DOM state.\n */\nfunction findNearestTestidFromActive(doc?: Document): string | undefined {\n if (!doc) return undefined;\n let cur: Element | null = doc.activeElement ?? null;\n let hops = 0;\n while (cur && hops < 20) {\n const tid = cur.getAttribute?.('data-testid');\n if (tid) return tid;\n cur = cur.parentElement;\n hops++;\n }\n return undefined;\n}\n\n// ---- UA-Client Hints (Chromium) ---------------------------------------------\n\ninterface UserAgentDataLow {\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n platform?: string;\n}\ninterface UserAgentDataHigh extends UserAgentDataLow {\n architecture?: string;\n bitness?: string;\n model?: string;\n platformVersion?: string;\n uaFullVersion?: string;\n fullVersionList?: Array<{ brand: string; version: string }>;\n}\ninterface NavigatorWithUAData extends Navigator {\n userAgentData?: UserAgentDataLow & {\n getHighEntropyValues?: (hints: string[]) => Promise<UserAgentDataHigh>;\n };\n}\n\nlet cachedHighEntropy: UserAgentDataHigh | null = null;\nlet highEntropyKickedOff = false;\n\nfunction kickOffUserAgentData(nav: Navigator | undefined): void {\n if (highEntropyKickedOff) return;\n const ua = (nav as NavigatorWithUAData | undefined)?.userAgentData;\n if (!ua?.getHighEntropyValues) return;\n highEntropyKickedOff = true;\n ua.getHighEntropyValues([\n 'architecture',\n 'bitness',\n 'model',\n 'platformVersion',\n 'uaFullVersion',\n 'fullVersionList',\n ])\n .then((v) => {\n cachedHighEntropy = v;\n })\n .catch(() => {\n // Some browsers reject the promise on cross-origin or insecure contexts;\n // we just carry on without the high-entropy bits.\n });\n}\n\n/**\n * Pick the most identifying brand from UA-CH `brands` — Chromium ships\n * with three: a stable real one (\"Chromium\" / \"Google Chrome\" / \"Brave\")\n * plus a placeholder (\"Not_A Brand\") that exists to test sniffer\n * tolerance. Skip the placeholder. Prefer non-Chromium-shell brands so\n * Brave / Edge / Opera identify as themselves rather than as Chromium.\n */\nfunction pickBrand(\n brands?: Array<{ brand: string; version: string }>,\n): { brand: string; version: string } | undefined {\n if (!brands?.length) return undefined;\n const real = brands.filter((b) => !/not.?a.?brand/i.test(b.brand));\n if (real.length === 0) return undefined;\n // Prefer a brand that isn't generic Chromium / Google Chrome — that's\n // the host browser when the user runs a derivative.\n const named = real.find((b) => !/chromium|google chrome/i.test(b.brand));\n return named ?? real[0];\n}\n\nfunction captureUserAgentData(nav: Navigator | undefined): MushiEnvironment['userAgentData'] {\n const low = (nav as NavigatorWithUAData | undefined)?.userAgentData;\n if (!low && !cachedHighEntropy) return undefined;\n const fullList = cachedHighEntropy?.fullVersionList;\n const brand = pickBrand(fullList ?? low?.brands);\n const out: NonNullable<MushiEnvironment['userAgentData']> = {};\n if (brand) {\n out.browser = brand.brand;\n out.browserVersion = brand.version;\n }\n // `platform` (low entropy) is e.g. \"macOS\", \"Windows\" — fine for a default.\n if (low?.platform) out.os = low.platform;\n if (cachedHighEntropy?.platformVersion) out.osVersion = cachedHighEntropy.platformVersion;\n if (typeof low?.mobile === 'boolean') out.mobile = low.mobile;\n if (cachedHighEntropy?.model) out.model = cachedHighEntropy.model;\n if (cachedHighEntropy?.architecture) out.architecture = cachedHighEntropy.architecture;\n if (cachedHighEntropy?.bitness) out.bitness = cachedHighEntropy.bitness;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\n// ---- Screen + media queries -------------------------------------------------\n\nfunction captureScreen(\n scr: Screen | undefined,\n win: Window | undefined,\n): MushiEnvironment['screen'] {\n if (!scr && !win) return undefined;\n const out: NonNullable<MushiEnvironment['screen']> = {};\n if (typeof scr?.width === 'number') out.width = scr.width;\n if (typeof scr?.height === 'number') out.height = scr.height;\n if (typeof win?.devicePixelRatio === 'number') out.devicePixelRatio = win.devicePixelRatio;\n if (typeof scr?.colorDepth === 'number') out.colorDepth = scr.colorDepth;\n // `screen.orientation` is intermittently undefined on iOS Safari, so we\n // can't lean on the standard `Screen` type — read it loosely via an\n // index access that tolerates the missing property at runtime.\n const orientationType = (scr as unknown as { orientation?: { type?: string } } | undefined)\n ?.orientation?.type;\n if (orientationType) out.orientation = orientationType;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\nfunction matchMedia(win: Window | undefined, query: string): boolean | undefined {\n if (!win?.matchMedia) return undefined;\n try {\n return win.matchMedia(query).matches;\n } catch {\n return undefined;\n }\n}\n\nfunction matchScheme(win: Window | undefined): MushiEnvironment['prefersColorScheme'] {\n if (!win?.matchMedia) return undefined;\n if (matchMedia(win, '(prefers-color-scheme: dark)')) return 'dark';\n if (matchMedia(win, '(prefers-color-scheme: light)')) return 'light';\n return 'no-preference';\n}\n\nfunction matchContrast(win: Window | undefined): MushiEnvironment['prefersContrast'] {\n if (!win?.matchMedia) return undefined;\n if (matchMedia(win, '(prefers-contrast: more)')) return 'more';\n if (matchMedia(win, '(prefers-contrast: less)')) return 'less';\n if (matchMedia(win, '(prefers-contrast: custom)')) return 'custom';\n return 'no-preference';\n}\n\nfunction matchDisplayMode(win: Window | undefined): MushiEnvironment['displayMode'] {\n if (!win?.matchMedia) return undefined;\n // Order matters: standalone implies !browser, fullscreen implies !standalone.\n // Walk most-specific-first.\n if (matchMedia(win, '(display-mode: fullscreen)')) return 'fullscreen';\n if (matchMedia(win, '(display-mode: standalone)')) return 'standalone';\n if (matchMedia(win, '(display-mode: minimal-ui)')) return 'minimal-ui';\n if (matchMedia(win, '(display-mode: browser)')) return 'browser';\n return undefined;\n}\n\n// ---- Build id from <meta name=\"mushi:build\"> --------------------------------\n\nfunction readBuildIdMeta(doc: Document | undefined): string | undefined {\n if (!doc) return undefined;\n const el = doc.querySelector?.('meta[name=\"mushi:build\"]') as HTMLMetaElement | null;\n const v = el?.content?.trim();\n if (!v) return undefined;\n // Cap at 64 chars — git SHAs are 40, semver+meta is well under that.\n // We don't want users accidentally shoving a manifest into a meta tag.\n return v.slice(0, 64);\n}\n\n// ---- Navigation timing ------------------------------------------------------\n\nfunction capturePageLoadTiming(win: Window | undefined): MushiEnvironment['pageLoadTiming'] {\n const perf = win?.performance;\n if (!perf?.getEntriesByType) return undefined;\n let entry: PerformanceNavigationTiming | undefined;\n try {\n const entries = perf.getEntriesByType('navigation') as PerformanceNavigationTiming[];\n entry = entries[0];\n } catch {\n return undefined;\n }\n if (!entry) return undefined;\n // `startTime` is in PerformanceEntry but TS sometimes types it as\n // `number` and sometimes the test mock omits it; treat as 0 when missing.\n const start = (entry as PerformanceNavigationTiming & { startTime?: number }).startTime ?? 0;\n const out: NonNullable<MushiEnvironment['pageLoadTiming']> = {};\n // `loadEventEnd === 0` while the page is still loading — only report\n // it once it's actually fired so a fresh capture during page load\n // doesn't claim \"load completed in 0ms\".\n if (entry.domContentLoadedEventEnd > 0)\n out.domContentLoadedMs = Math.round(entry.domContentLoadedEventEnd - start);\n if (entry.loadEventEnd > 0) out.loadCompleteMs = Math.round(entry.loadEventEnd - start);\n if (entry.responseStart > 0) out.timeToFirstByteMs = Math.round(entry.responseStart - start);\n if (typeof entry.type === 'string') out.navigationType = entry.type;\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\ninterface NetworkInformation {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n}\n\ninterface NavigatorWithConnection extends Navigator {\n connection?: NetworkInformation;\n}\n\ninterface NavigatorWithDeviceMemory extends Navigator {\n deviceMemory?: number;\n}\n","const STORAGE_KEY = 'mushi_reporter_token';\n\nexport function getReporterToken(): string {\n if (typeof localStorage !== 'undefined') {\n const existing = localStorage.getItem(STORAGE_KEY);\n if (existing) return existing;\n }\n\n const token = generateToken();\n\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(STORAGE_KEY, token);\n } catch {\n // localStorage full or unavailable — token is ephemeral\n }\n }\n\n return token;\n}\n\nfunction generateToken(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return `mushi_${crypto.randomUUID()}`;\n }\n\n const bytes = new Uint8Array(16);\n if (typeof crypto !== 'undefined') {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `mushi_${hex}`;\n}\n","/**\n * RFC-4122 v4 UUID generator with a capability ladder so it works in every\n * runtime a Mushi SDK ships to:\n *\n * 1. `crypto.randomUUID()` — browsers (secure context), Node 19+, Deno\n * 2. `crypto.getRandomValues()` — older browsers, RN with a crypto polyfill\n * 3. `Math.random()` — Hermes / JSC without a crypto polyfill\n *\n * Why this exists: report ids are written to the `reports.id uuid` column on\n * the backend. SDKs that minted ad-hoc ids (`rn-<ts>-<rand>`, `mushi_<hex>`)\n * failed the Postgres uuid cast (22P02) and the report was silently dropped\n * (Sentry MUSHI-MUSHI-SERVER-D). Emitting a well-formed UUID at the source\n * keeps the value valid end-to-end.\n *\n * A report id is an identifier, not a secret. The `Math.random` fallback only\n * affects collision odds — negligible at our volume, and the backend dedupes\n * on the `reports` primary key regardless — so we never throw just because a\n * runtime lacks a CSPRNG.\n */\nexport function newUuid(): string {\n const c = typeof crypto !== 'undefined' ? crypto : undefined;\n if (c?.randomUUID) {\n return c.randomUUID();\n }\n\n const bytes = new Uint8Array(16);\n if (c?.getRandomValues) {\n c.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n // Pin version (4) and variant (10xx) bits per RFC 4122 §4.4.\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\n}\n","/**\n * §3c — stable device fingerprint hash.\n *\n * Hashes a deliberately small set of long-lived device characteristics so\n * the same browser keeps the same hash across sessions, but moving to a\n * new browser/device produces a different one. This lets the server\n * detect cross-account abuse (same hash → many reporter accounts) without\n * needing fingerprint.js or any other entropy-heavy library.\n *\n * Privacy notes:\n * - We never send the raw inputs, only the SHA-256 hex digest.\n * - The set is intentionally low-entropy on purpose; this is \"is this the\n * same device\" not \"who is this user\". For high-stakes anti-fraud you\n * should still combine with server-side IP/geo signals.\n * - Cached in localStorage so subsequent calls are zero-cost.\n */\n\nconst CACHE_KEY = 'mushi_fingerprint_hash';\n\ninterface FingerprintInputs {\n userAgent: string;\n platform: string;\n language: string;\n timezone: string;\n screenWidth: number;\n screenHeight: number;\n pixelRatio: number;\n deviceMemory: number | undefined;\n hardwareConcurrency: number | undefined;\n}\n\nfunction collectInputs(): FingerprintInputs {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined;\n const scr = typeof screen !== 'undefined' ? screen : undefined;\n const win = typeof window !== 'undefined' ? window : undefined;\n return {\n userAgent: nav?.userAgent ?? 'unknown',\n platform: nav?.platform ?? 'unknown',\n language: nav?.language ?? 'en',\n timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? 'UTC',\n screenWidth: scr?.width ?? 0,\n screenHeight: scr?.height ?? 0,\n pixelRatio: win?.devicePixelRatio ?? 1,\n deviceMemory: (nav as NavigatorWithDeviceMemory | undefined)?.deviceMemory,\n hardwareConcurrency: nav?.hardwareConcurrency,\n };\n}\n\ninterface NavigatorWithDeviceMemory extends Navigator {\n deviceMemory?: number;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const buf = new TextEncoder().encode(input);\n const digest = await crypto.subtle.digest('SHA-256', buf);\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n // Fallback (Node 18+ test envs, very old browsers): non-cryptographic but\n // good enough for the \"are these two requests from the same device\" use\n // case the server makes of this value.\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (hash << 5) - hash + input.charCodeAt(i);\n hash |= 0;\n }\n return `fbk_${(hash >>> 0).toString(16).padStart(8, '0')}`;\n}\n\n/**\n * Returns a stable per-device hash. Cached in localStorage; first call is\n * one SHA-256, subsequent calls are a localStorage read.\n *\n * Returns `null` outside browser-like environments (SSR, web workers\n * without crypto.subtle) so callers can omit the field gracefully.\n */\nexport async function getDeviceFingerprintHash(): Promise<string | null> {\n if (typeof localStorage !== 'undefined') {\n const cached = localStorage.getItem(CACHE_KEY);\n if (cached) return cached;\n }\n\n const inputs = collectInputs();\n const serialised = JSON.stringify(inputs);\n const hash = await sha256Hex(serialised);\n\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(CACHE_KEY, hash);\n } catch {\n // localStorage quota / private mode — caller still gets the hash.\n }\n }\n return hash;\n}\n\n/** Test/diagnostic helper — never include in shipped reports. */\nexport function _resetFingerprintCacheForTests(): void {\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.removeItem(CACHE_KEY);\n } catch {\n // ignore\n }\n }\n}\n","const SESSION_KEY = 'mushi_session_id';\n\nlet cachedSessionId: string | null = null;\n\nexport function getSessionId(): string {\n if (cachedSessionId) return cachedSessionId;\n\n if (typeof sessionStorage !== 'undefined') {\n const existing = sessionStorage.getItem(SESSION_KEY);\n if (existing) {\n cachedSessionId = existing;\n return existing;\n }\n }\n\n const id = generateSessionId();\n cachedSessionId = id;\n\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(SESSION_KEY, id);\n } catch {\n // sessionStorage unavailable\n }\n }\n\n return id;\n}\n\nfunction generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `ms_${timestamp}_${random}`;\n}\n","export interface RateLimiterConfig {\n maxBurst?: number;\n refillRate?: number;\n refillIntervalMs?: number;\n}\n\nexport interface RateLimiter {\n tryConsume(): boolean;\n reset(): void;\n availableTokens(): number;\n}\n\nconst DEFAULT_MAX_BURST = 10;\nconst DEFAULT_REFILL_RATE = 1;\nconst DEFAULT_REFILL_INTERVAL_MS = 5_000;\n\nexport function createRateLimiter(config: RateLimiterConfig = {}): RateLimiter {\n const {\n maxBurst = DEFAULT_MAX_BURST,\n refillRate = DEFAULT_REFILL_RATE,\n refillIntervalMs = DEFAULT_REFILL_INTERVAL_MS,\n } = config;\n\n let tokens = maxBurst;\n let lastRefill = Date.now();\n\n function refill() {\n const now = Date.now();\n const elapsed = now - lastRefill;\n const refills = Math.floor(elapsed / refillIntervalMs);\n if (refills > 0) {\n tokens = Math.min(maxBurst, tokens + refills * refillRate);\n lastRefill = now;\n }\n }\n\n function tryConsume(): boolean {\n refill();\n if (tokens > 0) {\n tokens--;\n return true;\n }\n return false;\n }\n\n function reset(): void {\n tokens = maxBurst;\n lastRefill = Date.now();\n }\n\n function availableTokens(): number {\n refill();\n return tokens;\n }\n\n return { tryConsume, reset, availableTokens };\n}\n","export interface PiiScrubberConfig {\n emails?: boolean;\n phones?: boolean;\n creditCards?: boolean;\n ssns?: boolean;\n ipAddresses?: boolean;\n /**\n * Scrub vendor-shaped secret tokens (AWS access keys, Stripe keys,\n * Slack/GitHub PATs, OpenAI/Anthropic/Google keys, JWTs).\n *\n * Wave S1 / D-15: SDK parity with the server-side scrubber. The server\n * scrubs these on every LLM invocation; the SDK now scrubs them at\n * capture so they never hit the wire in the first place — important for\n * users who `console.log(stripeKey)` during dev and later ship bug\n * reports with the error text attached.\n */\n secretTokens?: boolean;\n /** IPv6 addresses. Defaults off for the same reason IPv4 does. */\n ipv6?: boolean;\n}\n\ninterface PiiPattern {\n key: keyof PiiScrubberConfig;\n regex: RegExp;\n replacement: string;\n}\n\n// Order matters: SSN → CC → vendor secrets → email → phone → IP. Secret\n// tokens are matched *before* the generic email/phone regex because some JWT\n// payloads contain `.` that could be mis-parsed as `xyz.abc.com`.\nconst ORDERED_PATTERNS: PiiPattern[] = [\n { key: 'ssns', regex: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, replacement: '[REDACTED_SSN]' },\n { key: 'creditCards', regex: /\\b(?:\\d[ -]*){12,18}\\d\\b/g, replacement: '[REDACTED_CC]' },\n\n // Vendor secret tokens — mirrors packages/server/.../pii-scrubber.ts exactly.\n { key: 'secretTokens', regex: /\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, replacement: '[REDACTED_AWS_KEY]' },\n { key: 'secretTokens', regex: /(?:aws_secret_access_key|secret_access_key)[\"'\\s:=]+[A-Za-z0-9/+=]{40}\\b/gi, replacement: 'aws_secret_access_key=[REDACTED_AWS_SECRET]' },\n { key: 'secretTokens', regex: /\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\\b/g, replacement: '[REDACTED_STRIPE_KEY]' },\n { key: 'secretTokens', regex: /\\bpk_(?:live|test)_[A-Za-z0-9]{24,}\\b/g, replacement: '[REDACTED_STRIPE_PK]' },\n { key: 'secretTokens', regex: /\\bxox[abpor]-[A-Za-z0-9-]{10,}\\b/g, replacement: '[REDACTED_SLACK_TOKEN]' },\n { key: 'secretTokens', regex: /\\bghp_[A-Za-z0-9]{36}\\b/g, replacement: '[REDACTED_GITHUB_PAT]' },\n { key: 'secretTokens', regex: /\\bgithub_pat_[A-Za-z0-9_]{80,}\\b/g, replacement: '[REDACTED_GITHUB_PAT]' },\n { key: 'secretTokens', regex: /\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b/g, replacement: '[REDACTED_OPENAI_KEY]' },\n { key: 'secretTokens', regex: /\\bsk-ant-[A-Za-z0-9_-]{20,}\\b/g, replacement: '[REDACTED_ANTHROPIC_KEY]' },\n { key: 'secretTokens', regex: /\\bAIza[0-9A-Za-z_-]{35}\\b/g, replacement: '[REDACTED_GOOGLE_KEY]' },\n { key: 'secretTokens', regex: /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g, replacement: '[REDACTED_JWT]' },\n\n { key: 'emails', regex: /\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b/g, replacement: '[REDACTED_EMAIL]' },\n { key: 'phones', regex: /(?:\\+\\d{1,3}[\\s.-])?\\(?\\d{2,4}\\)?[\\s.-]\\d{3,4}[\\s.-]\\d{3,4}\\b/g, replacement: '[REDACTED_PHONE]' },\n { key: 'ipAddresses', regex: /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g, replacement: '[REDACTED_IP]' },\n { key: 'ipv6', regex: /\\b(?:[A-Fa-f0-9]{1,4}:){2,7}[A-Fa-f0-9]{0,4}\\b/g, replacement: '[REDACTED_IPV6]' },\n];\n\nconst DEFAULT_CONFIG: PiiScrubberConfig = {\n emails: true,\n phones: true,\n creditCards: true,\n ssns: true,\n ipAddresses: false,\n // Secret tokens default ON — if they leak into a bug report there's no\n // good reason to ship them to our servers. Cheaper to scrub client-side.\n secretTokens: true,\n ipv6: false,\n};\n\nexport function createPiiScrubber(config: PiiScrubberConfig = {}) {\n const merged = { ...DEFAULT_CONFIG, ...config };\n\n const activePatterns = ORDERED_PATTERNS.filter((p) => merged[p.key]);\n\n function scrub(text: string): string {\n if (!text) return text;\n let result = text;\n for (const { regex, replacement } of activePatterns) {\n result = result.replace(new RegExp(regex.source, regex.flags), replacement);\n }\n return result;\n }\n\n function scrubObject<T extends Record<string, unknown>>(obj: T, keys: string[]): T {\n const copy = { ...obj };\n for (const key of keys) {\n if (typeof copy[key] === 'string') {\n (copy as Record<string, unknown>)[key] = scrub(copy[key] as string);\n }\n }\n return copy;\n }\n\n return { scrub, scrubObject };\n}\n\nexport function scrubPii(text: string, config?: PiiScrubberConfig): string {\n return createPiiScrubber(config).scrub(text);\n}\n","import type { MushiBreadcrumb } from './types';\n\n/**\n * Ring-buffer breadcrumb store. Capped at `max` entries (default 50);\n * once full, every new add evicts the oldest. We deliberately don't\n * use a Map — order matters and is the only thing we ever read, so a\n * plain array we slice-copy on snapshot is the right shape.\n *\n * Design notes:\n * - `add()` is O(1) on the steady-state hot path (just `push`). When\n * we hit `max` we evict the oldest with `shift()` — that's O(n)\n * in the worst case, but with `max=50` the constant is tiny and\n * it only fires once per insert past the cap. We deliberately\n * append-then-shift (rather than head-insert) so `getAll()` can\n * return the underlying array in oldest-first order without an\n * extra reverse copy on every snapshot.\n * - `getAll()` returns a *copy* so callers can't mutate the buffer\n * after a report is composed. Reports send the snapshot, not the\n * live ring.\n * - Long messages are truncated at 500 chars *at insert time*\n * because a runaway log line shouldn't push useful breadcrumbs\n * out of the buffer just by virtue of taking the whole entry.\n * - PII concerns: this buffer is intentionally *not* scrubbed at\n * insert time — `getBreadcrumbs()` should return the host's own\n * values verbatim so they're useful for in-app debugging. The\n * scrubbing pass runs at *report-snapshot time* in\n * `packages/web/src/mushi.ts`, applying the same `createPiiScrubber()`\n * used on `description` to every breadcrumb message + every string\n * field in `data`. That way emails / Stripe keys / JWTs in a\n * breadcrumb never leave the SDK process.\n */\nexport interface BreadcrumbBuffer {\n /** Append a single breadcrumb; auto-fills `timestamp` when omitted. */\n add(crumb: Omit<MushiBreadcrumb, 'timestamp'> & { timestamp?: number }): void;\n /** Return a copy of every retained breadcrumb, oldest first. */\n getAll(): MushiBreadcrumb[];\n /** Drop every entry. Useful for tests and `Mushi.destroy()`. */\n clear(): void;\n /** Number of entries currently held. */\n size(): number;\n}\n\nexport interface BreadcrumbBufferOptions {\n /** Hard cap on retained entries. Default 50. */\n max?: number;\n /** Hard cap on `message` length, in chars. Default 500. */\n maxMessageLength?: number;\n}\n\nconst DEFAULT_MAX = 50;\nconst DEFAULT_MAX_MESSAGE = 500;\n\nexport function createBreadcrumbBuffer(options: BreadcrumbBufferOptions = {}): BreadcrumbBuffer {\n const max = Math.max(1, options.max ?? DEFAULT_MAX);\n const maxMsg = Math.max(50, options.maxMessageLength ?? DEFAULT_MAX_MESSAGE);\n let entries: MushiBreadcrumb[] = [];\n\n return {\n add(input) {\n const ts = typeof input.timestamp === 'number' ? input.timestamp : Date.now();\n const message =\n typeof input.message === 'string' && input.message.length > maxMsg\n ? `${input.message.slice(0, maxMsg)}…`\n : input.message;\n const crumb: MushiBreadcrumb = {\n timestamp: ts,\n category: input.category,\n level: input.level ?? 'info',\n message: message ?? '',\n ...(input.data ? { data: input.data } : {}),\n };\n entries.push(crumb);\n // Evict the oldest entries when we're over the cap. Done in a\n // loop instead of `entries = entries.slice(-max)` so we don't\n // allocate a fresh array on every add when the buffer is at the\n // steady-state cap (the common case in long-lived sessions).\n while (entries.length > max) entries.shift();\n },\n\n getAll() {\n return entries.slice();\n },\n\n clear() {\n entries = [];\n },\n\n size() {\n return entries.length;\n },\n };\n}\n","/**\n * Normalise *anything* a host might throw — `Error`, string, plain\n * object, `null`, frozen DOMException — into the shape Mushi reports\n * use. Mirrors Sentry's own internal normaliser; lets `captureException`\n * be a thin sugar layer over `captureEvent`.\n *\n * Truncates the stack at 8 KB so a runaway long stack (recursive React\n * render error during a hot reload, for example) doesn't blow the\n * description budget when callers fall back to the stack as the body.\n */\nexport interface NormalisedException {\n name: string;\n message: string;\n stack?: string;\n cause?: unknown;\n}\n\nconst STACK_LIMIT = 8 * 1024;\nconst FALLBACK_JSON_LIMIT = 1000;\n\nexport function normaliseThrown(thrown: unknown): NormalisedException {\n if (thrown instanceof Error) {\n const name = thrown.name || 'Error';\n const message = thrown.message || String(thrown);\n const stack =\n typeof thrown.stack === 'string' && thrown.stack.length > 0\n ? thrown.stack.slice(0, STACK_LIMIT)\n : undefined;\n const cause = (thrown as { cause?: unknown }).cause;\n return {\n name,\n message,\n ...(stack ? { stack } : {}),\n ...(cause !== undefined\n ? { cause: cause instanceof Error ? cause.message : cause }\n : {}),\n };\n }\n if (typeof thrown === 'string') {\n return { name: 'Error', message: thrown };\n }\n if (thrown && typeof thrown === 'object') {\n const obj = thrown as Record<string, unknown>;\n const name = typeof obj.name === 'string' ? obj.name : 'Error';\n const message =\n typeof obj.message === 'string'\n ? obj.message\n : (() => {\n try {\n return JSON.stringify(obj).slice(0, FALLBACK_JSON_LIMIT);\n } catch {\n return String(obj);\n }\n })();\n const stack = typeof obj.stack === 'string' ? obj.stack.slice(0, STACK_LIMIT) : undefined;\n return { name, message, ...(stack ? { stack } : {}) };\n }\n // `String(null)` → `\"null\"`, `String(undefined)` → `\"undefined\"`.\n // We special-case `undefined` to read as \"unknown\" because that's\n // how it shows up in the most common case (a `throw` without an\n // argument, or `Promise.reject()`).\n if (thrown === undefined) return { name: 'Error', message: 'unknown' };\n return { name: 'Error', message: String(thrown) };\n}\n","/**\n * FILE: packages/core/src/design-tokens.ts\n * PURPOSE: The single cross-platform source of truth for Mushi widget design.\n *\n * Every platform SDK (web Shadow-DOM CSS, React Native components, Capacitor\n * native sheet) reads its colours, spacing, radii, typography, z-index scale,\n * motion, launcher geometry, and default copy from this module so the widget\n * renders coherently everywhere. `@mushi-mushi/core` is already a dependency\n * of every platform package, which is why the tokens live here rather than in\n * a separate published package — one import path, no extra build wiring.\n *\n * Colour values mirror the historical washi/vermillion palette previously\n * inlined in `@mushi-mushi/web`'s styles.ts so the visual identity is\n * unchanged; the difference is that RN and Capacitor now share the exact\n * same constants instead of re-deriving their own.\n */\n\nexport type MushiThemeMode = 'light' | 'dark';\n\nexport interface MushiColorPalette {\n /** washi cream / dark wash — primary surface */\n paper: string;\n /** elevated surface (panels, sheets) */\n paperRaised: string;\n /** sumi black / cream type — primary text */\n ink: string;\n /** captions, descriptions */\n inkMuted: string;\n /** disabled, separators */\n inkFaint: string;\n /** dim text */\n inkDim: string;\n /** hairline rules */\n rule: string;\n /** stronger rules / borders */\n ruleStrong: string;\n /** 朱 hanko red — signature accent */\n accent: string;\n /** ~8–12% accent wash */\n accentWash: string;\n /** accessible text on the accent wash */\n accentInk: string;\n /** success */\n ok: string;\n /** danger / destructive */\n danger: string;\n}\n\n/** Light-mode palette. */\nexport const MUSHI_COLORS_LIGHT: MushiColorPalette = {\n paper: '#F8F4ED',\n paperRaised: '#FFFFFF',\n ink: '#0E0D0B',\n inkMuted: '#5C5852',\n inkFaint: '#9A9489',\n inkDim: '#6E6760',\n rule: 'rgba(14,13,11,0.10)',\n ruleStrong: 'rgba(14,13,11,0.16)',\n accent: '#E03C2C',\n accentWash: 'rgba(224,60,44,0.08)',\n accentInk: '#7A1F15',\n ok: '#16A34A',\n danger: '#DC2626',\n};\n\n/** Dark-mode palette. */\nexport const MUSHI_COLORS_DARK: MushiColorPalette = {\n paper: '#0F0E0C',\n paperRaised: '#1A1815',\n ink: '#F2EBDD',\n inkMuted: '#928B7E',\n inkFaint: '#5A5650',\n inkDim: '#7A7268',\n rule: 'rgba(242,235,221,0.10)',\n ruleStrong: 'rgba(242,235,221,0.18)',\n accent: '#FF5A47',\n accentWash: 'rgba(255,90,71,0.12)',\n accentInk: '#FFE5E0',\n ok: '#4ADE80',\n danger: '#F87171',\n};\n\n/** Resolve the palette for a theme mode. */\nexport function mushiPalette(mode: MushiThemeMode): MushiColorPalette {\n return mode === 'dark' ? MUSHI_COLORS_DARK : MUSHI_COLORS_LIGHT;\n}\n\n/**\n * Spacing scale (px). Named by feel, matching the editorial design system so\n * the same rhythm reads across web and native.\n */\nexport const MUSHI_SPACING = {\n hairline: 2,\n tight: 4,\n snug: 8,\n comfy: 12,\n roomy: 16,\n lounge: 20,\n open: 24,\n wide: 32,\n} as const;\n\n/** Corner radii (px). Tables/strips stay sharp; controls get soft corners. */\nexport const MUSHI_RADIUS = {\n none: 0,\n control: 4,\n card: 10,\n sheet: 16,\n pill: 999,\n} as const;\n\n/** Typography stacks shared by every platform (system-first, no web-font fetch). */\nexport const MUSHI_TYPE = {\n fontDisplay: `'Iowan Old Style', 'Palatino Linotype', 'Palatino', 'Book Antiqua', 'Cambria', Georgia, 'Times New Roman', serif`,\n fontBody: `system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Display', 'Segoe UI', sans-serif`,\n fontMono: `ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, 'Liberation Mono', monospace`,\n sizeBody: 14,\n sizeLabel: 12,\n sizeTitle: 16,\n lineBody: 1.55,\n} as const;\n\n/**\n * z-index scale. The host element is pass-through; only interactive surfaces\n * opt back into pointer events. Banner sits just under the FAB; panel above.\n */\nexport const MUSHI_Z = {\n base: 99999,\n /** banner sits one below the trigger so an open FAB overlaps it */\n banner: 99998,\n /** report/assistant panel sits one above the trigger */\n panel: 100000,\n /** element-selector overlay — always on top */\n overlay: 2147483647,\n} as const;\n\n/** Motion signature — a soft back-out \"stamp press\". */\nexport const MUSHI_MOTION = {\n easeStamp: 'cubic-bezier(0.22, 1, 0.36, 1)',\n durationFast: 200,\n durationPanel: 300,\n} as const;\n\n/**\n * Launcher geometry — the numbers that previously diverged between platforms\n * (banner height, FAB size, default gutter, panel width). Centralising them\n * is what fixes the \"different on every app\" + safe-area bleed problems.\n */\nexport const MUSHI_GEOMETRY = {\n bannerHeight: 36,\n fabSize: 52,\n edgeTabWidth: 28,\n /** default gutter from the screen edge (added on top of safe-area insets) */\n gutter: 24,\n panelWidth: 384,\n /** below this viewport width the panel becomes a full-width bottom sheet */\n panelSheetBreakpoint: 480,\n} as const;\n\n/**\n * Default user-facing copy. Centralised so apps stop drifting on the banner\n * label / CTA wording (seen as inconsistent across the four host apps).\n */\nexport const MUSHI_COPY = {\n bannerLabel: 'Beta',\n bannerMessage: 'Help us improve — your feedback shapes what we ship.',\n bugCta: 'Report a bug',\n featureCta: 'Feature request',\n triggerText: '🐛',\n panelTitle: 'Send feedback',\n myReportsTab: 'My reports',\n assistantTab: 'Ask',\n} as const;\n\n/** A flat, serialisable snapshot of every token for a given theme mode. */\nexport interface MushiTokenSnapshot {\n mode: MushiThemeMode;\n colors: MushiColorPalette;\n spacing: typeof MUSHI_SPACING;\n radius: typeof MUSHI_RADIUS;\n type: typeof MUSHI_TYPE;\n z: typeof MUSHI_Z;\n motion: typeof MUSHI_MOTION;\n geometry: typeof MUSHI_GEOMETRY;\n copy: typeof MUSHI_COPY;\n}\n\n/** Build a full token snapshot for a theme mode (used by RN/Capacitor). */\nexport function mushiTokens(mode: MushiThemeMode): MushiTokenSnapshot {\n return {\n mode,\n colors: mushiPalette(mode),\n spacing: MUSHI_SPACING,\n radius: MUSHI_RADIUS,\n type: MUSHI_TYPE,\n z: MUSHI_Z,\n motion: MUSHI_MOTION,\n geometry: MUSHI_GEOMETRY,\n copy: MUSHI_COPY,\n };\n}\n","/**\n * FILE: packages/core/src/identity.ts\n * PURPOSE: The signed-JWT end-user identity contract shared between the SDK\n * and the Mushi backend.\n *\n * The host app's server mints a short-lived JWT (HS256, signed with the\n * project's identity secret obtained from the console) describing the\n * currently-logged-in end user, and hands it to the SDK via\n * `Mushi.identifyWithToken(jwt)`. The SDK never verifies the signature — it\n * only base64url-decodes the payload to show the user's name locally and\n * forwards the raw token to the backend, which verifies it against the\n * per-project secret before trusting any claim. This mirrors the Featurebase\n * `featurebaseJwt` model and is the trust anchor for \"My Reports\", rewards,\n * and the per-user assistant data index.\n *\n * Anonymous reporters (logged-out) keep using the random reporter token; the\n * signed JWT is purely additive.\n */\n\n/** Claims carried by a Mushi end-user identity token. */\nexport interface MushiIdentityClaims {\n /** Mushi external project id this token is scoped to. */\n projectId: string;\n /** The host app's stable id for this end user (becomes `external_user_id`). */\n sub: string;\n /** Optional display email (never stored raw server-side — hashed). */\n email?: string;\n /** Optional display name. */\n name?: string;\n /** Issued-at (seconds since epoch). */\n iat?: number;\n /** Expiry (seconds since epoch). Tokens should be short-lived (<= 1h). */\n exp?: number;\n}\n\n/**\n * Sentinel so callers can distinguish a Mushi identity token from the random\n * anonymous reporter token (`mushi_<uuid>`). Identity tokens are standard JWTs\n * (three dot-separated base64url segments), so this prefix is informational\n * only and not embedded in the wire format.\n */\nexport const MUSHI_IDENTITY_TOKEN_PREFIX = 'mushi.identity';\n\n/**\n * Build the canonical claims object a host server should sign. Exposed so the\n * `@mushi-mushi/node` SDK and docs share one definition of the payload shape.\n */\nexport function buildIdentityClaims(input: {\n projectId: string;\n userId: string;\n email?: string;\n name?: string;\n ttlSeconds?: number;\n}): Required<Pick<MushiIdentityClaims, 'projectId' | 'sub' | 'iat' | 'exp'>> &\n Pick<MushiIdentityClaims, 'email' | 'name'> {\n const now = Math.floor(Date.now() / 1000);\n const ttl = input.ttlSeconds && input.ttlSeconds > 0 ? Math.min(input.ttlSeconds, 3600) : 600;\n return {\n projectId: input.projectId,\n sub: input.userId,\n ...(input.email ? { email: input.email } : {}),\n ...(input.name ? { name: input.name } : {}),\n iat: now,\n exp: now + ttl,\n };\n}\n\nfunction base64UrlDecode(segment: string): string {\n const pad = segment.length % 4 === 0 ? '' : '='.repeat(4 - (segment.length % 4));\n const base64 = segment.replace(/-/g, '+').replace(/_/g, '/') + pad;\n if (typeof atob === 'function') return atob(base64);\n // Node / RN without atob\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const B = (globalThis as any).Buffer;\n if (B) return B.from(base64, 'base64').toString('binary');\n return '';\n}\n\n/**\n * Decode (WITHOUT verifying) the claims of an identity JWT. Returns null if the\n * token is malformed. CLIENT-SIDE DISPLAY ONLY — never trust these claims for\n * authorisation; the server re-verifies the signature.\n */\nexport function parseIdentityToken(token: string): MushiIdentityClaims | null {\n if (typeof token !== 'string') return null;\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n try {\n const json = base64UrlDecode(parts[1]);\n const payload = JSON.parse(json) as Record<string, unknown>;\n const projectId = typeof payload.projectId === 'string' ? payload.projectId : undefined;\n const sub = typeof payload.sub === 'string' ? payload.sub : undefined;\n if (!projectId || !sub) return null;\n return {\n projectId,\n sub,\n ...(typeof payload.email === 'string' ? { email: payload.email } : {}),\n ...(typeof payload.name === 'string' ? { name: payload.name } : {}),\n ...(typeof payload.iat === 'number' ? { iat: payload.iat } : {}),\n ...(typeof payload.exp === 'number' ? { exp: payload.exp } : {}),\n };\n } catch {\n return null;\n }\n}\n","/**\n * Shared favicon resolution helpers for admin console and SDK widget.\n */\n\nexport interface ProjectFaviconSource {\n project_id: string;\n project_name: string;\n project_slug: string;\n /** Operator override — wins over inferred domain when set. */\n icon_url?: string | null;\n /** e.g. https://kensaur.us — from SDK heartbeat or API key last_seen_origin */\n sdk_origin?: string | null;\n /** Connected GitHub/GitLab repo — used when SDK has not heartbeated yet. */\n repo_url?: string | null;\n}\n\n/**\n * Hosts that serve many dogfood apps under one favicon — skip for icon lookup\n * so we prefer slug/repo-specific domains or initials instead of one shared globe.\n */\nconst MULTI_TENANT_PARENT_HOSTS = new Set(['kensaur.us', 'www.kensaur.us']);\n\n/**\n * Slug → canonical production domain. Use app-specific TLDs, not shared parents.\n * Native-only apps (yen-yen) intentionally omitted — initials fallback is clearer.\n */\nconst SLUG_DOMAIN_HINTS: Record<string, string> = {\n 'glot-it': 'glot.it',\n glotit: 'glot.it',\n 'solo-boss-cloud': 'sbc-front.vercel.app',\n 'mushi-mushi': 'mushimushi.dev',\n};\n\n/**\n * Verified absolute favicon URLs for dogfood projects whose TLD blocks /favicon.*\n * or serves a shared parent icon. Playwright-checked Jun 2026.\n */\nconst SLUG_ICON_URL_HINTS: Record<string, string> = {\n 'mushi-mushi': 'https://kensaur.us/mushi-mushi/admin/favicon.svg',\n 'solo-boss-cloud': 'https://sbc-front.vercel.app/favicon.svg',\n 'glot-it': 'https://kensaur.us/glot-it/apple-touch-icon.png',\n glotit: 'https://kensaur.us/glot-it/apple-touch-icon.png',\n};\n\n/** Third-party favicon CDNs — return HTTP 200 generic globes; never use as fallbacks. */\nconst UNTRUSTED_FAVICON_HOSTS = [\n 'www.google.com',\n 'icons.duckduckgo.com',\n 'icon.horse',\n] as const;\n\nexport function isUntrustedFaviconUrl(url: string): boolean {\n try {\n const host = new URL(url).hostname.toLowerCase();\n return UNTRUSTED_FAVICON_HOSTS.some((h) => host === h || host.endsWith(`.${h}`));\n } catch {\n return false;\n }\n}\n\n/** Per-domain favicon URLs — first-party assets only (no CDN globes). */\nexport function faviconUrlCandidates(domain: string, _size = 32): string[] {\n return [\n `https://${domain}/favicon.svg`,\n `https://${domain}/favicon.ico`,\n `https://${domain}/favicon-32x32.png`,\n `https://${domain}/apple-touch-icon.png`,\n ];\n}\n\n/** Ordered unique domains to try for a project (most specific first). */\nexport function resolveProjectFaviconDomains(source: ProjectFaviconSource): string[] {\n const out: string[] = [];\n const add = (d: string | null | undefined) => {\n const n = d?.trim().toLowerCase();\n if (!n || out.includes(n)) return;\n out.push(n);\n };\n\n add(githubRepoDomainHint(source.repo_url));\n add(SLUG_DOMAIN_HINTS[source.project_slug.toLowerCase()]);\n\n const fromOrigin = source.sdk_origin ? originToDomain(source.sdk_origin) : null;\n if (fromOrigin && !MULTI_TENANT_PARENT_HOSTS.has(fromOrigin)) {\n add(fromOrigin);\n }\n\n return out;\n}\n\n/** Flat URL list across all candidate domains for a project. */\nexport function projectFaviconUrlCandidates(source: ProjectFaviconSource, size = 32): string[] {\n if (source.icon_url?.trim()) return [source.icon_url.trim()];\n const seen = new Set<string>();\n const urls: string[] = [];\n const push = (url: string) => {\n if (!url || seen.has(url) || isUntrustedFaviconUrl(url)) return;\n seen.add(url);\n urls.push(url);\n };\n\n const slugHint = SLUG_ICON_URL_HINTS[source.project_slug.toLowerCase()];\n if (slugHint) push(slugHint);\n\n for (const domain of resolveProjectFaviconDomains(source)) {\n for (const url of faviconUrlCandidates(domain, size)) {\n push(url);\n }\n }\n return urls;\n}\n\nexport function originToDomain(origin: string): string | null {\n const trimmed = origin.trim();\n if (!trimmed) return null;\n if (/^(capacitor|file|content|app):/i.test(trimmed)) return null;\n try {\n const url = new URL(trimmed.includes('://') ? trimmed : `https://${trimmed}`);\n const host = url.hostname.toLowerCase();\n if (host === 'localhost' || host === '127.0.0.1' || host.endsWith('.local')) {\n return null;\n }\n return host;\n } catch {\n return null;\n }\n}\n\n/** Derive a production hostname from a connected repo URL when possible. */\nexport function githubRepoDomainHint(repoUrl: string | null | undefined): string | null {\n if (!repoUrl?.trim()) return null;\n try {\n const u = new URL(repoUrl.trim());\n const host = u.hostname.toLowerCase();\n const parts = u.pathname.replace(/^\\/+|\\/+$/g, '').split('/').filter(Boolean);\n if (parts.length < 2) return null;\n const repo = parts[1]!.replace(/\\.git$/i, '').toLowerCase();\n\n if (/^[a-z0-9][a-z0-9.-]*\\.[a-z]{2,}$/i.test(repo)) return repo;\n\n if (host === 'github.com' && repo.endsWith('.github.io')) return repo;\n\n if (host !== 'github.com' && host !== 'www.github.com') return host;\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Best single domain — first entry from {@link resolveProjectFaviconDomains}. */\nexport function resolveProjectDomain(source: ProjectFaviconSource): string | null {\n return resolveProjectFaviconDomains(source)[0] ?? null;\n}\n\n/**\n * Google's favicon CDN returns HTTP 200 with a gray globe when it has no icon.\n * Treat low-saturation loaded images as \"miss\" so callers try the next URL or initials.\n */\nexport function isLikelyGenericFavicon(img: HTMLImageElement): boolean {\n if (typeof document === 'undefined') return false;\n if (!img.complete || img.naturalWidth === 0 || img.naturalHeight === 0) return false;\n\n try {\n const canvas = document.createElement('canvas');\n const w = img.naturalWidth;\n const h = img.naturalHeight;\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) return false;\n ctx.drawImage(img, 0, 0);\n const { data } = ctx.getImageData(0, 0, w, h);\n let opaque = 0;\n let satSum = 0;\n let maxDiff = 0;\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i]!;\n const g = data[i + 1]!;\n const b = data[i + 2]!;\n const a = data[i + 3]!;\n if (a < 128) continue;\n opaque++;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const diff = max - min;\n maxDiff = Math.max(maxDiff, diff);\n satSum += diff;\n }\n if (opaque === 0) return true;\n const avgSat = satSum / opaque;\n return avgSat < 14 && maxDiff < 24;\n } catch {\n // Cross-origin CDN images taint the canvas — treat as untrusted generic globe.\n return isUntrustedFaviconUrl(img.src);\n }\n}\n\n/** Two-letter initials for favicon fallback chips. */\nexport function projectInitials(name: string): string {\n const parts = name.trim().split(/[\\s._-]+/).filter(Boolean);\n if (parts.length >= 2) {\n return `${parts[0]![0] ?? ''}${parts[1]![0] ?? ''}`.toUpperCase();\n }\n const compact = name.replace(/[^a-zA-Z0-9]/g, '');\n return (compact.slice(0, 2) || name.slice(0, 2) || '?').toUpperCase();\n}\n\nconst INITIALS_CHIP_THEMES = [\n 'info',\n 'brand',\n 'warn',\n 'ok',\n 'accent',\n] as const;\n\n/** Stable theme index (0–4) for initials chip coloring. */\nexport function projectInitialsThemeIndex(projectId: string): number {\n let hash = 0;\n for (let i = 0; i < projectId.length; i++) {\n hash = (hash + projectId.charCodeAt(i)) % INITIALS_CHIP_THEMES.length;\n }\n return hash;\n}\n\n/**\n * Read the host page favicon href (web SDK only).\n *\n * Security: the host page declares this value, so it could be a `data:`,\n * `blob:`, or `javascript:` URL. Since the result is rendered into an\n * `<img src>` inside the widget, only same-trust http(s) (and protocol-relative)\n * URLs are returned; anything else falls back to `null` so the widget renders\n * its default mark instead of an unvalidated, host-controlled resource.\n */\nexport function readPageFaviconHref(): string | null {\n if (typeof document === 'undefined') return null;\n const selectors = [\n 'link[rel=\"icon\"]',\n 'link[rel=\"shortcut icon\"]',\n 'link[rel=\"apple-touch-icon\"]',\n ];\n for (const sel of selectors) {\n const link = document.querySelector<HTMLLinkElement>(sel);\n const href = link?.href;\n if (href && isSafeFaviconHref(href)) return href;\n }\n return null;\n}\n\n/** Allow only http(s) favicon URLs — reject data:/blob:/javascript: etc. */\nfunction isSafeFaviconHref(href: string): boolean {\n try {\n // `link.href` is already resolved to an absolute URL by the DOM; parse with a\n // base for safety in case a raw attribute value is ever passed in.\n const base = typeof location !== 'undefined' ? location.href : undefined;\n const protocol = new URL(href, base).protocol;\n return protocol === 'http:' || protocol === 'https:';\n } catch {\n return false;\n }\n}\n"]}
|