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

@statewavedev/connectors-jira

v0.4.2

Published

Jira Cloud source connector for Statewave — pulls issues and comments (and a real-time webhook receiver) into agent memory (preview)

Downloads

68

Readme

@statewavedev/connectors-jira

Preview Jira Cloud source connector for Statewave — turns Jira issues (and optionally their comments) into normalized episodes under project:<KEY>.

Part of the Statewave Connectors ecosystem. It ingests external Jira records into Statewave memory; it is not a Statewave storage backend.

Install

# the connector + the unified CLI to run it
npm install -g @statewavedev/connectors-cli
npm install @statewavedev/connectors-jira

The CLI (statewave-connectors) discovers the connector by name (sync jira). You can also import createJiraConnector from @statewavedev/connectors-jira directly in your own code.

Scope (preview)

  • Jira Cloud (REST v3, ADF) and Jira Server / Data Center (REST v2, plain-text) — pick with --deployment. See Jira Server / Data Center.
  • Auth: Cloud → email + API token (Basic). Server/DC → personal access token (Bearer) or username + password (Basic).
  • Pull mode + a real-time webhook receiver (listen jira) — see Webhook receiver.
  • Read-only — issues, opt-in comments + status transitions. Never writes to Jira.
  • Project allowlist required in pull mode (optional, recommended in webhook mode) — a connector instance only ingests the projects you name.
  • No email addresses — users are recorded by display name / username / accountId.

What it ingests

| Source | Episode kind | |---|---| | Issue (open) | jira.issue.created | | Issue (status category "done") | jira.issue.resolved | | Comment (opt-in via --include comments) | jira.comment.created | | Status change (opt-in via --include transitions) | jira.issue.transition |

Each episode carries source.url (a /browse/<KEY> link) for provenance, plus status, labels, assignee/reporter (display names), and timestamps in metadata.

Quickstart

export JIRA_EMAIL="[email protected]"
export JIRA_API_TOKEN="…"           # https://id.atlassian.com/manage-profile/security/api-tokens

statewave-connectors sync jira \
  --host https://myorg.atlassian.net \
  --projects ENG,PLATFORM \
  --dry-run

Add comments and redact PII from free text:

statewave-connectors sync jira \
  --host https://myorg.atlassian.net \
  --projects ENG \
  --include issues,comments \
  --redact-email --redact-phone --redact-secrets \
  --dry-run

--dry-run maps and prints episodes without ingesting. To actually ingest, drop --dry-run and point at your Statewave instance:

export STATEWAVE_URL="http://localhost:8100"
export STATEWAVE_API_KEY="…"   # if your instance requires one

statewave-connectors sync jira \
  --host https://myorg.atlassian.net \
  --projects ENG \
  --since 2026-01-01

Jira Server / Data Center

On-prem Jira differs from Cloud in three ways the connector handles via --deployment server:

| | Cloud (--deployment cloud, default) | Server / Data Center (--deployment server) | |---|---|---| | REST API | /rest/api/3 | /rest/api/2 | | Rich text | ADF (flattened to text) | plain text / wiki markup (used as-is) | | Auth | email + API token (Basic) | personal access token (Bearer) or username + password (Basic) |

export JIRA_BASE_URL="https://jira.your-company.com"
export JIRA_PAT="…"            # Data Center personal access token

statewave-connectors sync jira \
  --deployment server \
  --projects ENG,OPS \
  --dry-run

Everything else is shared: the same project:<KEY> subjects, ADF/plain-text → text normalization, no-email user fields (Server users resolve by displayName → username), redaction, project allowlist, and the issue/comment/transition kinds.

Verification status: the Server / Data Center path (v2 routing, Bearer-PAT and Basic auth, plain-text bodies, username display fields) is implemented against Atlassian's documented Server/DC API differences and covered by unit tests, but has not yet been validated against a live Jira Server / Data Center instance. Treat it as unverified until that round-trip is done; the Cloud path is exercised end-to-end. Tracking: statewave#193.

Webhook receiver (listen jira)

For real-time updates instead of (or alongside) polling, run the receiver — a pure (Request) => Promise<Response> handler, mountable on the built-in daemon, Vercel, Cloudflare, or Express. It dispatches the same jira.* kinds as the pull connector.

export JIRA_WEBHOOK_SECRET="…"          # the secret you set on the Jira admin webhook
export JIRA_BASE_URL="https://myorg.atlassian.net"
export STATEWAVE_URL="http://localhost:8100"
export STATEWAVE_API_KEY="…"

statewave-connectors listen jira --port 3000 --projects ENG,PLATFORM
# → http://0.0.0.0:3000/jira/events

Then register a Jira admin webhook (Jira Settings → System → Webhooks, or POST /rest/webhooks/1.0/webhook) pointing at the public address, set its secret to the same value, and subscribe to the issue/comment events. Expose the daemon publicly with a tunnel (ngrok / Cloudflare Tunnel) or your ingress.

Authentication — verified, not assumed. Jira admin webhooks sign every callback: they compute an HMAC over the raw body using your secret and send it as X-Hub-Signature: sha256=<hex> (Atlassian docs). The receiver recomputes that MAC with HMAC-SHA256 and rejects any mismatch in constant time before parsing or ingesting — there is no unauthenticated code path. It then dedups Jira's at-least-once retries, applies the optional --projects allowlist, normalizes with the same ADF→text / no-email path the pull connector uses, and ingests.

| Inbound webhookEvent | Episode kind | |---|---| | jira:issue_created, jira:issue_updated (open) | jira.issue.created | | jira:issue_updated (status category "done") | jira.issue.resolved | | comment_created, comment_updated | jira.comment.created |

jira:issue_deleted / comment_deleted and unrecognized events are acked (HTTP 200) and skipped — there is no delete episode kind.

Programmatic use:

import { createJiraWebhookHandler } from "@statewavedev/connectors-jira";

const handler = createJiraWebhookHandler({
  signingSecret: process.env.JIRA_WEBHOOK_SECRET!,
  baseUrl: "https://myorg.atlassian.net",
  projects: ["ENG"],            // optional allowlist
  redaction: { email: true },   // optional, parity with pull mode
  statewaveUrl: process.env.STATEWAVE_URL!,
  statewaveApiKey: process.env.STATEWAVE_API_KEY,
});
// export default handler;  // Vercel / Cloudflare

Transitions & sprint context (opt-in)

Both are off by default — the default stays the lightweight issue/comment mapping — and neither adds extra API calls or crawls boards/sprints.

Status transitions (--include transitions) request expand=changelog on the same issue search and emit one jira.issue.transition per status change (from/to status, actor, timestamp):

statewave-connectors sync jira \
  --host https://myorg.atlassian.net --projects ENG \
  --include issues,transitions --dry-run

The webhook receiver does the same automatically: a jira:issue_updated carrying a status change in its changelog emits both the issue snapshot and a jira.issue.transition (actor + time taken from the event).

Sprint context (--sprint-field <id>) names your Jira Sprint custom field (e.g. customfield_10020 — find it in the field's admin page or GET /rest/api/3/field). When set, that one field is added to the same search; the connector parses the array-of-objects sprint value into each issue's metadata.sprints and a sprint:<name> related subject. There is no Agile board/sprint enumeration — only the sprint already attached to the issue. The legacy serialized-string sprint format is not parsed.

statewave-connectors sync jira \
  --host https://myorg.atlassian.net --projects ENG \
  --sprint-field customfield_10020 --dry-run

Subject strategy

Each issue/comment lands under project:<KEY> (e.g. project:ENG) — the project the issue belongs to, so an agent can ask about a project's history. Override with --subject <value> to pin every episode to one subject instead.

Example episode

{
  "subject": "project:ENG",
  "kind": "jira.issue.resolved",
  "text": "Ada L resolved issue ENG-128: Login fails on Safari\n\nUsers on Safari 17 hit a redirect loop after SSO.",
  "occurred_at": "2026-05-20T14:03:00.000Z",
  "source": {
    "type": "jira.issue",
    "id": "ENG-128",
    "url": "https://myorg.atlassian.net/browse/ENG-128"
  },
  "metadata": {
    "issue_key": "ENG-128",
    "project_key": "ENG",
    "status": "Done",
    "status_category": "done",
    "issue_type": "Bug",
    "priority": "High",
    "labels": ["auth", "safari"],
    "assignee": "Ada L",
    "reporter": "Bob R",
    "related_subjects": ["issue:ENG-128", "assignee:Ada L"]
  },
  "idempotency_key": "…"
}

To get this exact shape, run the quickstart above with --dry-run --json.

Status

Preview. Pull mode (issues, comments, opt-in status transitions, opt-in sprint context) plus a webhook receiver (listen jira) with verified X-Hub-Signature HMAC-SHA256. Jira Cloud is exercised end-to-end. Jira Server / Data Center (--deployment server) is implemented + unit-tested but not yet validated against a live on-prem instance — see Jira Server / Data Center.