Newv2.1.0
Annotation auto-imports — release tags + deploys land on every chart automatically
- GitHub Releases webhook: paste your perchlens annotation URL into any repo's webhook settings and every published release becomes a labelled vertical line on every chart on the site. Tag-named, described with the release title, drops within seconds of `gh release create`
- Vercel deploys webhook: same idea, for production deploys. "Deploy · main" lines tag every successful production deploy, described with the first line of the commit message. Preview deploys and errored deploys are ignored — only the events worth marking get marked
- Generic webhook: POST JSON to your site's annotation URL with a bearer token and we'll create the annotation. Body is `{ label, description?, occurredAt?, externalRef? }` — wire Zapier, cron, CI, or anything that can POST. The Twitter campaign launch at 9am Tuesday is one curl away
- New Settings → Integrations panel — one shared per-site webhook secret, three copyable URLs, brief setup steps inline for each integration, and a rotate-secret button with two-step confirmation. The secret is masked by default so screenshotting the panel doesn't leak it
- Pinned-events chip strip now shows source affordance: small Pin icon for events you pinned manually (brand emerald), small GitBranch icon for GitHub releases (muted), Rocket for Vercel deploys (muted), Lightning for generic webhooks (muted). Tooltip on each chip leads with the source label so screen readers + hover both get the context
- Mobile bottom sheet: "How AI traffic is detected" modal now renders as a Vaul drag-to-dismiss bottom sheet on phones, joining Pin event and Add conversion. Last centred modal in the dashboard cleared
- Monthly digest emails get their own template — subject becomes "<Month> in review — <site>" instead of the weekly-looking "Weekly · …" prefix that the shared template was producing; eyebrow and CTA copy are also monthly-framed. The data shape and the editorial typography pass from Day 25 are unchanged
- Under the hood: shared HMAC-SHA256 / HMAC-SHA1 / bearer-token verifiers in src/lib/webhook-secret.ts with constant-time comparison; raw-body reading on all three webhook routes (re-parsing JSON would break signatures); dedup by externalRef so idempotent retries from GitHub/Vercel update in place instead of duplicating