git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/jirahhh" ~/.claude/skills/majiayu000-claude-skill-registry-jirahhh && rm -rf "$T"
skills/data/jirahhh/SKILL.mdJira CLI Guide - jirahhh
Complete reference for using the
jirahhh CLI tool to create, update, view, and search Jira issues with proper formatting and custom field support.
Repository: https://github.com/shanemcd/jirahhh
Quick Start
The easiest way to use
jirahhh is with uvx - no installation or repository cloning required:
# View an issue uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env prod # Create an issue uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env prod \ --project AAP \ --type Task \ --summary "My Task Title" \ --description "Task description here" \ --acceptance-criteria "- Criteria 1" # Search for issues uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ "project = AAP AND status = Open" \ --env prod \ --max-results 10
Tip: Add an alias to your shell for convenience:
alias jirahhh='uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh' # Then use it simply: jirahhh view AAP-12345 --env prod
Available Commands
The
jirahhh CLI has six subcommands:
- Create new Jira issues with markdown supportcreate
- Update existing issuesupdate
- View issue details with all fieldsview
- Search issues using JQL queriessearch
- List available fields for a project/issue typefields
- Make generic API calls to Jira REST APIapi
Common Operations
View an Issue
# View with all details uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view ANSTRAT-1567 --env prod # View specific fields uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 \ --env stage \ --fields "summary,status,description,assignee"
Create an Issue
With inline description:
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env prod \ --project AAP \ --type Task \ --summary "My Task Title" \ --description "Task description" \ --acceptance-criteria "- Must do X\n- Must do Y"
With markdown file (recommended for complex issues):
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env prod \ --project AAP \ --type Epic \ --summary "My Epic Title" \ --epic-name "My Epic Name" \ --parent ANSTRAT-1234 \ --description "path/to/description.md" \ --acceptance-criteria "path/to/acceptance-criteria.md"
The
--description parameter automatically detects .md files and converts markdown to Jira wiki markup using pypandoc.
Create Initiative with child Epic:
# 1. Create Initiative uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env prod \ --project ANSTRAT \ --type Initiative \ --summary "My Initiative" \ --description "description.md" \ --acceptance-criteria "- Acceptance criteria" # 2. Create child Epic (use ANSTRAT-XXXX from step 1 as parent) uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env prod \ --project AAP \ --type Epic \ --summary "My Epic" \ --epic-name "My Epic" \ --parent ANSTRAT-1586 \ --description "description.md" \ --acceptance-criteria "- Acceptance criteria"
Update an Issue
# Update summary uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh update AAP-12345 \ --env prod \ --summary "New Title" # Update description from markdown file uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh update AAP-12345 \ --env stage \ --description "path/to/updated.md" # Update multiple fields uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh update AAP-12345 \ --env prod \ --summary "Updated Title" \ --description "updated.md" \ --acceptance-criteria "- New criteria"
Search for Issues
# Basic JQL search uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ "project = AAP AND status = Open" \ --env prod \ --max-results 10 # Search with custom fields uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ "assignee = currentUser() ORDER BY created DESC" \ --env stage \ --fields "summary,status,priority,assignee" \ --max-results 10 # Find issues in an Epic uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ "'Epic Link' = AAP-12345" \ --env prod \ --max-results 100 # Find child issues of a parent (IMPORTANT: use "Parent Link" not "parent") uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ '"Parent Link" = ANSTRAT-1567' \ --env prod # Find child issues across all projects (AAP epics under ANSTRAT features) uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh search \ '"Parent Link" = ANSTRAT-1567 ORDER BY created ASC' \ --env prod \ --max-results 50
Discover Available Fields
# List all fields uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh fields --env prod # List fields for specific project and issue type (shows required fields) uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh fields \ --project AAP \ --type Epic \ --env stage
This shows which fields are required and available for creating that issue type.
Make Generic API Calls
# Get issue comments uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh api GET \ /rest/api/2/issue/AAP-12345/comment \ --env prod # Add a comment uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh api POST \ /rest/api/2/issue/AAP-12345/comment \ --env stage \ --data '{"body": "This is a comment"}' # Mention a user in a comment (use full email address) uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh api POST \ /rest/api/2/issue/AAP-12345/comment \ --env prod \ --data '{"body": "Thanks [~user@redhat.com] for the feedback!"}' # Get available transitions uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh api GET \ /rest/api/2/issue/AAP-12345/transitions \ --env prod # Transition an issue uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh api POST \ /rest/api/2/issue/AAP-12345/transitions \ --env stage \ --data '{"transition": {"id": "5"}}'
Configuration
Step 1: Generate Jira API Token
For Red Hat Jira (issues.redhat.com):
- Go to https://issues.redhat.com
- Click your profile icon (top right) → Profile
- Click Personal Access Tokens in the left sidebar
- Click Create token
- Give it a name (e.g., "jirahhh CLI")
- Set expiration (recommend 1 year or non-expiring for personal use)
- Click Create
- Copy the token immediately - you won't be able to see it again!
For Stage Jira (issues.stage.redhat.com):
- Follow the same steps but at https://issues.stage.redhat.com
- You'll need a separate token for stage
Step 2: Create Config File (Recommended)
Create
~/.config/jirahhh/config.yaml:
# Jira Configuration File stage: url: "https://issues.stage.redhat.com" token: "your-stage-token-here" proxy: "http://squid.corp.redhat.com:3128" prod: url: "https://issues.redhat.com" token: "your-prod-token-here" # Custom field IDs for ANSTRAT/AAP projects (optional - already in code) custom_fields: acceptance_criteria: "customfield_12315940" epic_name: "customfield_12311141" parent_link: "customfield_12313140" epic_link: "customfield_12311140" # Security level IDs (optional - already in code) security_levels: default: "11795" # Red Hat Employee
Create the config directory and file:
mkdir -p ~/.config/jirahhh nano ~/.config/jirahhh/config.yaml # or use your preferred editor
Then use
--env flag to switch between environments:
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env stage uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env prod
Alternative: Environment Variable
If you prefer not to store tokens in a config file:
export JIRA_API_TOKEN="your-token" uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env prod
The environment variable overrides the config file if both are present.
Important Notes
- Stage requires proxy: The Red Hat proxy (
) is required for stage Jira accesssquid.corp.redhat.com:3128 - Prod does NOT use proxy: Production Jira is directly accessible
- Token security: Keep your tokens secure - don't commit them to git
- Token expiration: Set reminders to regenerate tokens before they expire
Important Project Rules
Project Selection
- ANSTRAT project for: Initiative, Outcome, Feature
- AAP project for: Epic, Story, Task, Bug, Sub-task
ANSTRAT is for strategic planning and high-level features. AAP is for implementation work (Epics and below).
Required Fields
Acceptance Criteria - Required for ALL issue types in ANSTRAT/AAP projects:
- Field ID:
customfield_12315940 - Always include
parameter when creating issues--acceptance-criteria
Epic Name - Required when creating Epic issue type:
- Field ID:
customfield_12311141 - Include
parameter when--epic-name--type Epic
Security Level
All issues are automatically created with "Red Hat Employee" security level (ID: 11795), which restricts access to Red Hat employees and contractors only. This is set automatically and cannot be disabled.
Custom Fields Reference
Common custom field IDs used in ANSTRAT/AAP projects:
| Field | Field ID | Usage |
|---|---|---|
| Acceptance Criteria | | Required for all issue types |
| Epic Name | | Required when creating Epics |
| Parent Link | | Links child to parent issue |
| Epic Link | | Links issue to an Epic |
Important: Finding Child Issues
CRITICAL: To find child issues of a parent, you MUST use
"Parent Link" (the custom field name), NOT parent (the JQL keyword).
❌ WRONG - This will NOT work:
jirahhh search "parent = ANSTRAT-1567" --env prod # Returns 0 results even if children exist!
✅ CORRECT - Use "Parent Link" field name:
jirahhh search '"Parent Link" = ANSTRAT-1567' --env prod # Returns all child issues across all projects (AAP epics under ANSTRAT feature, etc.)
Why this matters:
is a JQL keyword that only works for subtasks (not Epics/Stories/Tasks)parent =
is the custom field name (customfield_12313140) that works for all parent-child relationships"Parent Link"- Child issues can exist in different projects (e.g., AAP epics under ANSTRAT features)
- Using
searches across ALL projects for children"Parent Link"
Common use case:
# Find all child epics under ANSTRAT-1567 feature jirahhh search '"Parent Link" = ANSTRAT-1567 ORDER BY created ASC' \ --env prod \ --max-results 50 \ --fields "summary,status,issuetype,assignee"
This will return child issues from ANY project (ANSTRAT, AAP, etc.) that have ANSTRAT-1567 as their parent.
Command Reference
jirahhh create
jirahhh createRequired:
- Project key (ANSTRAT, AAP)--project
- Issue title--summary
- Issue type (Initiative, Epic, Story, Task, Spike, Bug)--type
Description (one required):
- Inline text or path to file (.md auto-converted, .txt used as-is)--description
- Path to Jira wiki markup file (use--description-file
for stdin)-
Optional:
- Acceptance criteria (required in ANSTRAT/AAP)--acceptance-criteria
- Epic name (required when creating Epic)--epic-name
- Parent issue key (e.g., ANSTRAT-1587)--parent
- Epic to link to (e.g., AAP-12345)--epic-link
- Environment:--env
orstage
(default: stage)prod
jirahhh update
jirahhh updateRequired:
- Issue key to update (positional, e.g., AAP-12345)issue_key
Optional (at least one should be provided):
- New title--summary
- Inline text or path to file (.md auto-converted)--description
- Path to Jira wiki markup file (use--description-file
for stdin)-
- New acceptance criteria--acceptance-criteria
- Environment:--env
orstage
(default: stage)prod
jirahhh view
jirahhh viewRequired:
- Issue key to view (positional, e.g., AAP-12345)issue_key
Optional:
- Comma-separated list of fields (default: all common fields)--fields
- Environment:--env
orstage
(default: stage)prod
jirahhh search
jirahhh searchRequired:
- JQL query string (positional, e.g.,jql
)"project = AAP AND status = Open"
Optional:
- Comma-separated fields (default: summary,status,issuetype,assignee)--fields
- Maximum results to return (default: 50)--max-results
- Environment:--env
orstage
(default: stage)prod
jirahhh fields
jirahhh fieldsOptional:
- Project key to filter (e.g., AAP)--project
- Issue type to filter (e.g., Epic)--type
- Environment:--env
orstage
(default: stage)prod
When
--project and --type are specified, shows which fields are required for creating that issue type.
jirahhh api
jirahhh apiRequired:
- HTTP method: GET, POST, PUT, DELETEmethod
- API endpoint path (e.g.,endpoint
)/rest/api/2/issue/AAP-12345/comment
Optional:
- JSON data for POST/PUT requests--data
- Environment:--env
orstage
(default: stage)prod
Markdown Conversion
The CLI automatically converts markdown files to Jira wiki markup when you use
.md file extensions.
Supported conversions:
- Headers:
→####h4. - Bold:
→**text***text* - Bullets:
→-* - Links:
→[text](url)[text|url] - Anchors:
→<span id="anchor"></span>{anchor:anchor}
Round-trip workflow:
- Pull from Jira:
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view ANSTRAT-1587 --env prod # Manually convert output to markdown using pandoc if needed
-
Edit markdown locally in your preferred editor
-
Push back to Jira:
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh update ANSTRAT-1587 \ --env stage \ --description "path/to/updated.md"
Draft Workflow
Organize markdown files before creating issues:
Drafts/ └── Initiative - Title/ ├── description.md ├── acceptance-criteria.md └── Epic - Title/ ├── description.md ├── acceptance-criteria.md └── Story - Title/ ├── description.md └── acceptance-criteria.md
Then create issues from the markdown files:
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create \ --env stage \ --project AAP \ --type Epic \ --summary "Epic Title" \ --epic-name "Epic Title" \ --parent ANSTRAT-1234 \ --description "Drafts/Initiative - Title/Epic - Title/description.md" \ --acceptance-criteria "Drafts/Initiative - Title/Epic - Title/acceptance-criteria.md"
Environment Switching
The
--env flag automatically configures everything:
Stage (auto-enables proxy):
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create --env stage ... uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env stage
Prod (auto-sets URL, no proxy):
uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh create --env prod ... uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh view AAP-12345 --env prod
The
--env flag:
- Selects correct token from config file
- Sets appropriate Jira URL (stage or prod)
- Enables/disables proxy as needed
Key Features
- No installation required: Use
to run directly from GitHubuvx - Markdown support: Write issues in markdown, auto-convert to Jira format
- Environment-aware: Simple
flag switches between stage and prod--env - Custom fields: Automatic handling of acceptance criteria, epic name, parent links
- JQL search: Full JQL query support for issue discovery
- Field discovery: List available fields and requirements per issue type
- API access: Make any Jira REST API call via the
commandapi - Security: All issues automatically restricted to Red Hat employees
Tips
-
Add a shell alias for convenience:
alias jirahhh='uvx --from "git+https://github.com/shanemcd/jirahhh" jirahhh' -
Use markdown files for complex descriptions - easier to edit and version control
-
Discover fields first when creating new issue types:
jirahhh fields --project AAP --type Epic --env prod -
Search before creating to avoid duplicates:
jirahhh search "project = AAP AND summary ~ 'My Feature'" --env prod -
User mentions in comments: Use full email format
not[~user@redhat.com][~username] -
Use
to inspect existing issues when learning field formatsview -
Finding child issues: Always use
not"Parent Link" = ISSUE-KEY
(see Custom Fields Reference section for details)parent = ISSUE-KEY
Technical Details
- Uses
Python library for Jira API accesspycontribs/jira - Uses Red Hat proxy (squid.corp.redhat.com:3128) for stage instance
- Authentication via Bearer token (not Basic Auth)
- Markdown conversion via
librarypypandoc - Supports all Jira REST API v2 endpoints via
commandapi
Links
- Repository: https://github.com/shanemcd/jirahhh
- Issues: https://github.com/shanemcd/jirahhh/issues
- Jira Production: https://issues.redhat.com
- Jira Stage: https://issues.stage.redhat.com
Last updated: 2025-10-20