{"version":3,"sources":["../src/index.ts","../src/normalizer.ts","../src/fingerprint.ts","../src/rate-limiter.ts","../src/github.ts","../src/bug-report.ts","../src/client.ts","../src/screenshot.ts","../src/handler.ts"],"sourcesContent":["export {\n  init,\n  captureException,\n  captureMessage,\n  captureBugReport,\n  flush,\n} from './client'\nexport { fetchIssueImage } from './screenshot'\nexport { withErrorReporting } from './handler'\nexport type { WithErrorReportingOptions } from './handler'\nexport type {\n  ErrorTrackerConfig,\n  ErrorContext,\n  BugReportInput,\n  BugReportResult,\n  BugReportReporter,\n  BugReportScreenshot,\n  FetchIssueImageOptions,\n  FetchIssueImageResult,\n} from './types'\n","/**\n * Stack trace normalizer.\n *\n * Strips volatile parts of stack traces (line/column numbers, webpack hashes,\n * query strings) so that the same logical error produces the same fingerprint\n * across deploys.\n */\n\n/** Strip line:col numbers like `:42:13` at the end of file paths */\nconst LINE_COL_RE = /:\\d+:\\d+/g\n\n/** Strip webpack-internal:/// prefix */\nconst WEBPACK_PREFIX_RE = /webpack-internal:\\/\\/\\//g\n\n/** Strip query strings from file paths like `?abc123` or `?v=hash` */\nconst QUERY_STRING_RE = /\\?[^\\s)]+/g\n\n/** Match stack frame lines (starts with \"at \" after whitespace) */\nconst FRAME_RE = /^\\s+at\\s+/\n\n/** Skip frames from node_modules */\nconst NODE_MODULES_RE = /node_modules/\n\n/**\n * Normalize a stack trace by removing volatile parts.\n * Returns a stable string suitable for hashing.\n */\nexport function normalizeStack(stack: string | undefined): string {\n  if (!stack) return ''\n\n  return stack\n    .replace(WEBPACK_PREFIX_RE, '')\n    .replace(QUERY_STRING_RE, '')\n    .replace(LINE_COL_RE, '')\n}\n\n/**\n * Extract the first N meaningful (non-node_modules) frames from a stack trace.\n * Used for fingerprint generation — only top frames matter for identity.\n */\nexport function extractFrames(stack: string | undefined, maxFrames = 3): string[] {\n  if (!stack) return []\n\n  const lines = stack.split('\\n')\n  const frames: string[] = []\n\n  for (const line of lines) {\n    if (!FRAME_RE.test(line)) continue\n    if (NODE_MODULES_RE.test(line)) continue\n\n    // Normalize the frame before collecting\n    const normalized = line\n      .replace(WEBPACK_PREFIX_RE, '')\n      .replace(QUERY_STRING_RE, '')\n      .replace(LINE_COL_RE, '')\n      .trim()\n\n    frames.push(normalized)\n    if (frames.length >= maxFrames) break\n  }\n\n  return frames\n}\n","/**\n * Error fingerprinting.\n *\n * Produces a deterministic hash from an error's name, message (truncated),\n * and top stack frames. Two occurrences of the \"same\" error — even across\n * different deploys with different line numbers — should produce the same\n * fingerprint.\n *\n * Hashing uses the Web Crypto API (`crypto.subtle`), which is available on\n * every modern runtime — Node 20+, edge functions, Cloudflare Workers, Deno,\n * and browsers — so the tracker has no Node-only dependency and runs anywhere\n * `fetch` does. The algorithm is still SHA-256, so fingerprints are byte-for-byte\n * identical to the previous `node:crypto` implementation (existing issues keep\n * deduping correctly).\n */\n\nimport { extractFrames } from './normalizer'\n\nconst MESSAGE_TRUNCATE_LENGTH = 100\n\n/**\n * Generate a 12-char hex fingerprint from an Error or plain string.\n */\nexport async function generateFingerprint(input: Error | string): Promise<string> {\n  let name: string\n  let message: string\n  let stack: string | undefined\n\n  if (typeof input === 'string') {\n    name = 'Error'\n    message = input\n    stack = undefined\n  } else {\n    name = input.name || 'Error'\n    message = input.message || ''\n    stack = input.stack\n  }\n\n  const truncatedMessage = message.slice(0, MESSAGE_TRUNCATE_LENGTH)\n  const frames = extractFrames(stack)\n  const payload = `${name}\\n${truncatedMessage}\\n${frames.join('\\n')}`\n\n  const hash = await sha256Hex(payload)\n  return hash.slice(0, 12)\n}\n\n/** SHA-256 of a string as lowercase hex, via the Web Crypto API. */\nasync function sha256Hex(input: string): Promise<string> {\n  const bytes = new TextEncoder().encode(input)\n  const digest = await crypto.subtle.digest('SHA-256', bytes)\n  const view = new Uint8Array(digest)\n\n  let hex = ''\n  for (let i = 0; i < view.length; i++) {\n    hex += view[i].toString(16).padStart(2, '0')\n  }\n  return hex\n}\n","/**\n * Rate limiter with deduplication.\n *\n * Two layers of protection:\n * 1. Sliding window: max N issues created per minute\n * 2. Dedup window: suppress the same fingerprint within a configurable period\n */\n\nexport interface RateLimiterConfig {\n  /** Max new issues per minute. */\n  maxPerMinute: number\n  /** Suppress duplicate fingerprints within this window (ms). */\n  dedupeWindowMs: number\n}\n\nconst ONE_MINUTE = 60_000\nconst CLEANUP_INTERVAL = 5 * 60_000 // 5 minutes\n\nexport class RateLimiter {\n  private readonly config: RateLimiterConfig\n  private readonly timestamps: number[] = []\n  private readonly dedup = new Map<string, number>()\n  private cleanupTimer: ReturnType<typeof setInterval> | null = null\n\n  constructor(config: RateLimiterConfig) {\n    this.config = config\n    this.cleanupTimer = setInterval(() => this.cleanup(), CLEANUP_INTERVAL)\n    // Unref so the timer doesn't keep the process alive\n    if (this.cleanupTimer && typeof this.cleanupTimer === 'object' && 'unref' in this.cleanupTimer) {\n      this.cleanupTimer.unref()\n    }\n  }\n\n  /**\n   * Check whether a fingerprint can be processed right now.\n   * Returns false if rate-limited or deduped.\n   */\n  canProcess(fingerprint: string): boolean {\n    const now = Date.now()\n\n    // Check dedup first\n    const lastSeen = this.dedup.get(fingerprint)\n    if (lastSeen !== undefined && now - lastSeen < this.config.dedupeWindowMs) {\n      return false\n    }\n\n    // Check rate limit\n    this.pruneOldTimestamps(now)\n    return this.timestamps.length < this.config.maxPerMinute\n  }\n\n  /**\n   * Record that a fingerprint was processed.\n   * Call this after successfully processing (or starting to process) an error.\n   */\n  recordProcessed(fingerprint: string): void {\n    const now = Date.now()\n    this.timestamps.push(now)\n    this.dedup.set(fingerprint, now)\n  }\n\n  /** Stop the cleanup timer. Call on shutdown. */\n  destroy(): void {\n    if (this.cleanupTimer) {\n      clearInterval(this.cleanupTimer)\n      this.cleanupTimer = null\n    }\n  }\n\n  private pruneOldTimestamps(now: number): void {\n    const cutoff = now - ONE_MINUTE\n    while (this.timestamps.length > 0 && this.timestamps[0]! < cutoff) {\n      this.timestamps.shift()\n    }\n  }\n\n  private cleanup(): void {\n    const now = Date.now()\n    this.pruneOldTimestamps(now)\n\n    for (const [fp, ts] of this.dedup.entries()) {\n      if (now - ts >= this.config.dedupeWindowMs) {\n        this.dedup.delete(fp)\n      }\n    }\n  }\n}\n","/**\n * GitHub API layer for error tracking.\n *\n * A tiny `fetch`-based GitHub REST client — no SDK dependency, so it runs on any\n * runtime with a global `fetch` (Node 20+, edge functions, Cloudflare Workers,\n * Deno). All methods catch errors internally and delegate to `onError`; they\n * never throw, so the tracker can never crash the host application.\n */\n\nimport type { GitHubClient, ExistingIssue, CreatedIssue } from './types'\n\nexport interface GitHubClientConfig {\n  token: string\n  repo: string // \"owner/repo\"\n  onError: (err: unknown) => void\n  /** Create missing labels before filing an issue. Default: true */\n  autoCreateLabels?: boolean\n}\n\nconst API_BASE = 'https://api.github.com'\nconst UPLOADS_BASE = 'https://uploads.github.com'\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024\n\nconst LABEL_COLORS: Record<string, string> = {\n  'error-report': 'B60205',\n  'bug-report': '1D76DB',\n}\n\nfunction colorForLabel(name: string): string {\n  if (LABEL_COLORS[name]) return LABEL_COLORS[name]\n  if (name.startsWith('fingerprint:')) return '5319E7'\n  return 'CCCCCC'\n}\n\nfunction parseRepo(repo: string): { owner: string; repo: string } {\n  const [owner, name] = repo.split('/')\n  if (!owner || !name) {\n    throw new Error(`Invalid repo format \"${repo}\". Expected \"owner/repo\".`)\n  }\n  return { owner, repo: name }\n}\n\nexport function createGitHubClient(config: GitHubClientConfig): GitHubClient {\n  const { owner, repo } = parseRepo(config.repo)\n  const autoCreateLabels = config.autoCreateLabels !== false\n  const ensuredLabels = new Set<string>()\n\n  const headers: Record<string, string> = {\n    Authorization: `Bearer ${config.token}`,\n    Accept: 'application/vnd.github+json',\n    'X-GitHub-Api-Version': '2022-11-28',\n    // GitHub rejects requests without a User-Agent.\n    'User-Agent': 'gh-issue-tracker',\n    'Content-Type': 'application/json',\n  }\n\n  /** Low-level fetch — returns the Response without throwing, for callers that\n   *  need to inspect the status (e.g. a 404 means \"branch missing, create it\"). */\n  function ghFetch(method: string, path: string, body?: unknown): Promise<Response> {\n    return fetch(`${API_BASE}${path}`, {\n      method,\n      headers,\n      body: body === undefined ? undefined : JSON.stringify(body),\n    })\n  }\n\n  /** Fetch + throw on error + parse JSON, for the happy-path calls. */\n  async function request(method: string, path: string, body?: unknown): Promise<unknown> {\n    const res = await ghFetch(method, path, body)\n    if (!res.ok) {\n      const detail = await res.text().catch(() => '')\n      throw new Error(\n        `GitHub ${method} ${path} failed: ${res.status} ${res.statusText}${detail ? ` — ${detail}` : ''}`,\n      )\n    }\n    if (res.status === 204) return null\n    return res.json().catch(() => null)\n  }\n\n  /** Ensure `branch` exists, creating it from the repo's default branch if not. */\n  async function ensureBranch(branch: string): Promise<void> {\n    const head = await ghFetch('GET', `/repos/${owner}/${repo}/git/ref/heads/${branch}`)\n    if (head.ok) return\n    if (head.status !== 404) {\n      throw new Error(`GitHub get ref heads/${branch} failed: ${head.status} ${head.statusText}`)\n    }\n    // Branch doesn't exist yet — branch it off the repo's default branch.\n    const repoInfo = (await request('GET', `/repos/${owner}/${repo}`)) as { default_branch: string }\n    const defRef = (await request(\n      'GET',\n      `/repos/${owner}/${repo}/git/ref/heads/${repoInfo.default_branch}`,\n    )) as { object: { sha: string } }\n    await request('POST', `/repos/${owner}/${repo}/git/refs`, {\n      ref: `refs/heads/${branch}`,\n      sha: defRef.object.sha,\n    })\n  }\n\n  async function ensureLabel(name: string): Promise<void> {\n    if (ensuredLabels.has(name)) return\n    const res = await ghFetch('POST', `/repos/${owner}/${repo}/labels`, {\n      name,\n      color: colorForLabel(name),\n      description: 'Auto-created by gh-issue-tracker',\n    })\n    const detail = await res.text().catch(() => '')\n    if (res.ok || (res.status === 422 && /already_exists/.test(detail))) {\n      ensuredLabels.add(name)\n      return\n    }\n    throw new Error(\n      `GitHub POST /labels failed: ${res.status} ${res.statusText}${detail ? ` — ${detail}` : ''}`,\n    )\n  }\n\n  async function ensureLabels(names: string[]): Promise<void> {\n    for (const name of names) {\n      try {\n        await ensureLabel(name)\n      } catch (err) {\n        config.onError(err)\n      }\n    }\n  }\n\n  function isMissingLabelFailure(status: number, detail: string): boolean {\n    return status === 422 && /Label/.test(detail)\n  }\n\n  let repositoryId: number | undefined\n\n  async function resolveRepositoryId(): Promise<number> {\n    if (repositoryId !== undefined) return repositoryId\n    const info = (await request('GET', `/repos/${owner}/${repo}`)) as { id: number }\n    if (!info?.id) {\n      throw new Error(`GitHub GET /repos/${owner}/${repo} returned no repository id`)\n    }\n    repositoryId = info.id\n    return repositoryId\n  }\n\n  return {\n    async searchExistingIssue(fingerprint: string): Promise<ExistingIssue | null> {\n      try {\n        const query = new URLSearchParams({\n          labels: `fingerprint:${fingerprint}`,\n          state: 'all',\n          per_page: '1',\n        })\n        const data = (await request(\n          'GET',\n          `/repos/${owner}/${repo}/issues?${query.toString()}`,\n        )) as Array<{ number: number; state: string; title: string }> | null\n\n        const issue = data?.[0]\n        if (!issue) return null\n\n        return {\n          number: issue.number,\n          state: issue.state as 'open' | 'closed',\n          title: issue.title,\n        }\n      } catch (err) {\n        config.onError(err)\n        return null\n      }\n    },\n\n    async createIssue(title: string, body: string, labels: string[]): Promise<CreatedIssue | null> {\n      try {\n        if (autoCreateLabels && labels.length > 0) {\n          await ensureLabels(labels)\n        }\n\n        const post = async (issueLabels: string[]): Promise<CreatedIssue> => {\n          const res = await ghFetch('POST', `/repos/${owner}/${repo}/issues`, {\n            title,\n            body,\n            labels: issueLabels,\n          })\n          const detail = await res.text().catch(() => '')\n          if (!res.ok) {\n            const err = new Error(\n              `GitHub POST /issues failed: ${res.status} ${res.statusText}${detail ? ` — ${detail}` : ''}`,\n            )\n            ;(err as Error & { status: number; detail: string }).status = res.status\n            ;(err as Error & { status: number; detail: string }).detail = detail\n            throw err\n          }\n          const data = JSON.parse(detail) as { number: number; html_url: string }\n          return { number: data.number, url: data.html_url }\n        }\n\n        try {\n          return await post(labels)\n        } catch (err) {\n          const status = (err as { status?: number }).status\n          const detail = (err as { detail?: string }).detail ?? (err instanceof Error ? err.message : '')\n          if (labels.length > 0 && status !== undefined && isMissingLabelFailure(status, detail)) {\n            config.onError(\n              new Error(\n                `[gh-issue-tracker] Label does not exist on ${config.repo} (${labels.join(', ')}). ` +\n                  `Set autoCreateLabels: true (default) or run: gh label create <name> --repo ${config.repo}. ` +\n                  `Filing the issue without labels so the report is not dropped.`,\n              ),\n            )\n            return await post([])\n          }\n          throw err\n        }\n      } catch (err) {\n        config.onError(err)\n        return null\n      }\n    },\n\n    async addReaction(issueNumber: number): Promise<void> {\n      try {\n        await request('POST', `/repos/${owner}/${repo}/issues/${issueNumber}/reactions`, {\n          content: '+1',\n        })\n      } catch (err) {\n        config.onError(err)\n      }\n    },\n\n    async reopenIssue(issueNumber: number, comment: string): Promise<void> {\n      try {\n        await request('PATCH', `/repos/${owner}/${repo}/issues/${issueNumber}`, {\n          state: 'open',\n        })\n        await request('POST', `/repos/${owner}/${repo}/issues/${issueNumber}/comments`, {\n          body: comment,\n        })\n      } catch (err) {\n        config.onError(err)\n      }\n    },\n\n    async uploadImage({ branch, path, base64Content, message }): Promise<boolean> {\n      try {\n        await ensureBranch(branch)\n        await request('PUT', `/repos/${owner}/${repo}/contents/${path}`, {\n          message,\n          content: base64Content,\n          branch,\n        })\n        return true\n      } catch (err) {\n        config.onError(err)\n        return false\n      }\n    },\n\n    async uploadUserAttachment({ name, contentType, data }): Promise<string | null> {\n      try {\n        if (data.byteLength === 0) {\n          throw new Error(`attachment \"${name}\" is empty`)\n        }\n        if (data.byteLength > MAX_IMAGE_BYTES) {\n          throw new Error(\n            `attachment \"${name}\" is ${data.byteLength} bytes; images must be at most ${MAX_IMAGE_BYTES}`,\n          )\n        }\n\n        const filename = name.split(/[/\\\\]/).pop() || 'screenshot.png'\n        const repoId = await resolveRepositoryId()\n        const params = new URLSearchParams({\n          name: filename,\n          content_type: contentType,\n          repository_id: String(repoId),\n        })\n\n        const bytes = new Uint8Array(data.byteLength)\n        bytes.set(data)\n\n        const res = await fetch(`${UPLOADS_BASE}/user-attachments/assets?${params.toString()}`, {\n          method: 'POST',\n          headers: {\n            Authorization: `Bearer ${config.token}`,\n            Accept: 'application/vnd.github+json',\n            'X-GitHub-Api-Version': '2022-11-28',\n            'User-Agent': 'gh-issue-tracker',\n            'Content-Type': 'application/octet-stream',\n          },\n          body: bytes.buffer,\n        })\n        if (!res.ok) {\n          const detail = await res.text().catch(() => '')\n          throw new Error(\n            `GitHub POST /user-attachments/assets failed: ${res.status} ${res.statusText}${detail ? ` — ${detail}` : ''}`,\n          )\n        }\n        const payload = (await res.json().catch(() => null)) as { url?: string } | null\n        if (!payload?.url) {\n          throw new Error('GitHub user-attachment upload returned no asset URL')\n        }\n        return payload.url\n      } catch (err) {\n        config.onError(err)\n        return null\n      }\n    },\n  }\n}\n","/**\n * Bug-report helpers — pure functions for turning a user bug report into a\n * GitHub issue (title, body, screenshot path/encoding). The orchestration that\n * actually uploads + creates the issue lives in `client.ts` (`captureBugReport`).\n */\n\nimport type { BugReportInput } from './types'\n\nexport const DEFAULT_SCREENSHOT_BRANCH = 'bug-report-screenshots'\nexport const DEFAULT_SCREENSHOT_PROXY_PATH = 'api/bug-screenshots'\n\n/** MIME type from a screenshot filename. Falls back to image/png. */\nexport function contentTypeFromFilename(filename: string): string {\n  const ext = filename.toLowerCase().split('.').pop() ?? ''\n  if (ext === 'png') return 'image/png'\n  if (ext === 'jpg' || ext === 'jpeg') return 'image/jpeg'\n  if (ext === 'gif') return 'image/gif'\n  if (ext === 'webp') return 'image/webp'\n  if (ext === 'mp4') return 'video/mp4'\n  if (ext === 'webm') return 'video/webm'\n  if (ext === 'mov') return 'video/quicktime'\n  return 'image/png'\n}\n\n/** Base64-encode bytes without Node's Buffer (edge/Workers safe). */\nexport function uint8ToBase64(bytes: Uint8Array): string {\n  let binary = ''\n  const CHUNK = 0x8000\n  for (let i = 0; i < bytes.length; i += CHUNK) {\n    binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n  }\n  return btoa(binary)\n}\n\n/** Deterministic, traversal-safe screenshot path: `yyyy/mm/<reporter>-<ts>-<name>`. */\nexport function buildScreenshotPath(reporterId: string, filename: string, now = new Date()): string {\n  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '_')\n  const safeReporter = reporterId.replace(/[^a-zA-Z0-9._-]/g, '_')\n  const yyyy = now.getUTCFullYear()\n  const mm = String(now.getUTCMonth() + 1).padStart(2, '0')\n  return `${yyyy}/${mm}/${safeReporter}-${now.getTime()}-${safeName}`\n}\n\nexport function truncate(text: string, max: number): string {\n  return text.length <= max ? text : text.slice(0, max - 1) + '…'\n}\n\nexport function pagePath(url: string): string {\n  try {\n    return new URL(url).pathname\n  } catch {\n    return url.split('?')[0] ?? url\n  }\n}\n\n/** Build the issue body for a bug report. */\nexport function formatBugReportBody(\n  input: BugReportInput,\n  screenshotUrl: string | undefined,\n  environment: string | undefined,\n): string {\n  const pin =\n    input.pin\n      ? `(${input.pin.x.toFixed(1)}%, ${input.pin.y.toFixed(1)}%)`\n      : 'Not specified'\n\n  const sections: string[] = [\n    '## User Bug Report',\n    '',\n    '### Reporter',\n    `- **Name:** ${input.reporter.name ?? 'Not specified'}`,\n    `- **Email:** ${input.reporter.email ?? 'Not specified'}`,\n    `- **Role:** ${input.reporter.role ?? 'Not specified'}`,\n    `- **User ID:** ${input.reporter.id}`,\n    '',\n    '### Location',\n    `- **Page:** ${input.pageUrl}`,\n    `- **Pin:** ${pin}`,\n  ]\n\n  const meta = Object.entries(input.metadata ?? {}).filter(\n    ([, v]) => v !== undefined && v !== null && v !== '',\n  )\n  if (meta.length > 0) {\n    sections.push('', '### Environment')\n    for (const [k, v] of meta) sections.push(`- **${k}:** ${v}`)\n  }\n\n  sections.push(\n    '',\n    `_Environment: ${environment ?? 'unknown'} • ${new Date().toISOString()}_`,\n    '',\n    '---',\n    '',\n    '### Description',\n    input.message,\n    '',\n    '---',\n    '',\n    screenshotUrl\n      ? `![Screenshot](${screenshotUrl})`\n      : input.screenshot\n        ? '_Screenshot upload failed_'\n        : '_No screenshot attached_',\n  )\n\n  return sections.join('\\n')\n}\n","/**\n * Error tracker client — the main orchestrator.\n *\n * Singleton pattern: call `init()` once at startup, then use\n * `captureException()` / `captureMessage()` anywhere in your app.\n * All GitHub API calls are fire-and-forget. Call `flush()` in\n * serverless environments to wait for pending operations before returning.\n */\n\nimport type {\n  ErrorTrackerConfig,\n  ErrorContext,\n  GitHubClient,\n  BugReportInput,\n  BugReportResult,\n} from './types'\nimport { generateFingerprint } from './fingerprint'\nimport { RateLimiter } from './rate-limiter'\nimport { createGitHubClient } from './github'\nimport {\n  DEFAULT_SCREENSHOT_BRANCH,\n  DEFAULT_SCREENSHOT_PROXY_PATH,\n  buildScreenshotPath,\n  contentTypeFromFilename,\n  formatBugReportBody,\n  pagePath,\n  truncate,\n  uint8ToBase64,\n} from './bug-report'\n\n// ---------------------------------------------------------------------------\n// Module state (singleton)\n// ---------------------------------------------------------------------------\n\nlet config: ErrorTrackerConfig | null = null\nlet github: GitHubClient | null = null\nlet limiter: RateLimiter | null = null\nconst pending: Promise<void>[] = []\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Initialize the error tracker. Call once at app startup.\n */\nexport function init(cfg: ErrorTrackerConfig): void {\n  config = {\n    environment: 'development',\n    enabled: true,\n    reopenClosed: true,\n    rateLimitPerMinute: 10,\n    dedupeWindowMs: 60_000,\n    labels: [],\n    onError: console.error,\n    ...cfg,\n  }\n\n  if (!config.enabled) return\n\n  github = createGitHubClient({\n    token: config.githubToken,\n    repo: config.githubRepo,\n    onError: config.onError!,\n    autoCreateLabels: config.autoCreateLabels,\n  })\n\n  limiter = new RateLimiter({\n    maxPerMinute: config.rateLimitPerMinute!,\n    dedupeWindowMs: config.dedupeWindowMs!,\n  })\n}\n\n/**\n * Capture an exception. Fire-and-forget — use `flush()` if you\n * need to wait for the GitHub API call to complete.\n */\nexport function captureException(error: Error, context?: ErrorContext): void {\n  if (!config?.enabled || !github || !limiter) return\n\n  // Fingerprinting is async (Web Crypto), so it runs inside the fire-and-forget\n  // promise; flush() still awaits the whole chain.\n  const lim = limiter\n  const promise = (async () => {\n    const fingerprint = await generateFingerprint(error)\n\n    if (!lim.canProcess(fingerprint)) {\n      console.error(`[error-tracker] Rate limited or deduped: ${fingerprint}`)\n      return\n    }\n    lim.recordProcessed(fingerprint)\n\n    await processError(error, fingerprint, context)\n  })().catch((err) => {\n    config?.onError?.(err)\n  })\n\n  pending.push(promise)\n}\n\n/**\n * Capture a plain message as an error event.\n */\nexport function captureMessage(\n  message: string,\n  level: 'error' | 'warning' = 'error',\n  context?: ErrorContext,\n): void {\n  if (!config?.enabled || !github || !limiter) return\n\n  const gh = github\n  const lim = limiter\n  const promise = (async () => {\n    const fingerprint = await generateFingerprint(message)\n\n    if (!lim.canProcess(fingerprint)) return\n    lim.recordProcessed(fingerprint)\n\n    const title = `[${level === 'warning' ? 'Warning' : 'Error'}] ${message.slice(0, 80)}`\n    const body = formatBody(message, undefined, fingerprint, context)\n    const labels = buildLabels(fingerprint)\n\n    const existing = await gh.searchExistingIssue(fingerprint)\n\n    if (existing?.state === 'open') {\n      await gh.addReaction(existing.number)\n    } else if (existing?.state === 'closed') {\n      if (config?.reopenClosed) {\n        await gh.reopenIssue(existing.number, recurrenceComment())\n        await gh.addReaction(existing.number)\n      }\n    } else {\n      await gh.createIssue(title, body, labels)\n    }\n  })().catch((err) => {\n    config?.onError?.(err)\n  })\n\n  pending.push(promise)\n}\n\n/**\n * Capture a user-submitted bug report as a GitHub issue, optionally with a\n * screenshot. Unlike `captureException`, this is NOT fire-and-forget or deduped\n * — it awaits the GitHub calls and returns the created issue so the caller (an\n * API route) can surface the result. Requires `init()` to have been called.\n *\n * If `input.screenshot` is set, the image is uploaded as a GitHub user\n * attachment by default (same path as `gh issue create --attach`) and\n * embedded in the issue. Set `screenshotUpload: \"branch\"` to keep the\n * Contents-API + proxy path (GitHub Enterprise Server / existing setups).\n */\nexport async function captureBugReport(\n  input: BugReportInput,\n): Promise<BugReportResult | null> {\n  if (!config?.enabled || !github) return null\n  const gh = github\n  const cfg = config\n\n  let screenshotUrl: string | undefined\n  if (input.screenshot) {\n    screenshotUrl =\n      cfg.screenshotUpload === 'branch'\n        ? await uploadScreenshotToBranch(gh, cfg, input)\n        : await uploadScreenshotAsAttachment(gh, input)\n  }\n\n  const title = `[Bug Report] ${truncate(input.message.replace(/\\s+/g, ' ').trim(), 80)} — ${pagePath(input.pageUrl)}`\n  const body = formatBugReportBody(input, screenshotUrl, cfg.environment)\n  const labels = ['bug-report', ...(input.labels ?? [])]\n\n  const issue = await gh.createIssue(title, body, labels)\n  if (!issue) return null\n\n  return { issueNumber: issue.number, issueUrl: issue.url, screenshotUrl }\n}\n\n/**\n * Wait for all pending error reports to complete.\n * Call before serverless function returns.\n */\nexport async function flush(): Promise<void> {\n  await Promise.allSettled(pending)\n  pending.length = 0\n}\n\n/**\n * Reset internal state. For testing only.\n * @internal\n */\nexport function _reset(): void {\n  limiter?.destroy()\n  config = null\n  github = null\n  limiter = null\n  pending.length = 0\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nasync function processError(\n  error: Error,\n  fingerprint: string,\n  context?: ErrorContext,\n): Promise<void> {\n  if (!github) return\n\n  const existing = await github.searchExistingIssue(fingerprint)\n\n  if (existing?.state === 'open') {\n    await github.addReaction(existing.number)\n    return\n  }\n\n  if (existing?.state === 'closed') {\n    if (config?.reopenClosed) {\n      await github.reopenIssue(existing.number, recurrenceComment())\n      await github.addReaction(existing.number)\n    }\n    return\n  }\n\n  // No existing issue — create one\n  const title = `[Error] ${(error.name || 'Error')}: ${error.message.slice(0, 80)}`\n  const body = formatBody(error.message, error.stack, fingerprint, context)\n  const labels = buildLabels(fingerprint)\n\n  await github.createIssue(title, body, labels)\n}\n\nfunction buildLabels(fingerprint: string): string[] {\n  return [\n    'error-report',\n    `fingerprint:${fingerprint}`,\n    ...(config?.labels ?? []),\n  ]\n}\n\nfunction formatBody(\n  message: string,\n  stack: string | undefined,\n  fingerprint: string,\n  context?: ErrorContext,\n): string {\n  const env = config?.environment ?? 'unknown'\n  const timestamp = new Date().toISOString()\n\n  const sections = [\n    `## Error Report (Automated)`,\n    `**Environment:** ${env} | **Fingerprint:** \\`${fingerprint}\\` | **Time:** ${timestamp}`,\n    '',\n    `### Message`,\n    message,\n  ]\n\n  if (stack) {\n    sections.push('', '### Stack Trace', '```', stack, '```')\n  }\n\n  if (context?.tags && Object.keys(context.tags).length > 0) {\n    const tagLines = Object.entries(context.tags)\n      .map(([k, v]) => `- **${k}:** ${v}`)\n      .join('\\n')\n    sections.push('', '### Tags', tagLines)\n  }\n\n  if (context?.requestUrl) {\n    sections.push('', `**Request URL:** ${context.requestUrl}`)\n  }\n\n  if (context?.user) {\n    sections.push(`**User:** ${context.user.id}${context.user.email ? ` (${context.user.email})` : ''}`)\n  }\n\n  if (context?.extras && Object.keys(context.extras).length > 0) {\n    sections.push(\n      '',\n      '<details>',\n      '<summary>Additional metadata</summary>',\n      '',\n      '```json',\n      JSON.stringify(context.extras, null, 2),\n      '```',\n      '</details>',\n    )\n  }\n\n  return sections.join('\\n')\n}\n\nasync function uploadScreenshotAsAttachment(\n  gh: GitHubClient,\n  input: BugReportInput,\n): Promise<string | undefined> {\n  const shot = input.screenshot\n  if (!shot) return undefined\n  const url = await gh.uploadUserAttachment({\n    name: shot.filename,\n    contentType: shot.contentType ?? contentTypeFromFilename(shot.filename),\n    data: shot.data,\n  })\n  return url ?? undefined\n}\n\nasync function uploadScreenshotToBranch(\n  gh: GitHubClient,\n  cfg: ErrorTrackerConfig,\n  input: BugReportInput,\n): Promise<string | undefined> {\n  const shot = input.screenshot\n  if (!shot) return undefined\n  const branch = cfg.screenshotBranch ?? DEFAULT_SCREENSHOT_BRANCH\n  const path = buildScreenshotPath(input.reporter.id, shot.filename)\n  const uploaded = await gh.uploadImage({\n    branch,\n    path,\n    base64Content: uint8ToBase64(shot.data),\n    message: `chore(bug-report): add screenshot ${path}`,\n  })\n  if (!uploaded) return undefined\n  if (cfg.appBaseUrl) {\n    const base = cfg.appBaseUrl.replace(/\\/$/, '')\n    const proxy = (cfg.screenshotProxyPath ?? DEFAULT_SCREENSHOT_PROXY_PATH).replace(\n      /^\\/|\\/$/g,\n      '',\n    )\n    return `${base}/${proxy}/${path}`\n  }\n  // Public-repo fallback — raw.githubusercontent works without a token.\n  return `https://raw.githubusercontent.com/${cfg.githubRepo}/${branch}/${path}`\n}\n\nfunction recurrenceComment(): string {\n  const env = config?.environment ?? 'unknown'\n  return `**Recurrence detected** at ${new Date().toISOString()} in \\`${env}\\` environment.`\n}\n","/**\n * Screenshot read-through proxy for `screenshotUpload: \"branch\"` (legacy).\n * Default bug reports use GitHub user-attachments and do not need this.\n */\n\nimport type { FetchIssueImageOptions, FetchIssueImageResult } from './types'\nimport { DEFAULT_SCREENSHOT_BRANCH } from './bug-report'\n\n// Strict shape `yyyy/mm/<filename>`; filename has no slashes, so traversal is\n// impossible. The explicit `..` check is belt-and-suspenders.\nconst PATH_SHAPE = /^\\d{4}\\/\\d{2}\\/[\\w.-]+$/\n\nfunction contentTypeFor(filepath: string): string {\n  const ext = filepath.toLowerCase().split('.').pop() ?? ''\n  if (ext === 'png') return 'image/png'\n  if (ext === 'webp') return 'image/webp'\n  return 'image/jpeg'\n}\n\nexport async function fetchIssueImage(\n  opts: FetchIssueImageOptions,\n): Promise<FetchIssueImageResult> {\n  const branch = opts.branch ?? DEFAULT_SCREENSHOT_BRANCH\n\n  if (!PATH_SHAPE.test(opts.path) || opts.path.includes('..')) {\n    return { status: 400 }\n  }\n\n  const [owner, repo] = opts.repo.split('/')\n  if (!owner || !repo || !opts.token) {\n    return { status: 503 }\n  }\n\n  const url = `https://api.github.com/repos/${owner}/${repo}/contents/${opts.path}?ref=${branch}`\n  let res: Response\n  try {\n    res = await fetch(url, {\n      headers: {\n        Authorization: `Bearer ${opts.token}`,\n        Accept: 'application/vnd.github.raw',\n        'User-Agent': 'gh-issue-tracker',\n      },\n    })\n  } catch {\n    return { status: 502 }\n  }\n\n  if (res.status === 404) return { status: 404 }\n  if (!res.ok) return { status: 502 }\n\n  const body = await res.arrayBuffer()\n  return { status: 200, body, contentType: contentTypeFor(opts.path) }\n}\n","/**\n * Route-handler wrapper — capture every server error a handler produces.\n *\n * Frameworks surface server errors two ways: a handler can THROW, or it can\n * deliberately RETURN a 5xx response. A thrown-error hook (e.g. Next.js\n * `onRequestError`) only sees the first. `withErrorReporting` covers both, so\n * \"a 500 is a server error → it files an issue\" holds no matter how the 500 is\n * produced.\n *\n * Framework-agnostic: works with anything whose handler takes a Web `Request`\n * first and returns a `Response` (Next.js route handlers, Remix, Hono,\n * Cloudflare Workers, plain fetch handlers). Edge-native, zero deps.\n *\n *   export const POST = withErrorReporting(async (req) => { ... })\n *\n * Requires `init()` to have run. Capture is deduplicated, so even if a thrown\n * error is ALSO reported by a framework hook, only one issue is created.\n */\n\nimport type { ErrorContext } from './types'\nimport { captureException, flush } from './client'\n\nexport interface WithErrorReportingOptions {\n  /** Report responses whose status is >= this. Default: 500. */\n  minStatus?: number\n  /** Also capture thrown errors (not just returned 5xx). Default: true. */\n  catchThrows?: boolean\n  /**\n   * Re-throw a caught error after reporting it (so the framework still handles\n   * it). Default: true. When false, the error is swallowed and a 500 response\n   * is returned instead.\n   */\n  rethrow?: boolean\n  /** Extra context merged into every report (tags, user, etc.). */\n  context?: ErrorContext\n}\n\nfunction requestInfo(arg: unknown): { method?: string; url?: string } {\n  const r = arg as { method?: unknown; url?: unknown } | undefined\n  return {\n    method: typeof r?.method === 'string' ? r.method : undefined,\n    url: typeof r?.url === 'string' ? r.url : undefined,\n  }\n}\n\nfunction mergeContext(\n  base: ErrorContext | undefined,\n  extraTags: Record<string, string>,\n  url: string | undefined,\n): ErrorContext {\n  return {\n    ...base,\n    tags: { ...extraTags, ...(base?.tags ?? {}) },\n    requestUrl: base?.requestUrl ?? url,\n  }\n}\n\nexport function withErrorReporting<A extends unknown[]>(\n  handler: (...args: A) => Response | Promise<Response>,\n  options: WithErrorReportingOptions = {},\n): (...args: A) => Promise<Response> {\n  const minStatus = options.minStatus ?? 500\n  const catchThrows = options.catchThrows ?? true\n  const rethrow = options.rethrow ?? true\n\n  return async (...args: A): Promise<Response> => {\n    let res: Response\n    try {\n      res = await handler(...args)\n    } catch (err) {\n      if (catchThrows) {\n        const { method, url } = requestInfo(args[0])\n        captureException(err instanceof Error ? err : new Error(String(err)), {\n          ...mergeContext(\n            options.context,\n            { source: 'withErrorReporting', kind: 'throw', ...(method ? { method } : {}) },\n            url,\n          ),\n        })\n        await flush()\n        if (!rethrow) {\n          return new Response('Internal Server Error', { status: 500 })\n        }\n      }\n      throw err\n    }\n\n    if (res.status >= minStatus) {\n      const { method, url } = requestInfo(args[0])\n      let detail = ''\n      try {\n        detail = (await res.clone().text()).slice(0, 300)\n      } catch {\n        /* body not readable — ignore */\n      }\n      captureException(\n        new Error(\n          `HTTP ${res.status} from ${method ?? '?'} ${url ?? '?'}${detail ? ` — ${detail}` : ''}`,\n        ),\n        mergeContext(\n          options.context,\n          {\n            source: 'withErrorReporting',\n            kind: 'response',\n            status: String(res.status),\n            ...(method ? { method } : {}),\n          },\n          url,\n        ),\n      )\n      await flush()\n    }\n\n    return res\n  }\n}\n"],"mappings":"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","names":["config","config"]}