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

@888aaen/jira-cli

v1.4.0

Published

Jira CLI — kubectl for Jira, designed for AI agents and automation

Readme

jira-cli

A non-interactive CLI for Jira built for AI agents, CI, and automation. All output is machine-readable JSON by default, so it drops straight into jq pipelines, shell scripts, and LLM tool calling.

jira search jql "assignee = currentUser() AND status != Done" | jq -r '.[].key'

Why use this

  • JSON by default, clean streams. Results go to stdout, all diagnostics to stderr, and failures return a non-zero exit code. jq, rg, and wc work without choking on error blobs, and scripts check $? instead of parsing strings.
  • Auth stays out of band. You log in once; the token lives in the OS keychain and is never written to disk or exposed to an agent. Execution inherits an already-authenticated environment.
  • Inspectable, scoped state. jira context set --project PROJ pins defaults on disk so you don't repeat --project on every call — and you can read back exactly what scope you're operating in.
  • Lean output. Project only the fields you need with repeatable -F customfield_x flags, keeping responses (and token usage) small.
  • No daemon, no custom protocol. It's a plain binary. Every action is one replayable command line — debug by copying it from your shell history and running it again.
  • Server-side audit. jira me audit --date YYYY-MM-DD reconstructs what actually changed on a given day from Jira's own changelog, independent of local state.

See What makes this an agent CLI for the longer rationale.

Why not the existing jira-cli?

This project is inspired by ankitpokhrel/jira-cli — a feature-rich interactive Jira command line with a full TUI (tables, keyboard navigation, prompts). Think of it as the k9s of Jira: visual and built for humans at a terminal.

This takes the opposite approach — the kubectl of Jira: non-interactive, scriptable, and built for agents and automation. No TUI, no prompts, just structured output machines can parse. Want a great interactive experience? Use that one. Want to wire Jira into an AI agent, CI pipeline, or shell script? Use this.

Install

npm (recommended)

npm install -g @888aaen/jira-cli

Installs the jira binary for macOS (arm64, x64), Linux (x64, arm64), and Windows (x64).

Build from source

Prerequisites: Go 1.25+

git clone https://github.com/AndersSpringborg/jira-agent-cli.git
cd jira-agent-cli
sudo make install      # builds and installs to /usr/local/bin/jira
sudo make uninstall    # to remove

Quick Start (AI agent)

Give an agent Jira access in two commands:

npm install -g @888aaen/jira-cli
npx skills@latest add AndersSpringborg/jira-agent-cli

The first installs the jira binary. The second installs the jira-cli skill into ~/.claude/skills/jira-cli/, so any Claude Code agent on the machine learns to drive it — it checks for an existing session, guides you through login if needed, and picks the right command for each request.

Quick Start (manual)

1. Authenticate

Create an API token at https://id.atlassian.com/manage-profile/security/api-tokens, then:

jira auth login --server https://your-org.atlassian.net \
  --email [email protected] --token YOUR_API_TOKEN

The token is stored in the OS keychain — never written to disk.

Jira Cloud and Server/Data Center. Cloud profiles (*.atlassian.net) use basic auth + REST v3 + ADF bodies. Server/Data Center profiles use PAT/bearer auth + REST v2 + wiki/plain text bodies.

2. Verify and set defaults

jira ping                              # check connectivity
jira context set --project PROJ        # default project for subsequent commands
jira context set --board-id 42
jira context set --display markdown    # human-readable output everywhere (json is the default)

A per-command --format flag always overrides the context default. See Output Formats.

3. Use it

jira issue list                                          # issues in your project
jira issue view PROJ-123
jira issue create -p PROJ -s "Fix login bug" -t Bug
jira search jql "project = PROJ AND status = 'In Progress'"
jira issue list | jq '.[].key'

Output Formats

| Flag | Description | |---------------------|------------------------------------------| | --format json | Machine-readable JSON (default) | | --format markdown | Structured markdown, fewer tokens for LLMs |

Set a persistent default with jira context set --display markdown; --format always overrides it.

Writing to Jira

Every mutation is a single command with explicit flags, so the transcript line is exactly what changed. Write commands print the result as JSON and exit non-zero on failure, so you can chain them with && and check the exit code.

# Create (prints structured JSON with .key; add --raw for the full Jira response)
jira issue create -p PROJ -s "Fix login bug" -t Bug -b "Steps to reproduce..."

# Edit fields, including custom fields by id (-F is repeatable)
jira issue edit PROJ-123 -s "New summary" -l backend -F customfield_10145="value"

# Transition through the workflow
jira issue move PROJ-123 "In Progress"
jira issue move PROJ-123 Done --resolution Fixed --comment "Shipped in v1.2"

# Assign and comment ('me' for yourself, 'x' to unassign; otherwise pass an account ID,
# username, or email resolvable by `jira user search`)
jira issue assign PROJ-123 me
jira issue comment add PROJ-123 "Investigated -- root cause was a stale cache."

# Link, clone, delete
jira issue link PROJ-123 PROJ-456 "blocks"
jira issue clone PROJ-123 -s "Follow-up: ..."
jira issue delete PROJ-123

# Sprint management
jira sprint add 42 PROJ-123 PROJ-456

Capture a created key and act on it in the same script:

key=$(jira issue create -p PROJ -s "Automated task" -t Task | jq -r '.key')
jira issue move "$key" "In Progress" && jira issue assign "$key" me

Run jira issue <verb> --help for the full flag set on any command.

Commands

| Command | Description | |----------------|----------------------------------------------| | jira auth | Login, logout, status, whoami | | jira config | Manage profiles (init, list, show, set, use, delete) | | jira context | Set default filters (project, board, labels, etc.) | | jira issue | Full issue lifecycle (list, view, create, edit, delete, assign, move, comment, link, clone) | | jira board | List boards, view board issues | | jira sprint | List, start, close sprints; add issues | | jira project | List and view projects | | jira search | JQL and full-text search | | jira user | Search and get users | | jira me | Show current user; me audit for daily activity | | jira mine | List issues assigned to you | | jira open | Open project or issue in browser | | jira ping | Check connectivity to Jira |

Run jira <command> --help for details on any command.

Configuration

Config lives at ~/.config/jira-cli/config.yml. You normally don't edit it by hand — use the jira config and jira context commands.

Profiles

Manage multiple Jira instances:

jira config init --profile work --base-url https://work.atlassian.net
jira auth login --profile work --server https://work.atlassian.net \
  --email [email protected] --token YOUR_TOKEN
jira config use work                 # switch default
jira issue list --profile work       # use a profile for one command

Environment Variables

These override config file values and are useful in CI/automation:

| Variable | Description | |-------------------|-----------------------------------| | JIRA_BASE_URL | Jira server URL | | JIRA_TOKEN | API token (bypasses OS keychain) | | JIRA_EMAIL | User email | | JIRA_AUTH_TYPE | Auth type: basic or pat | | JIRABOT_PROFILE | Profile name to use |

What makes this an agent CLI

Out-of-band authentication

Authentication and execution are decoupled. A human or CI process runs jira auth login once; the token is stored in the OS keychain, never on disk. An agent never sees, requests, or routes the credential — it inherits an already-authenticated environment, and access is revoked system-side without any model trust.

Inspectable state and blast-radius control

jira context set --project PROJ --board-id 42 writes default parameters to disk, restricting the default operating scope without an agent having to append --project to every call. The context is explicit, inspectable state; breaking scope requires an explicit per-command override (e.g. --profile).

Built for the Unix pipe

The CLI leans on standard tools (jq, rg, grep, wc) instead of a bespoke processing engine. stdout carries only the result; diagnostics, warnings, and errors go to stderr, so pipelines never choke on error output. Failed calls return a non-zero exit code, so success/failure is read from $? rather than parsed from text.

jira search jql "assignee = currentUser()" | jq -r '.[].key'
jira issue list | jq '[.[] | select(.status.name=="Done")] | length'
jira issue view CER-1 --raw | rg -o '"customfield_\d+"'

Non-mutating discovery and field projection

Read paths (search jql, search text, issue list, mine, issue view) are non-mutating and return consistent, keyed JSON (key, fields.*). Custom-field projection keeps responses small so an agent retrieves only what it needs via repeatable --field/-F flags; issue view also keeps --fields as a comma-separated alias.

CLI over MCP

Rather than running a Model Context Protocol server, this is a standard binary: no long-lived daemon, no open socket, no persistent state between executions. Every action is the exact execution string, so debugging is just re-running the command from shell history, and agents reuse shell operators (&&, ||, |, >) instead of learning a custom RPC protocol.

Dual-layer auditing

Verification rests on hard records, not transcripts. Shell history is a replayable record of what was attempted — every input is a command-line argument, not hidden state. jira me audit --date YYYY-MM-DD queries Jira's server-side changelog to reconstruct what actually mutated on a given day for the authenticated user, independent of local terminal state.