@mushi-mushi/core 1.0.0 → 1.2.0
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 +27 -0
- package/dist/index.cjs +47 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -5
- package/dist/index.d.ts +151 -5
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api-client.ts","../src/region.ts","../src/pre-filter.ts","../src/logger.ts","../src/queue-crypto.ts","../src/queue.ts","../src/environment.ts","../src/reporter-token.ts","../src/fingerprint.ts","../src/session.ts","../src/rate-limiter.ts","../src/pii-scrubber.ts","../src/breadcrumbs.ts","../src/exception-normaliser.ts"],"names":["getBackoffDelay","sleep","sha256Hex"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n MushiApiClient,\n MushiApiResponse,\n MushiReport,\n MushiReportStatus,\n MushiReporterComment,\n MushiReporterReport,\n MushiRuntimeSdkConfig,\n MushiSdkVersionInfo,\n} from './types';\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}\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';\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 } = 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 ): Promise<MushiApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\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 ...(internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {}),\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);\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);\n }\n return {\n ok: false,\n error: {\n code: `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 [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 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 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(reportId: string, reporterToken: string, body: string) {\n return requestForReporter<{ comment: MushiReporterComment }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reply`,\n reporterToken,\n { body },\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","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 /\\b(test|asdf|qwerty|lorem ipsum)\\b/i, // common test strings\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\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\nfunction emit(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\nfunction buildLogger(\n scope: string,\n minLevel: LogLevel,\n baseMeta: Record<string, unknown>,\n formatter: (entry: LogEntry) => string,\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 )\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 } = options\n\n const resolvedFormat = format === 'auto' ? detectFormat() : format\n const formatter = resolvedFormat === 'json' ? formatJson : formatPretty\n\n return buildLogger(scope, level, meta, formatter)\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;\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 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 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 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 // --- 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 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 try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch {\n lsDelete(rowId);\n }\n failed++;\n continue;\n }\n\n const result = await client.submitReport(report);\n\n if (result.ok) {\n try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch {\n lsDelete(rowId);\n }\n sent++;\n } else {\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 handler = () => {\n if (navigator.onLine) {\n flush(client).catch(() => {});\n }\n };\n\n window.addEventListener('online', handler);\n syncCleanup = () => window.removeEventListener('online', handler);\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 * §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"]}
|
|
1
|
+
{"version":3,"sources":["../src/api-client.ts","../src/region.ts","../src/pre-filter.ts","../src/logger.ts","../src/queue-crypto.ts","../src/queue.ts","../src/environment.ts","../src/reporter-token.ts","../src/fingerprint.ts","../src/session.ts","../src/rate-limiter.ts","../src/pii-scrubber.ts","../src/breadcrumbs.ts","../src/exception-normaliser.ts"],"names":["getBackoffDelay","sleep","sha256Hex"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n MushiApiClient,\n MushiApiResponse,\n MushiReport,\n MushiReportStatus,\n MushiReporterComment,\n MushiReporterReport,\n MushiRuntimeSdkConfig,\n MushiSdkVersionInfo,\n MushiTierResult,\n} from './types';\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}\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';\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 } = 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 ): Promise<MushiApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\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 ...(internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {}),\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);\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);\n }\n return {\n ok: false,\n error: {\n code: `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 [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 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 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(reportId: string, reporterToken: string, body: string) {\n return requestForReporter<{ comment: MushiReporterComment }>(\n 'POST',\n `/v1/reporter/reports/${reportId}/reply`,\n reporterToken,\n { body },\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}\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","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 /\\b(test|asdf|qwerty|lorem ipsum)\\b/i, // common test strings\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\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\nfunction emit(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\nfunction buildLogger(\n scope: string,\n minLevel: LogLevel,\n baseMeta: Record<string, unknown>,\n formatter: (entry: LogEntry) => string,\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 )\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 } = options\n\n const resolvedFormat = format === 'auto' ? detectFormat() : format\n const formatter = resolvedFormat === 'json' ? formatJson : formatPretty\n\n return buildLogger(scope, level, meta, formatter)\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;\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 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 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 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 // --- 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 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 try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch {\n lsDelete(rowId);\n }\n failed++;\n continue;\n }\n\n const result = await client.submitReport(report);\n\n if (result.ok) {\n try {\n if (backend === 'indexeddb') await idbDelete(rowId);\n else lsDelete(rowId);\n } catch {\n lsDelete(rowId);\n }\n sent++;\n } else {\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 handler = () => {\n if (navigator.onLine) {\n flush(client).catch(() => {});\n }\n };\n\n window.addEventListener('online', handler);\n syncCleanup = () => window.removeEventListener('online', handler);\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 * §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"]}
|