AgentSkillsCN

Jira Jql

JQL 语法参考与自然语言查询翻译模式,助力实现智能 JIRA 搜索。

SKILL.md
--- frontmatter
description: JQL syntax reference and natural language query translation patterns for intelligent JIRA search

JIRA JQL Translation Skill

When users search JIRA with natural language queries, use this skill to generate appropriate JQL (JIRA Query Language) queries that are syntactically correct, semantically meaningful, and performant.

Core Translation Principles

  1. Understand Intent: Interpret what the user wants to find
  2. Apply Smart Defaults: Use fuzzy matching and expansions for common patterns
  3. Prioritize Performance: Always include project filters when possible
  4. Be Transparent: Generate clear, readable JQL that users can learn from
  5. Add Context: Include sensible ORDER BY clauses for immediate usefulness

Translation Patterns

Fuzzy Status Matching

Users rarely know exact status names. Apply intelligent fuzzy matching:

"open" / "opened" / "active" / "not done":

jql
status IN (Open, 'To Do', 'In Progress', 'Refinement In Progress', New, Blocked)

"closed" / "done" / "finished" / "completed":

jql
status IN (Closed, Done, Resolved, 'Refinement Complete')

"in progress" / "working on" / "active development":

jql
status IN ('In Progress', 'Code Review', Testing, 'Refinement In Progress')

"blocked" / "stuck" / "waiting":

jql
status IN (Blocked, Waiting, 'Pending Review', 'Pending Approval')

"needs review" / "ready for review":

jql
status IN ('Code Review', 'Pending Review', 'Ready for QA')

Release/Version Queries

Teams use both fixVersion field AND labels inconsistently. Always check both automatically:

"release-3.2" / "version 3.2" / "3.2 release":

jql
(fixVersion = 'release-3.2' OR labels = 'release-3.2')

"targeted to X" / "planned for X":

jql
(fixVersion = 'X' OR labels = 'X')

Pattern: Always use OR to check both fixVersion and labels for any version/release query.

Link Following

"linked to RHAISTRAT-123" / "related to RHAI-456":

jql
issue IN linkedIssues(RHAISTRAT-123)

"blocks RHAIENG-789" / "blocking KEY":

jql
issue IN linkedIssues(RHAIENG-789, "blocks")

"blocked by KEY":

jql
issue IN linkedIssues(KEY, "is blocked by")

"depends on KEY":

jql
issue IN linkedIssues(KEY, "depends on")

Common link types: Relates, Blocks, Clones, Duplicates, Causes, Depends on

Ownership Queries

"my issues" / "assigned to me" / "mine":

jql
assignee = currentUser()

"created by me" / "I created" / "I reported":

jql
reporter = currentUser()

"unassigned" / "no assignee" / "needs owner":

jql
assignee IS EMPTY

"assigned to john" / "john's issues":

jql
assignee = john

Note: Usernames in JIRA are typically lowercase, without spaces.

Priority Queries

"high priority" / "urgent" / "critical":

jql
priority IN (Highest, High, Critical)

"low priority":

jql
priority IN (Lowest, Low)

"medium priority" / "normal":

jql
priority = Medium

Issue Type Queries

"bugs" / "defects":

jql
issuetype = Bug

"features" / "stories" / "user stories":

jql
issuetype IN (Feature, Story, 'User Story')

"tasks" / "chores":

jql
issuetype = Task

"epics":

jql
issuetype = Epic

"subtasks" / "sub-tasks":

jql
issuetype IN subTaskIssueTypes()

Date/Time Queries

"last week" / "past week" / "this week":

jql
updated >= -7d

"yesterday" / "last 24 hours":

jql
updated >= -1d

"last month":

jql
updated >= -30d

"today" / "updated today":

jql
updated >= startOfDay()

"created this month":

jql
created >= startOfMonth()

"overdue":

jql
due < now() AND resolution = Unresolved

Sprint Queries

"current sprint" / "active sprint":

jql
sprint IN openSprints()

"no sprint" / "backlog" / "not in any sprint":

jql
sprint IS EMPTY

"sprint 25" / "sprint X":

jql
sprint = X

Team/Group Queries

"assigned to the QA team" / "QA's issues":

jql
assignee IN membersOf("qa") OR assignee IN membersOf("quality-assurance")

"created by the dev team":

jql
reporter IN membersOf("developers")

Label Queries

"labeled X" / "tagged X" / "with label X":

jql
labels = X

"requires architecture review":

jql
labels = requires_architecture_review

Note: Labels are typically lowercase with underscores or hyphens.

Resolution Queries

"unresolved" / "not done" / "still open":

jql
resolution = Unresolved

"resolved" / "fixed":

jql
resolution IS NOT EMPTY

JQL Syntax Reference

Operators

OperatorUsageExample
=Equals (exact match)status = Open
!=Not equalspriority != Low
>Greater thanvotes > 10
>=Greater or equalcreated >= -7d
<Less thanvotes < 5
<=Less or equalduedate <= now()
INMatches any value in liststatus IN (Open, 'In Progress')
NOT INExcludes all values in liststatus NOT IN (Closed, Done)
~Contains (text search)summary ~ "authentication"
!~Does not containsummary !~ "deprecated"
IS EMPTYField has no valueassignee IS EMPTY
IS NOT EMPTYField has a valuelabels IS NOT EMPTY
IS NULLSame as IS EMPTYfixVersion IS NULL
IS NOT NULLSame as IS NOT EMPTYcomponent IS NOT NULL
WASHad value in the paststatus WAS 'In Progress'
WAS INWas any of valuesstatus WAS IN (Open, New)
WAS NOTWas not valueassignee WAS NOT john
CHANGEDField value changedpriority CHANGED

Functions

FunctionDescriptionExample
currentUser()Currently logged-in userassignee = currentUser()
linkedIssues(key)All issues linked to keyissue IN linkedIssues(RHAI-123)
linkedIssues(key, linkType)Issues with specific link typeissue IN linkedIssues(RHAI-123, "blocks")
membersOf(group)Users in a groupassignee IN membersOf("developers")
now()Current date/timecreated > now(-1h)
startOfDay([offset])Start of today (or offset)created >= startOfDay()
endOfDay([offset])End of today (or offset)due <= endOfDay()
startOfWeek([offset])Start of weekcreated >= startOfWeek()
endOfWeek([offset])End of weekdue <= endOfWeek()
startOfMonth([offset])Start of monthcreated >= startOfMonth()
endOfMonth([offset])End of monthdue <= endOfMonth()
startOfYear([offset])Start of yearcreated >= startOfYear()
endOfYear([offset])End of yearresolved <= endOfYear()
openSprints()All active sprintssprint IN openSprints()
closedSprints()All completed sprintssprint IN closedSprints()
futureSprints()All future sprintssprint IN futureSprints()
subTaskIssueTypes()All subtask typesissuetype IN subTaskIssueTypes()
issueHistory()Search issue historyAdvanced usage

Time offset examples:

  • now(-1h) - 1 hour ago
  • startOfDay(-7) - Start of day 7 days ago
  • startOfMonth(1) - Start of next month

Fields

FieldDescriptionExample Values
projectProject keyRHAISTRAT, RHAIENG, RHAIRFE
summaryIssue title"Add authentication support"
descriptionIssue descriptionFree text
issuetypeType of issueBug, Feature, Story, Task, Epic
statusCurrent statusOpen, 'In Progress', Done, Closed
priorityPriority levelHighest, High, Medium, Low, Lowest
assigneeAssigned userjdoe, currentUser()
reporterCreated byjsmith, currentUser()
createdCreation date"2025-01-15", -7d
updatedLast updated-1d, startOfDay()
resolvedResolution date-30d, now()
dueDue date"2025-02-01", endOfWeek()
labelsTags/labelsdocumentation, security
componentComponentAuthentication, UXD, API
fixVersionTarget version1.5.0, release-3.2
affectsVersionFound in version1.4.0
resolutionResolution statusUnresolved, Fixed, Won't Fix
sprintSprintSprint 25, openSprints()
commentIssue commentsFree text search
votesNumber of votes10, >5
watchersNumber of watchers3, >=1
textAll text fieldsSearches summary, description, comments

Logical Operators

OperatorUsageExample
ANDAll conditions must be trueproject = RHAI AND status = Open
ORAny condition must be truepriority = High OR priority = Highest
NOTNegates a conditionNOT status = Closed

Parentheses for grouping:

jql
(priority = High OR priority = Highest) AND status = Open

Ordering

ORDER BY sorts results:

jql
ORDER BY priority DESC
ORDER BY created ASC
ORDER BY priority DESC, updated DESC

Directions: ASC (ascending), DESC (descending)

Quoting Rules

Quote multi-word values with single or double quotes:

jql
status = 'In Progress'
status = "Code Review"
project IN (RHAI, RHAIENG)  # Single-word values don't need quotes

Quote special characters:

jql
summary ~ "user's authentication"

Date Formats

Relative dates:

  • -1d - 1 day ago
  • -2w - 2 weeks ago
  • -3M - 3 months ago
  • -1y - 1 year ago
  • -30m - 30 minutes ago
  • -2h - 2 hours ago

Absolute dates:

  • "2025-01-15"
  • "2025/01/15"
  • "15/Jan/25"

Functions:

  • now()
  • startOfDay(), endOfDay()
  • startOfWeek(), endOfWeek()

Complex Translation Examples

Example 1: "my open bugs in RHAIENG"

User Intent: Find bugs assigned to me that aren't finished yet, in a specific project

Generated JQL:

jql
project = RHAIENG
AND issuetype = Bug
AND assignee = currentUser()
AND status IN (Open, 'To Do', 'In Progress', New, Blocked)
ORDER BY priority DESC, updated DESC

Why:

  • Project filter first (performance)
  • Fuzzy status matching ("open" → multiple statuses)
  • Sensible ordering (high priority first, then recently updated)

Example 2: "features targeted to release-3.2 that are still open"

User Intent: Find features planned for a release that aren't done yet

Generated JQL:

jql
issuetype IN (Feature, Story, 'User Story')
AND (fixVersion = 'release-3.2' OR labels = 'release-3.2')
AND status NOT IN (Done, Closed, Resolved, 'Refinement Complete')
ORDER BY priority DESC

Why:

  • Checks both fixVersion and labels (teams use inconsistently)
  • Excludes "closed" statuses (fuzzy matching)
  • Orders by priority for focus

Example 3: "issues linked to RHAISTRAT-123"

User Intent: Find all issues with any link to a specific issue

Generated JQL:

jql
issue IN linkedIssues(RHAISTRAT-123)
ORDER BY type ASC, key ASC

Why:

  • Uses linkedIssues() function
  • Orders by type for grouping (bugs, features, etc.)

Example 4: "my issues updated in the last week"

User Intent: Find my issues with recent activity

Generated JQL:

jql
assignee = currentUser()
AND updated >= -7d
ORDER BY updated DESC

Why:

  • Simple and direct
  • Orders by most recent first

Example 5: "unassigned high priority bugs in RHAIENG"

User Intent: Find urgent bugs that need an owner

Generated JQL:

jql
project = RHAIENG
AND issuetype = Bug
AND priority IN (Highest, High, Critical)
AND assignee IS EMPTY
ORDER BY priority DESC, created DESC

Why:

  • Project filter first
  • Fuzzy priority matching ("high priority" → multiple levels)
  • Orders by priority then age

Example 6: "bugs created by me that block other issues"

User Intent: Find bugs I reported that are blockers

Generated JQL:

jql
issuetype = Bug
AND reporter = currentUser()
AND issue IN linkedIssues(*, "blocks")
ORDER BY created DESC

Note: The * wildcard with linkedIssues may not work in all JIRA versions. Alternative approach:

jql
issuetype = Bug
AND reporter = currentUser()
ORDER BY created DESC

Then filter manually for blockers.

Example 7: "features in the current sprint assigned to the QA team"

User Intent: Find features in active sprint assigned to QA

Generated JQL:

jql
issuetype IN (Feature, Story)
AND sprint IN openSprints()
AND (assignee IN membersOf("qa") OR assignee IN membersOf("quality-assurance"))
ORDER BY rank ASC

Why:

  • Uses openSprints() for current sprint
  • Checks multiple possible group names
  • Orders by rank (sprint order)

Example 8: "my overdue tasks"

User Intent: Find tasks assigned to me that are past due date

Generated JQL:

jql
assignee = currentUser()
AND due < now()
AND resolution = Unresolved
ORDER BY due ASC

Why:

  • Checks due date is in the past
  • Excludes resolved issues
  • Orders by most overdue first

Example 9: "issues created this month in RHAISTRAT project with no labels"

User Intent: Find recent issues that haven't been tagged yet

Generated JQL:

jql
project = RHAISTRAT
AND created >= startOfMonth()
AND labels IS EMPTY
ORDER BY created DESC

Why:

  • Uses startOfMonth() for "this month"
  • IS EMPTY for "no labels"
  • Recent first ordering

Example 10: "bugs in release-2.5 that were closed but are now reopened"

User Intent: Find regressions in a specific release

Generated JQL:

jql
issuetype = Bug
AND (fixVersion = 'release-2.5' OR labels = 'release-2.5')
AND status WAS Closed
AND status = Open
ORDER BY updated DESC

Why:

  • Uses WAS operator for history
  • Checks both version field and labels
  • Current status is Open (reopened)

Translation Guidelines

1. Always Include Project Filters When Possible

Bad (slow, searches all issues):

jql
assignee = currentUser() AND status = Open

Good (fast, limits scope):

jql
project = RHAIENG AND assignee = currentUser() AND status = Open

Performance: 10-100x faster with project filter.

2. Use Fuzzy Matching for Status and Priority

Don't require users to know exact status names. Map common terms to multiple statuses:

  • "open" → Open, To Do, In Progress, New
  • "high priority" → Highest, High, Critical

3. Always Expand Release Queries

Check both fixVersion AND labels automatically:

jql
(fixVersion = 'X' OR labels = 'X')

4. Add Sensible ORDER BY Clauses

Don't return unordered results. Choose ordering based on intent:

  • Priority: ORDER BY priority DESC
  • Recency: ORDER BY updated DESC or ORDER BY created DESC
  • Due date: ORDER BY due ASC
  • Sprint: ORDER BY rank ASC

5. Quote Multi-Word Values

jql
status = 'In Progress'      # Correct
status = In Progress        # Wrong (syntax error)

6. Prefer Positive Conditions

Less clear:

jql
NOT status = Closed

More clear:

jql
status IN (Open, 'In Progress', 'To Do')

7. Use Functions for Dynamic Values

Static (becomes outdated):

jql
assignee = jdoe

Dynamic (works for any user):

jql
assignee = currentUser()

8. Combine Related Conditions

Verbose:

jql
status = Open OR status = 'In Progress' OR status = 'To Do'

Concise:

jql
status IN (Open, 'In Progress', 'To Do')

9. Be Explicit About Intent

If user says "my bugs", include:

  • issuetype = Bug
  • assignee = currentUser()
  • Likely want: status IN (open statuses)
  • Good ordering: priority DESC

10. Handle Ambiguity with Sensible Defaults

If query is vague like "issues", default to:

jql
assignee = currentUser() AND resolution = Unresolved
ORDER BY updated DESC

Assume user wants their own open issues.


Common Patterns Quick Reference

User SaysGenerate JQL
"my issues"assignee = currentUser() AND resolution = Unresolved
"my bugs"issuetype = Bug AND assignee = currentUser() AND status IN (...)
"my open bugs"Above + fuzzy status
"bugs in PROJECT"project = PROJECT AND issuetype = Bug
"high priority"priority IN (Highest, High, Critical)
"release-X"(fixVersion = 'release-X' OR labels = 'release-X')
"last week"updated >= -7d
"today"updated >= startOfDay()
"unassigned"assignee IS EMPTY
"created by me"reporter = currentUser()
"overdue"due < now() AND resolution = Unresolved
"current sprint"sprint IN openSprints()
"linked to KEY"issue IN linkedIssues(KEY)
"no labels"labels IS EMPTY

Performance Optimization Tips

1. Project Filter First

Always include project in queries when possible.

2. Avoid Text Searches When Possible

Slow:

jql
summary ~ "authentication" OR description ~ "authentication"

Faster:

jql
text ~ "authentication"  # Searches summary, description, comments

Even better (if possible):

jql
labels = authentication  # Field match is fastest

3. Limit OR Conditions

Slower:

jql
project = A OR project = B OR project = C OR ...  # Many ORs

Faster:

jql
project IN (A, B, C, ...)  # Single IN clause

4. Use Indexed Fields

Prefer these (indexed in most JIRA instances):

  • project
  • status
  • priority
  • assignee
  • reporter
  • issuetype

Avoid heavy reliance on:

  • text searches (~ operator)
  • comments
  • description

Error Prevention

Common Mistakes to Avoid

1. Missing Quotes:

jql
status = In Progress  # WRONG (syntax error)
status = 'In Progress'  # CORRECT

2. Wrong Operator for Field Type:

jql
created ~ "2025-01-15"  # WRONG (~ is for text)
created = "2025-01-15"  # CORRECT (= for dates)

3. Using != with Text Fields:

jql
summary != "test"  # NOT SUPPORTED
NOT summary ~ "test"  # Use this instead

4. Case Sensitivity:

  • Field names: Case-insensitive (status = Status = STATUS)
  • Values: Case-sensitive (status = Openstatus = open)
  • Functions: Case-insensitive

5. Reserved Words: Don't use these as unquoted values: AND, OR, NOT, EMPTY, NULL, ORDER, BY


Web References

For the most up-to-date JQL documentation:


Usage in /jira:search Command

When the /jira:search command invokes this skill, you should:

  1. Parse the user's natural language query
  2. Identify key components (project, issue type, status, owner, etc.)
  3. Apply fuzzy matching and smart expansions
  4. Construct syntactically correct JQL
  5. Add sensible ORDER BY clause
  6. Return the JQL string only (no explanation in the JQL itself)

The command will show the JQL to the user with an explanation before execution.

Example workflow:

User query: "my open bugs in RHAIENG"

Your thought process:

  1. "my" → assignee = currentUser()
  2. "bugs" → issuetype = Bug
  3. "in RHAIENG" → project = RHAIENG
  4. "open" → status IN (Open, 'To Do', 'In Progress', New, Blocked)
  5. Add ordering → ORDER BY priority DESC, updated DESC

Generated JQL:

jql
project = RHAIENG AND issuetype = Bug AND assignee = currentUser() AND status IN (Open, 'To Do', 'In Progress', New, Blocked) ORDER BY priority DESC, updated DESC

Remember: Your goal is to translate user intent into powerful, correct, performant JQL. Be smart, be helpful, and always think about what the user really wants to find.