{"id":37712946,"url":"https://github.com/zudsniper/bugs","last_synced_at":"2026-01-16T13:21:31.486Z","repository":{"id":311403055,"uuid":"1043589304","full_name":"zudsniper/bugs","owner":"zudsniper","description":"a bug reporter for reactjs that autoreports (with lots of diagnostic info) to linear/gh issues/etc","archived":false,"fork":false,"pushed_at":"2025-08-24T07:51:32.000Z","size":75,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-24T14:27:56.349Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zudsniper.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-24T07:25:01.000Z","updated_at":"2025-08-24T07:51:35.000Z","dependencies_parsed_at":"2025-08-24T14:29:32.169Z","dependency_job_id":"0167c6ee-fe02-44b9-9450-7b3c318e9733","html_url":"https://github.com/zudsniper/bugs","commit_stats":null,"previous_names":["zudsniper/bugs"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zudsniper/bugs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zudsniper%2Fbugs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zudsniper%2Fbugs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zudsniper%2Fbugs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zudsniper%2Fbugs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zudsniper","download_url":"https://codeload.github.com/zudsniper/bugs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zudsniper%2Fbugs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479033,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-16T13:21:30.664Z","updated_at":"2026-01-16T13:21:31.476Z","avatar_url":"https://github.com/zudsniper.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐛 @zudsniper/bugs\n\nA comprehensive, standalone bug reporter widget for React and Next.js applications with screenshot capture, console logging, and multiple integration options.\n\n![Bug Reporter Demo](https://via.placeholder.com/800x400/f97316/white?text=Bug+Reporter+Demo)\n\n## ✨ Features\n\n- **📸 Screenshot Capture** - Automatic screenshot with privacy controls\n- **📝 Console Log Capture** - Automatic console log collection with filtering\n- **🌐 Network Request Monitoring** - Track API calls and network issues\n- **🔗 Multiple Integrations** - GitHub Issues, Linear, Jira, Slack, Discord, webhooks, and email\n- **🎨 Customizable UI** - Themes, positioning, and custom styling\n- **📱 Responsive Design** - Mobile-friendly interface\n- **🔐 Privacy First** - Configurable data redaction and exclusions\n- **⌨️ Keyboard Shortcuts** - Customizable hotkeys\n- **📁 File Upload Support** - Drag \u0026 drop, paste, and click to upload\n- **🔄 TypeScript Support** - Full type safety and IntelliSense\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\n# npm\nnpm install @zudsniper/bugs\n\n# yarn\nyarn add @zudsniper/bugs\n\n# pnpm\npnpm add @zudsniper/bugs\n```\n\n### Basic Usage\n\n\u003e ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nimport { BugReporter, defaultConfigs } from '@zudsniper/bugs';\nimport '@zudsniper/bugs/styles';\n\nfunction App() {\n  const config = defaultConfigs.github('owner/repo', 'github-token');\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eMy App\u003c/h1\u003e\n      \u003cBugReporter config={config} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\nThat's it! Your users can now report bugs by clicking the floating bug icon.\n\n## 📖 Documentation\n\n### Configuration\n\nThe bug reporter is highly configurable through the `BugReporterConfig` object:\n\n\u003e ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nimport { BugReporter, mergeConfigs, defaultConfigs } from '@zudsniper/bugs';\n\nconst config = mergeConfigs(\n  defaultConfigs.github('owner/repo', 'token'),\n  {\n    ui: {\n      title: 'Report a Bug',\n      theme: 'auto',\n      position: 'bottom-right',\n      primaryColor: '#3b82f6'\n    },\n    capture: {\n      captureScreenshot: true,\n      maxConsoleLogs: 50,\n      maxNetworkRequests: 25\n    },\n    validation: {\n      requireTitle: true,\n      requireDescription: true,\n      requireEmail: false\n    }\n  }\n);\n\n\u003cBugReporter config={config} /\u003e\n```\n\n### Integrations\n\n#### GitHub Issues\n\n\u003e ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nconst config = defaultConfigs.github('owner/repository', 'github-token');\n\n// Or with custom configuration\nconst config = {\n  integrations: {\n    github: {\n      repo: 'owner/repository',\n      token: 'github-token',\n      labels: ['bug', 'user-report'],\n      assignees: ['developer-username'],\n      milestone: 'v1.0'\n    }\n  }\n};\n```\n\n#### Linear\n\n\u003e ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nconst config = defaultConfigs.linear('linear-api-key', 'team-id');\n\n// Or with custom configuration\nconst config = {\n  integrations: {\n    linear: {\n      apiKey: 'linear-api-key',\n      teamId: 'team-id',\n      projectId: 'project-id',\n      priority: 2, // High priority\n      labels: ['bug', 'user-feedback']\n    }\n  }\n};\n```\n\n#### Slack\n\n```tsx\nconst config = defaultConfigs.slack('https://hooks.slack.com/your/webhook');\n\n// Or with custom configuration\nconst config = {\n  integrations: {\n    slack: {\n      webhook: 'https://hooks.slack.com/your/webhook',\n      channel: '#bugs',\n      username: 'Bug Reporter',\n      iconEmoji: ':bug:'\n    }\n  }\n};\n```\n\n#### Custom Webhook\n\n\u003e ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nconst config = defaultConfigs.webhook('https://your-api.com/bug-reports');\n\n// Or with authentication\nconst config = {\n  integrations: {\n    webhook: {\n      url: 'https://your-api.com/bug-reports',\n      method: 'POST',\n      headers: {\n        'Authorization': 'Bearer your-token',\n        'X-App-Version': '1.0.0'\n      },\n      auth: {\n        type: 'bearer',\n        token: 'your-auth-token'\n      }\n    }\n  }\n};\n```\n\n### Custom Trigger\n\nReplace the default floating button with your own trigger:\n\n```tsx\nfunction CustomTrigger({ onClick }) {\n  return (\n    \u003cbutton onClick={onClick} className=\"my-bug-button\"\u003e\n      🐛 Report Issue\n    \u003c/button\u003e\n  );\n}\n\n\u003cBugReporter config={config}\u003e\n  \u003cCustomTrigger /\u003e\n\u003c/BugReporter\u003e\n```\n\n### Privacy Controls\n\nProtect sensitive information:\n\n```tsx\nconst config = {\n  privacy: {\n    excludeSelectors: [\n      '[data-private]',\n      '.password-field',\n      '.credit-card-input'\n    ],\n    redactPatterns: [\n      /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/g, // emails\n      /\\b\\d{4}\\s?\\d{4}\\s?\\d{4}\\s?\\d{4}\\b/g // credit cards\n    ],\n    anonymizeUrls: true,\n    allowScreenshots: true,\n    allowConsoleLogs: false // Disable console logs for privacy\n  }\n};\n```\n\n### Keyboard Shortcuts\n\n```tsx\nconst config = {\n  keyboard: {\n    openShortcut: ['ctrl', 'shift', 'b'],\n    closeShortcut: ['escape'],\n    submitShortcut: ['ctrl', 'enter']\n  }\n};\n```\n\n### Custom Fields\n\nAdd custom form fields:\n\n```tsx\nconst config = {\n  ui: {\n    fields: [\n      {\n        type: 'text',\n        key: 'title',\n        label: 'Issue Title',\n        required: true\n      },\n      {\n        type: 'select',\n        key: 'severity',\n        label: 'Severity',\n        options: [\n          { value: 'low', label: 'Low' },\n          { value: 'medium', label: 'Medium' },\n          { value: 'high', label: 'High' },\n          { value: 'critical', label: 'Critical' }\n        ],\n        required: true\n      },\n      {\n        type: 'textarea',\n        key: 'description',\n        label: 'Description',\n        placeholder: 'Describe the issue...',\n        required: true\n      },\n      {\n        type: 'email',\n        key: 'userEmail',\n        label: 'Email (optional)',\n        validation: {\n          pattern: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n        }\n      }\n    ]\n  }\n};\n```\n\n## 🎨 Styling and Theming\n\n### Built-in Themes\n\n```tsx\nconst config = {\n  ui: {\n    theme: 'light', // 'light', 'dark', or 'auto'\n    primaryColor: '#3b82f6'\n  }\n};\n```\n\n### Custom CSS\n\nOverride default styles using CSS variables:\n\n```css\n:root {\n  --br-color-primary: #your-primary-color;\n  --br-color-secondary: #your-secondary-color;\n  --br-border-radius: 8px;\n}\n\n/* Custom styling */\n.br-popup-container {\n  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);\n}\n\n.br-floating-button {\n  background: linear-gradient(45deg, #ff6b6b, #4ecdc4);\n}\n```\n\n### Custom Styles Object\n\n```tsx\nconst config = {\n  ui: {\n    customStyles: {\n      '--br-color-primary': '#9333ea',\n      '--br-color-secondary': '#7c3aed',\n      '--br-border-radius': '12px'\n    }\n  }\n};\n```\n\n## 📱 Framework Examples\n\n### Next.js App Router\n\n\u003e ⚠️ **SECURITY WARNING**: The example below uses `NEXT_PUBLIC_*` environment variables which expose values to the client-side code. **This is insecure for production**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\n'use client';\n\nimport { BugReporter, defaultConfigs } from '@zudsniper/bugs';\nimport '@zudsniper/bugs/styles';\n\nexport default function Layout({ children }) {\n  const config = defaultConfigs.github('owner/repo', process.env.NEXT_PUBLIC_GITHUB_TOKEN);\n  \n  return (\n    \u003chtml\u003e\n      \u003cbody\u003e\n        {children}\n        \u003cBugReporter config={config} /\u003e\n      \u003c/body\u003e\n    \u003c/html\u003e\n  );\n}\n```\n\n### Next.js Pages Router\n\n\u003e ⚠️ **SECURITY WARNING**: The example below uses `NEXT_PUBLIC_*` environment variables which expose values to the client-side code. **This is insecure for production**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\n// pages/_app.tsx\nimport { BugReporter, defaultConfigs } from '@zudsniper/bugs';\nimport '@zudsniper/bugs/styles';\n\nexport default function MyApp({ Component, pageProps }) {\n  const config = defaultConfigs.linear(\n    process.env.NEXT_PUBLIC_LINEAR_API_KEY,\n    process.env.NEXT_PUBLIC_LINEAR_TEAM_ID\n  );\n\n  return (\n    \u003c\u003e\n      \u003cComponent {...pageProps} /\u003e\n      \u003cBugReporter config={config} /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Vite + React\n\n```tsx\n// main.tsx\nimport { BugReporter, defaultConfigs } from '@zudsniper/bugs';\nimport '@zudsniper/bugs/styles';\n\nconst config = defaultConfigs.webhook('https://your-api.com/bug-reports');\n\nReactDOM.render(\n  \u003cReact.StrictMode\u003e\n    \u003cApp /\u003e\n    \u003cBugReporter config={config} /\u003e\n  \u003c/React.StrictMode\u003e,\n  document.getElementById('root')\n);\n```\n\n### Vanilla JavaScript (CDN)\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003clink rel=\"stylesheet\" href=\"https://unpkg.com/@zudsniper/bugs@latest/dist/styles.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv id=\"app\"\u003eYour app content\u003c/div\u003e\n  \n  \u003cscript src=\"https://unpkg.com/react@18/umd/react.production.min.js\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/react-dom@18/umd/react-dom.production.min.js\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/@zudsniper/bugs@latest/dist/index.js\"\u003e\u003c/script\u003e\n  \n  \u003cscript\u003e\n    const { BugReporter, defaultConfigs } = window.ZudsniperBugs;\n    const config = defaultConfigs.slack('https://hooks.slack.com/your/webhook');\n    \n    const container = document.createElement('div');\n    document.body.appendChild(container);\n    \n    ReactDOM.render(\n      React.createElement(BugReporter, { config }),\n      container\n    );\n  \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## 🔧 Advanced Usage\n\n### Multiple Integrations\n\nSend reports to multiple services simultaneously:\n\n\u003e ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.\n\n```tsx\nconst config = {\n  integrations: {\n    github: {\n      repo: 'owner/repo',\n      token: 'github-token'\n    },\n    slack: {\n      webhook: 'https://hooks.slack.com/webhook'\n    },\n    webhook: {\n      url: 'https://your-analytics.com/bug-reports'\n    }\n  }\n};\n```\n\n### Event Handlers\n\n```tsx\n\u003cBugReporter\n  config={config}\n  onSubmitSuccess={(response) =\u003e {\n    console.log('Bug report submitted:', response);\n    // Analytics tracking\n    gtag('event', 'bug_report_submitted', {\n      issue_id: response.issueId\n    });\n  }}\n  onSubmitError={(error) =\u003e {\n    console.error('Submission failed:', error);\n    // Error tracking\n    Sentry.captureException(error);\n  }}\n  onOpen={() =\u003e {\n    console.log('Bug reporter opened');\n  }}\n  onClose={() =\u003e {\n    console.log('Bug reporter closed');\n  }}\n/\u003e\n```\n\n### Data Transformation\n\nModify report data before submission:\n\n```tsx\nconst config = {\n  advanced: {\n    transformData: (data) =\u003e {\n      return {\n        ...data,\n        // Add custom metadata\n        environment: process.env.NODE_ENV,\n        version: process.env.REACT_APP_VERSION,\n        userId: getCurrentUserId(),\n        // Remove sensitive information\n        consoleLogs: data.consoleLogs.filter(log =\u003e \n          !log.message.includes('password')\n        )\n      };\n    }\n  }\n};\n```\n\n### File Upload Configuration\n\n```tsx\nconst config = {\n  validation: {\n    maxFileSize: 10 * 1024 * 1024, // 10MB\n    maxFiles: 5,\n    allowedFileTypes: [\n      'image/', // All image types\n      'text/plain',\n      'application/pdf',\n      '.log', // By extension\n      '.json'\n    ]\n  }\n};\n```\n\n## 🛡️ Security Best Practices\n\n⚠️ **CRITICAL SECURITY WARNING**: Never expose API keys, tokens, or sensitive credentials in your frontend code. Always use server-side proxy endpoints for secure integrations.\n\n### Recommended: Proxy Mode (Secure)\n\nFor production applications, use proxy mode where API keys stay on your server:\n\n```tsx\n// Secure configuration - API keys stay on server\nconst config = {\n  integrations: {\n    github: {\n      mode: 'proxy',\n      endpoint: '/api/bug-report/github'\n    },\n    linear: {\n      mode: 'proxy',\n      endpoint: '/api/bug-report/linear'\n    }\n  }\n};\n```\n\n### Direct Mode (Development Only)\n\n⚠️ Only use direct mode for development/testing with non-production tokens:\n\n```tsx\n// NOT recommended for production - tokens exposed to client\nconst config = {\n  integrations: {\n    github: {\n      mode: 'direct', // or omit mode (defaults to direct)\n      repo: 'owner/repo',\n      token: 'github_token' // ⚠️ Exposed to client!\n    }\n  }\n};\n```\n\n### Backend API Routes\n\nCreate server-side API routes that handle the actual integration calls. Examples for Next.js:\n\n#### GitHub Issues API Route\n\n```typescript\n// app/api/bug-report/github/route.ts\nimport { NextRequest } from 'next/server';\n\nexport async function POST(request: NextRequest) {\n  try {\n    const bugData = await request.json();\n    \n    // Your GitHub token stays secure on the server\n    const response = await fetch(`https://api.github.com/repos/${process.env.GITHUB_REPO}/issues`, {\n      method: 'POST',\n      headers: {\n        'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`,\n        'Accept': 'application/vnd.github.v3+json',\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify({\n        title: bugData.title || 'Bug Report',\n        body: formatBugReport(bugData),\n        labels: ['bug', 'user-report']\n      })\n    });\n    \n    const issue = await response.json();\n    return Response.json({ \n      success: true, \n      issueId: issue.number.toString(),\n      issueUrl: issue.html_url \n    });\n  } catch (error) {\n    return Response.json({ success: false, error: 'Failed to create issue' }, { status: 500 });\n  }\n}\n\nfunction formatBugReport(data: any): string {\n  // Format your bug report data as needed\n  return `## Description\\n${data.description}\\n\\n## Environment\\n- URL: ${data.url}\\n- User Agent: ${data.userAgent}`;\n}\n```\n\n#### Linear API Route\n\n```typescript\n// app/api/bug-report/linear/route.ts\nimport { NextRequest } from 'next/server';\n\nexport async function POST(request: NextRequest) {\n  try {\n    const bugData = await request.json();\n    \n    const mutation = `\n      mutation IssueCreate($input: IssueCreateInput!) {\n        issueCreate(input: $input) {\n          success\n          issue { id identifier title url }\n        }\n      }\n    `;\n    \n    const response = await fetch('https://api.linear.app/graphql', {\n      method: 'POST',\n      headers: {\n        'Authorization': process.env.LINEAR_API_KEY!, // Secure on server\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify({\n        query: mutation,\n        variables: {\n          input: {\n            title: bugData.title || 'Bug Report',\n            description: formatLinearReport(bugData),\n            teamId: process.env.LINEAR_TEAM_ID!,\n            priority: 3\n          }\n        }\n      })\n    });\n    \n    const result = await response.json();\n    const issue = result.data?.issueCreate?.issue;\n    \n    return Response.json({\n      success: true,\n      issueId: issue.identifier,\n      issueUrl: issue.url\n    });\n  } catch (error) {\n    return Response.json({ success: false, error: 'Failed to create Linear issue' }, { status: 500 });\n  }\n}\n```\n\n### Environment Variables (Server-Side)\n\n```bash\n# .env.local (server-side only)\nGITHUB_TOKEN=github_pat_...\nGITHUB_REPO=owner/repo\nLINEAR_API_KEY=lin_api_...\nLINEAR_TEAM_ID=team_id\n```\n\n### Data Sanitization\n\nThe bug reporter automatically:\n- Redacts sensitive URL parameters\n- Excludes elements marked with `data-private`\n- Sanitizes console log arguments\n- Filters network request headers\n- Removes sensitive patterns from logs\n\n### Additional Security Measures\n\n- Always validate and sanitize data on your backend\n- Implement rate limiting on your API routes\n- Use HTTPS for all endpoints\n- Validate API tokens server-side\n- Log security events for monitoring\n- Consider implementing CSRF protection\n\n## 🎯 Performance\n\n### Bundle Size\n\n- Core library: ~45KB gzipped\n- With all integrations: ~65KB gzipped\n- Tree-shakable: Only includes used integrations\n\n### Optimization Tips\n\n```tsx\n// Lazy load for better performance\nconst BugReporter = lazy(() =\u003e import('@zudsniper/bugs'));\n\nfunction App() {\n  return (\n    \u003cSuspense fallback={null}\u003e\n      \u003cBugReporter config={config} /\u003e\n    \u003c/Suspense\u003e\n  );\n}\n```\n\n## 🐛 Troubleshooting\n\n### Common Issues\n\n#### Screenshots not capturing\n\n```tsx\n// Ensure html2canvas peer dependency is installed\nnpm install html2canvas\n\n// Or disable screenshots\nconst config = {\n  capture: {\n    captureScreenshot: false\n  }\n};\n```\n\n#### Network requests not captured\n\n```tsx\n// Make sure capture is started before requests\nconst config = {\n  capture: {\n    maxNetworkRequests: 50 // Increase limit\n  }\n};\n```\n\n#### Integration not working\n\n```tsx\n// Validate configuration\nimport { validationManager } from '@zudsniper/bugs';\n\nconst validation = validationManager.validateConfig(config);\nif (!validation.isValid) {\n  console.error('Config errors:', validation.errors);\n}\n```\n\n### Debug Mode\n\n```tsx\nconst config = {\n  advanced: {\n    customLogger: (level, message, data) =\u003e {\n      console.log(`[BugReporter:${level}] ${message}`, data);\n    }\n  }\n};\n```\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/your-username/bug-reporter-popup.git\n\n# Install dependencies\ncd bug-reporter-popup\nnpm install\n\n# Start development\nnpm run dev\n\n# Run tests\nnpm test\n\n# Build for production\nnpm run build\n```\n\n## 📄 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- [html2canvas](https://html2canvas.hertzen.com/) for screenshot functionality\n- [Framer Motion](https://www.framer.com/motion/) for smooth animations\n- [Lucide React](https://lucide.dev/) for beautiful icons\n\n## 📊 Stats\n\n![npm version](https://img.shields.io/npm/v/@zudsniper/bugs)\n![npm downloads](https://img.shields.io/npm/dm/@zudsniper/bugs)\n![bundle size](https://img.shields.io/bundlephobia/minzip/@zudsniper/bugs)\n![license](https://img.shields.io/npm/l/@zudsniper/bugs)\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eMade with ❤️ for better user feedback\u003c/strong\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzudsniper%2Fbugs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzudsniper%2Fbugs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzudsniper%2Fbugs/lists"}