npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@keystrokehq/sentry

v0.0.11

Published

Official Keystroke integration for [Sentry](https://sentry.io).

Readme

@keystrokehq/sentry

Official Keystroke integration for Sentry.

  • 176 operations across 21 resource domains (issues, releases, projects, monitors, replays, dashboards, alerts, Discover, SCIM, …).
  • 27 direct-binding triggers: 16 integration-platform webhooks (issue / error / comment / alert lifecycle), 7 Seer Autofix events, 2 preprod-artifact events, 1 legacy project service-hook, and 1 parameterised Discover polling trigger.
  • OAuth 2.0 (refreshable) public connection with provider-specific exchangeCode and extractInstallationInfo hooks. Bearer-token tenants (user / organisation / internal-integration tokens) run through the same runtime path — the token is resolved into the same Authorization: Bearer header.
  • Built-in HMAC-SHA256 verification, region-URL override for us.sentry.io / de.sentry.io / self-hosted deployments, RFC 5988 Link-header pagination, and DSN-vs-token guard-rails.

Install

pnpm add @keystrokehq/sentry

The package is ESM-only, side-effect free, and ships typed subpath exports. End-user authoring code imports from subpaths (./connection, ./issues, ./triggers, …) — never from the package root.

Credentials

Most customers connect via OAuth. The platform persists the access token under SENTRY_ACCESS_TOKEN, the refresh token under SENTRY_REFRESH_TOKEN, and (when resolved at install time) the installed organisation slug plus region URL. Workflow authors receive the resolved SentryIntegrationCredentials shape:

import type { SentryIntegrationCredentials } from '@keystrokehq/sentry/connection';

| Field | Required | Notes | | ------------------- | -------- | ------------------------------------------------------ | | SENTRY_ACCESS_TOKEN | ✅ | OAuth access token or long-lived auth token. | | SENTRY_REGION_URL | optional | Defaults to https://sentry.io. Set for us. / de. multi-region, or a self-hosted host. | | SENTRY_ORG_SLUG | optional | Default organisation slug used when an operation omits organization_slug. |

Platform operators supply the Sentry app credentials (client_id, client_secret, webhook_secret) through the environment keys KEYSTROKE_OFFICIAL_SENTRY_CLIENT_ID, _CLIENT_SECRET, and _WEBHOOK_SECRET. These are internal — they never reach authored workflow code.

OAuth scope matrix

| Capability | Scopes you need | | -------------------------------------------- | ------------------------------------------------ | | Read orgs, projects, teams, members, issues | org:read project:read event:read member:read team:read | | Update issue status / assignee / archive | event:admin project:write | | Manage alert rules (metric + issue) | alerts:read alerts:write | | Create and update releases / deploys / files | release:admin | | Manage project keys (DSN rotation) | project:admin | | SCIM user / group provisioning | member:write team:admin |

The default OAuth flow requests the superset above. Trim the scope list in your platform config if you only need a narrower subset.

Quickstart — Sentry → Linear + Slack fan-out

import { getOrganizationIssueDetails, updateIssueAttributesInOrganization } from '@keystrokehq/sentry/issues';
import { on } from '@keystrokehq/sentry/triggers';
import { createIssue } from '@keystrokehq/linear/issues';
import { sendMessage } from '@keystrokehq/slack/platform/messages';
import { Workflow } from '@keystrokehq/core';

export const sentryFanOut = new Workflow({
  id: 'sentry-fan-out',
  name: 'Sentry → Linear + Slack',
  triggers: [
    on.issueCreated({
      filter: (event) => event.data.issue.level !== 'info',
      transform: (event) => ({
        sentryIssueId: event.data.issue.id,
        title: event.data.issue.title ?? 'Unknown Sentry issue',
        url: event.data.issue.web_url ?? null,
      }),
    }),
  ],
  run: async ({ input, run }) => {
    const issue = await run(getOrganizationIssueDetails, {
      input: { issue_id: input.sentryIssueId },
    });

    const linearIssue = await run(createIssue, {
      input: {
        teamId: 'TEAM_UUID',
        title: issue.title ?? input.title,
        description: `Sentry: ${input.url ?? 'no url'}`,
      },
    });

    await run(sendMessage, {
      input: {
        channel: '#oncall',
        text: `:rotating_light: ${input.title}\nLinear: ${linearIssue.issue?.url ?? 'pending'}\nSentry: ${input.url ?? ''}`,
      },
    });

    await run(updateIssueAttributesInOrganization, {
      input: {
        id: [input.sentryIssueId],
        assignedTo: 'team:oncall',
        statusDetails: { linear_url: linearIssue.issue?.url },
      },
    });
  },
});

Public surface

End-user authoring (operations)

| Subpath | Domain | | ----------------------------------------------- | ---------------------------------------------------------- | | @keystrokehq/sentry/organizations | 15 operations — orgs, stats, integrations | | @keystrokehq/sentry/members | 7 operations — member CRUD + invites | | @keystrokehq/sentry/teams | 14 operations — team CRUD + external-team links | | @keystrokehq/sentry/projects | 19 operations — project CRUD, filters, ownership, symbols | | @keystrokehq/sentry/project-keys | 5 operations — DSN / client key management | | @keystrokehq/sentry/issues | 13 operations — issue lifecycle + external-issue links | | @keystrokehq/sentry/events-api | 7 operations — issue events, project events, Discover | | @keystrokehq/sentry/releases | 21 operations — releases, files, repos, commits | | @keystrokehq/sentry/deploys | 2 operations — record + list deploys per release | | @keystrokehq/sentry/environments | 3 operations — project environment management | | @keystrokehq/sentry/alerts | 11 operations — metric + issue alert rules | | @keystrokehq/sentry/notifications | 5 operations — notification actions | | @keystrokehq/sentry/monitors | 10 operations — cron monitors + check-ins | | @keystrokehq/sentry/dashboards | 5 operations — organisation dashboards | | @keystrokehq/sentry/discover | 5 operations — saved Discover queries | | @keystrokehq/sentry/webhooks | 5 operations — legacy project service hook CRUD | | @keystrokehq/sentry/replays | 9 operations — Session Replay | | @keystrokehq/sentry/feedback | 2 operations — user feedback | | @keystrokehq/sentry/debug-files | 3 operations — DIF / dSYM upload | | @keystrokehq/sentry/scim | 11 operations — SCIM + SAML + external users | | @keystrokehq/sentry/user-emails | 4 operations — account email management |

End-user authoring (triggers)

import { on, webhooks, polling } from '@keystrokehq/sentry/triggers';
  • on.<event>({ filter, transform, name, description }) — integration-platform webhooks. Available events:
    • installationCreated, installationDeleted
    • issueCreated, issueResolved, issueAssigned, issueUnresolved, issueIgnored, issueArchived
    • errorCreated
    • commentCreated, commentUpdated, commentDeleted
    • eventAlertTriggered
    • metricAlertCritical, metricAlertWarning, metricAlertResolved
    • Seer: seerRootCauseStarted, seerRootCauseCompleted, seerSolutionStarted, seerSolutionCompleted, seerCodingStarted, seerCodingCompleted, seerPrCreated
    • Preprod artifacts: preprodSizeAnalysisCompleted, preprodBuildDistributionCompleted
  • webhooks.serviceHookEventAlert({ filter, transform }) — legacy per-project service-hook binding. Signs with the per-hook secret, not the integration client secret.
  • polling.discoverEvents(params, options?) — parameterised polling over /api/0/organizations/{slug}/events/. Supply field, query, project, environment, statsPeriod, dataset, and optionally schedule.

Support surfaces

import { sentry, type SentryIntegrationCredentials } from '@keystrokehq/sentry/connection';
import { createSentryClient, type SentryCredentials } from '@keystrokehq/sentry/client';
import { sentryIssueSchema, sentryProjectSummarySchema } from '@keystrokehq/sentry/schemas';
import { sentryIssueCreatedEventSchema } from '@keystrokehq/sentry/events';
import { verifySentryWebhookRequest, verifySentryServiceHookRequest } from '@keystrokehq/sentry/verification';

Internal (do not import from application code)

  • @keystrokehq/sentry/_official — bundle export used by @keystrokehq/official-integration-catalog.
  • @keystrokehq/sentry/_runtime — reserved for hosted runtime plumbing.

Caveats

  • DSN ≠ auth token. The client rejects any value that parses as a Sentry DSN (a URL with a user@host component). DSNs are ingest-only.
  • Region routing. If a customer installs from us.sentry.io or de.sentry.io, the OAuth hook captures the region URL at install time. Self-hosted deployments must explicitly set SENTRY_REGION_URL on the credentials or the client will default to https://sentry.io.
  • Webhook timing. Integration-platform webhooks must respond within one second per Sentry's docs. Keep the transform path cheap and push work onto run callbacks.
  • Issue state migration. Sentry is migrating from ignoredarchived; both triggers are exposed. Collapse them in transform if you want a single "muted" state downstream.
  • Service hooks are deprecated. Prefer the integration-webhook path for new installs. The service-hook operations + trigger remain for backward compatibility.

Not yet supported

  • seer.coding_completed and preprod webhooks currently pass through raw payloads. When the payload schemas stabilise upstream, we will upgrade them to a strict shape.

License: MIT.