{"_id":"@alunsoldgroup/bug-reporter","_rev":"2-f549c9bd952324301da6f6baadbbb1fb","name":"@alunsoldgroup/bug-reporter","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@alunsoldgroup/bug-reporter","version":"0.1.0","keywords":["bug-report","feedback","astro","cloudflare-workers","linear","posthog","voice"],"license":"MIT","_id":"@alunsoldgroup/bug-reporter@0.1.0","maintainers":[{"name":"alunsoldgroup","email":"al@unsold.group"}],"homepage":"https://github.com/alunsoldantarctica/bug-reporter#readme","bugs":{"url":"https://github.com/alunsoldantarctica/bug-reporter/issues"},"dist":{"shasum":"228ebd0dbbd12b259bef512fd2b094554d7cfecd","tarball":"https://registry.npmjs.org/@alunsoldgroup/bug-reporter/-/bug-reporter-0.1.0.tgz","fileCount":16,"integrity":"sha512-gfZpZbnUfMEGtZMXDZmex8hUMeHNFqLmrnOdr4gcDUjqGQiYPHgMEAKI4rjLswrvNB3jpav5CosYZC4noWWDZg==","signatures":[{"sig":"MEUCIQDiDwkPK4Xk6N1BC1KXZZVOt6ecbG6Pre38ug3q55NnbwIgNyIBnB6Yml2A90r87tvllvZb94abrNmR3ZV+bQWAXfE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110376},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"alunsoldgroup","email":"al@unsold.group"},"repository":{"url":"git+https://github.com/alunsoldantarctica/bug-reporter.git","type":"git"},"_npmVersion":"11.8.0","description":"Adapter-first bug reporter kit with optional voice, element capture, PostHog replay links, and Linear filing.","directories":{},"sideEffects":false,"_nodeVersion":"25.5.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/bug-reporter_0.1.0_1782483650427_0.22908740670451122","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@alunsoldgroup/bug-reporter","version":"0.1.1","type":"module","description":"Adapter-first bug reporter kit with optional voice, element capture, PostHog replay links, and Linear filing.","license":"MIT","homepage":"https://github.com/alunsoldantarctica/bug-reporter#readme","repository":{"type":"git","url":"git+https://github.com/alunsoldantarctica/bug-reporter.git"},"keywords":["bug-report","feedback","astro","cloudflare-workers","linear","posthog","voice"],"sideEffects":false,"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"pnpm run build"},"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0"},"devDependencies":{"@types/react":"^19.0.0","@types/react-dom":"^19.0.0","typescript":"^5.6.0"},"_id":"@alunsoldgroup/bug-reporter@0.1.1","bugs":{"url":"https://github.com/alunsoldantarctica/bug-reporter/issues"},"_nodeVersion":"25.5.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-1SHjLp0dIJQrJVIe9bITXXDKfJVVJMajGRnKcGPFGmMjiwW2a4qVODUtcYB6elHN1G4MzFjpnoCyyeQxU3vdFQ==","shasum":"a4ee0c934d0660576e4bce77f87371f61d18ad4c","tarball":"https://registry.npmjs.org/@alunsoldgroup/bug-reporter/-/bug-reporter-0.1.1.tgz","fileCount":16,"unpackedSize":113285,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCmtwwXiEKis/VJPsI6u5H3sM8MFVt7Jf4AHybMG6rzlwIgP+hviMDq07gsOjg65uoPqcbuBb6dqF5tfTzSTgDcebI="}]},"_npmUser":{"name":"alunsoldgroup","email":"al@unsold.group"},"directories":{},"maintainers":[{"name":"alunsoldgroup","email":"al@unsold.group"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bug-reporter_0.1.1_1782485327300_0.7625338685850909"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-26T14:20:50.219Z","modified":"2026-06-26T14:48:47.551Z","0.1.0":"2026-06-26T14:20:50.615Z","0.1.1":"2026-06-26T14:48:47.440Z"},"bugs":{"url":"https://github.com/alunsoldantarctica/bug-reporter/issues"},"license":"MIT","homepage":"https://github.com/alunsoldantarctica/bug-reporter#readme","keywords":["bug-report","feedback","astro","cloudflare-workers","linear","posthog","voice"],"repository":{"type":"git","url":"git+https://github.com/alunsoldantarctica/bug-reporter.git"},"description":"Adapter-first bug reporter kit with optional voice, element capture, PostHog replay links, and Linear filing.","maintainers":[{"name":"alunsoldgroup","email":"al@unsold.group"}],"readme":"# @alunsoldgroup/bug-reporter\n\n[![npm version](https://img.shields.io/npm/v/@alunsoldgroup/bug-reporter?logo=npm&color=cb3837)](https://www.npmjs.com/package/@alunsoldgroup/bug-reporter)\n[![npm downloads](https://img.shields.io/npm/dm/@alunsoldgroup/bug-reporter?logo=npm&color=cb3837)](https://www.npmjs.com/package/@alunsoldgroup/bug-reporter)\n[![GitHub stars](https://img.shields.io/github/stars/alunsoldantarctica/bug-reporter?logo=github)](https://github.com/alunsoldantarctica/bug-reporter/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/alunsoldantarctica/bug-reporter?logo=github)](https://github.com/alunsoldantarctica/bug-reporter/network/members)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n![TypeScript](https://img.shields.io/badge/TypeScript-ready-3178c6?logo=typescript&logoColor=white)\n![React](https://img.shields.io/badge/React-peer-61dafb?logo=react&logoColor=111827)\n![Cloudflare Workers](https://img.shields.io/badge/Cloudflare%20Workers-adapter-f38020?logo=cloudflare&logoColor=white)\n\nBug reporting UI and adapters that turn vague product feedback into\ndeveloper-ready tickets.\n\nUse it when you want staff, QA, or trusted beta users to report bugs with useful\ndeveloper context: the page URL, selected UI elements, optional screenshots,\noptional voice narration, and optional PostHog replay links.\n\nMost in-app bug reporters stop at a text box. This package captures the context\ndevelopers actually need: the page, the selected UI element, browser details,\nscreenshots, optional voice narration, and optional replay links. The server\nadapter turns that into a Linear issue that is ready for triage, automation, or\ndirect implementation.\n\nThe package is adapter-first. You can use the provided Astro on Cloudflare\nWorkers adapter, or plug the browser payload into your own backend, issue\ntracker, storage, and auth stack.\n\n## Why Integrate It\n\n- **Fewer low-signal tickets**: every report can include URL, selector, visible\n  text, viewport, user agent, screenshots, replay id, and voice transcript.\n- **Works with your stack**: browser collection is separate from server filing.\n  Bring your own auth, database, storage, queue, issue tracker, and redaction.\n- **Safe secret boundary**: Linear, PostHog, and AI Gateway credentials stay on\n  your server. Static demos can use mock submitters.\n- **Agent-ready output**: tickets include structured context that a developer,\n  Claude Code routine, or coding agent can map back to owning files.\n- **Optional integrations**: voice, PostHog, and transcription degrade\n  independently. Text-only reporting still works.\n- **Small surface area**: core package exports typed payloads, browser helpers,\n  an HTTP adapter, and an Astro/Cloudflare route helper.\n\n## Integration Model\n\n```txt\nBrowser reporter\n  -> captures page + element + optional files + optional replay id\n  -> POST /api/bug-report\n  -> your server checks auth and redacts\n  -> Linear issue + attachments + optional transcript\n  -> optional Claude Code enrichment comment\n```\n\n## Demo\n\nTry the static GitHub Pages demo:\n\nhttps://alunsoldantarctica.github.io/bug-reporter/\n\nThe demo uses a mock submitter. It is safe to run on GitHub Pages because it does\nnot contain Linear, PostHog, or AI Gateway credentials.\n\n## AI Agent Docs\n\nFor LLM crawlers and coding agents:\n\n- [`llms.txt`](./llms.txt) — compact package summary and integration guidance\n- [`AGENTS.md`](./AGENTS.md) — step-by-step agent install instructions\n\n## What It Supports\n\n- Floating bug reporter for public pages\n- Header/admin report button flows\n- Visual element picking\n- Text-node picking for copy, labels, headings, and inline content\n- Optional screenshot and element metadata capture\n- Optional microphone narration\n- WAV conversion for broader browser/tool compatibility\n- Optional PostHog session replay links\n- Linear issue creation through a server adapter\n- Astro + Cloudflare Workers route helper\n- Claude Code routine example for enriching tickets with codebase context\n\n## What Your Team Gets\n\nInstead of this:\n\n```txt\n\"Checkout is weird on mobile\"\n```\n\nYou get this:\n\n```txt\nTitle: [site] /checkout: Submit button disabled after changing dates\nURL: https://app.example.com/checkout\nSelector: button[data-testid=\"checkout-submit\"]\nKind: text or element\nVisible text: Complete booking\nViewport: 390x844\nReplay: https://us.posthog.com/project/123/replay/...\nTranscript: \"I changed the departure date, then the button stayed disabled.\"\nAttachments: element screenshot, optional voice clip\n```\n\nThat is enough for an engineer or agent to search the codebase, identify likely\nowning components, reproduce the flow, and propose tests.\n\n## Feature Walkthrough\n\nThe GIFs use a fictional expedition-insurance site so behavior is clear without\ndepending on any production app.\n\n### Floating Reporter\n\n![Floating reporter flow](./docs/assets/floating-reporter.gif)\n\n### Element Picker\n\n![Element picker flow](./docs/assets/element-picker.gif)\n\n### Optional Integrations\n\n![Integration setup flow](./docs/assets/integrations.gif)\n\n## Install\n\n```sh\nnpm install @alunsoldgroup/bug-reporter\n```\n\nPeer dependencies:\n\n```sh\nnpm install react react-dom\n```\n\n## Quick Start\n\nSend reports to your own server endpoint:\n\n```ts\nimport { createHttpBugReportAdapter } from \"@alunsoldgroup/bug-reporter\";\n\nconst bugReporter = createHttpBugReportAdapter(\"/api/bug-report\");\n\nawait bugReporter.submit({\n  source: \"site\",\n  surface: window.location.pathname,\n  url: window.location.href,\n  message: \"The quote button is disabled after changing dates.\",\n  severity: \"medium\",\n  userAgent: navigator.userAgent,\n  replaySessionId: window.posthog?.get_session_id?.(),\n});\n```\n\nWhen files are present, the HTTP adapter sends `multipart/form-data`.\nOtherwise it sends JSON.\n\n## Element and Text Picking\n\nUse `pickTargetFromPoint(x, y)` when building a custom picker. It resolves:\n\n- normal DOM elements\n- React/Astro component output, via the concrete DOM element under the cursor\n- text nodes, via `caretPositionFromPoint` / `caretRangeFromPoint`\n\nText picks return `kind: \"text\"`, the parent element for screenshots/selectors,\nand the exact text node content when the browser exposes it.\n\n## Astro on Cloudflare Workers\n\nCreate an API route:\n\n```ts\n// src/pages/api/bug-report.ts\nimport type { APIRoute } from \"astro\";\nimport { createAstroCloudflareBugReportHandler } from \"@alunsoldgroup/bug-reporter\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n  const handle = createAstroCloudflareBugReportHandler({\n    env: locals.runtime.env,\n    requireAuth: (req) => Boolean(req.headers.get(\"cookie\")?.includes(\"staff_session=\")),\n  });\n\n  return handle(request);\n};\n```\n\nFull example:\n\n`examples/astro-cloudflare/src/pages/api/bug-report.ts`\n\n## Cloudflare Bindings\n\nRequired for Linear filing:\n\n```txt\nLINEAR_API_TOKEN\n```\n\nOptional:\n\n```txt\nLINEAR_TEAM_KEY=ENG\nLINEAR_LABELS=bug,reported-from-app\nPOSTHOG_PROJECT_ID=12345\nPOSTHOG_HOST=https://us.posthog.com\nAI_GATEWAY_URL=https://gateway.ai.cloudflare.com/v1/<account>/<gateway>\nAI_GATEWAY_TOKEN=<cloudflare-ai-gateway-token>\n```\n\n`AI_GATEWAY_URL` and `AI_GATEWAY_TOKEN` enable best-effort audio transcription\nthrough Groq Whisper via Cloudflare AI Gateway. Provider keys stay server-side.\n\n## Public Demo vs Production\n\nGitHub Pages can host the floating-button demo because it is static browser\ncode. It cannot safely create real Linear tickets or transcribe audio because\nthose require secrets.\n\nRecommended split:\n\n- GitHub Pages: static demo, mock submitter\n- Production app: authenticated UI\n- Cloudflare Worker/Astro route: Linear, PostHog, AI Gateway, redaction, auth\n\n## Suggested Bug Workflow\n\n1. Render the reporter only for trusted users.\n2. Reporter selects the broken UI element.\n3. Reporter adds text, severity, optional voice, optional replay.\n4. Server creates the Linear issue and attaches screenshots/audio.\n5. Automation enriches the ticket with codebase context.\n\nThe value is in the metadata. A vague report like \"button broken\" becomes:\n\n```txt\nURL: /quote\nSelector: .operator-card[data-slug=\"quark\"]\nVisible text: Quark Expeditions\nViewport: 390x844\nPostHog replay: https://...\nVoice transcript: \"I changed dates and the operator disappeared.\"\n```\n\n## Claude Code Ticket Enrichment\n\nThis repo includes an example routine:\n\n`examples/claude-code/linear-bug-context-routine.md`\n\nThe intended automation:\n\n1. Linear webhook fires for new bug-reporter tickets.\n2. A Worker, CI job, or local script starts Claude Code in your repo.\n3. The routine reads the Linear issue, comments, screenshots, transcript, and\n   replay URL.\n4. It searches for matching routes, visible text, selectors, test ids, and\n   analytics events.\n5. It posts a concise Linear comment with likely owning files, reproduction\n   path, first hypothesis, confidence, and suggested tests.\n\nExample enrichment:\n\n```md\nLikely owning surface:\n- `src/pages/quote.astro`\n- `src/components/QuoteWizard.tsx`\n- `src/components/quote-wizard/Step3Operator.tsx`\n\nWhy:\n- Reported URL is `/quote`.\n- Picked selector points to the operator card grid.\n- Visible text matches the operator selection step.\n- Replay should confirm whether state resets after date changes.\n\nFirst hypothesis:\nChanging dates resets wizard state and clears selected operator before submit.\n\nSuggested tests:\n- Unit test for date changes preserving selected operator.\n- Playwright path covering destination, dates, operator, back, date edit, submit.\n\nConfidence: medium. Need replay check before implementation.\n```\n\n## Security Model\n\nDo not expose ticketing, analytics, or transcription keys to the browser.\n\nRecommended production rules:\n\n- Gate the reporting route with staff/admin auth.\n- Redact sensitive fields before ticket creation.\n- Store `LINEAR_API_TOKEN` and `AI_GATEWAY_TOKEN` in platform secrets.\n- Treat PostHog replay links as internal-only.\n- Make microphone recording opt-in.\n- Disclose recording and retention behavior in your UI.\n\nThe package handles plumbing. Your app remains responsible for consent,\nauthorization, retention, and PII handling.\n\n## Public API\n\n```ts\ncreateHttpBugReportAdapter(endpoint?: string)\ncreateAstroCloudflareBugReportHandler(options)\npickAudioMime()\nblobToWav(blob)\nformatRecordingTime(seconds)\n```\n\nCore types:\n\n```ts\nBugReportPayload\nBugReportResult\nBugReportAdapter\nBugReportFile\nCapturedElement\nPostHogLike\n```\n\n## Publish\n\n```sh\npnpm run build\nnpm publish --access public\n```\n","readmeFilename":"README.md"}