TooLooLoo

JQL Gaps for Jira: documentation

User documentation for the Marketplace listing. This file is the source of truth: it is published as is by toolooloo-site (npm run sync && npm run build), and that URL goes in the listing's Documentation field. Edit the file, never the published page.


What the app does

Jira's JQL search engine has a fixed vocabulary: it knows assignee, status, created, and a short list of others, and nothing you type teaches it a new one. JQL Gaps adds 26 functions to that engine — typed inline, in the same search bar, exactly like a native keyword — for questions the built-in engine cannot answer at all: business days instead of calendar days, one date field compared to another, a work item's full sprint history, a real regular expression on any field, and more.

What it does not do. It is not a visual query builder and does not replace JQL syntax — every function is JQL, typed the way any other clause is. It does not sync or index your instance in the background: each call answers from what Jira returns at the moment of the search.

Requirements

Installing

  1. Open the listing on the Atlassian Marketplace and choose Get it now, or in Jira go to Apps > Explore more apps and search for JQL Gaps for Jira.
  2. Pick the site to install it on and confirm the permissions.
  3. That's it. Every function is available in the search bar immediately — there is no index to build and no button to press first.

Installing requires Jira administrator rights. Using a function in a search does not.

Finding a function: the reference page

Jira's own autocomplete shows a function's name and nothing else — no signature, no arguments, no allowed values. Open Apps > JQL Gaps for Jira > Reference for the full list: each function's syntax, what it answers, its arguments with their allowed values, and a Try it on your data button that runs the example against your own site in one click. A free-text filter searches by name, category or keyword.

The function catalogue

CategoryFunctions
DatesbusinessDays, dateCompare, fieldCompare, duplicateField
HierarchyparentMatch, childMatch, hasChildren, descendantMatch, childrenCount, childrenAll
SprintssprintDate, sprintChanges, addedToSprintAfterStart
AttachmentsattachmentMatch
TextfieldMatch, projectMatch
PeopleinactiveUser, commentedBy, activityBy, loggedTimeBy
LinkslinkedMatch, remoteLinkMatch
Projects & versionsversionDate
CommentscommentCount
ChangelogfieldWas, businessTimeInStatus

The reference page groups these the same way, with the full signature and examples for each — this table is an index, not a substitute for it.

Two rules that shape how a function is called

Most functions need a starting search. A JQL function can return at most 1000 identifiers, and a function that scanned your whole instance on every keystroke would be slow at best. So a scanning function takes a subquery as its first argument — the search you would already narrow down to by hand — and answers only within it:

issue in businessDays("duedate", "<=", "3") issue in parentMatch("project = OPS AND labels = security")

Four functions can answer instantly for the whole site. sprintChanges, inactiveUser, hasChildren and attachmentMatch accept "*" in place of a subquery, because the fact they answer (a sprint entered or left, an account deactivated, whether children exist, a file extension) is a short, fixed vocabulary the app can answer from Jira's own index rather than a scan:

issue in sprintChanges("*", "removed", "Sprint 42") issue in inactiveUser("*", "assignee")

Passing "*" to any other function is refused by name, with a message explaining why — the fact it would need to precompute is not a fixed vocabulary (a regular expression, or a comparison between two fields chosen at query time, has no finite list of answers to look up in advance).

A JQL escaping detail worth knowing

JQL's escaping rules are not a regular expression's. Native JQL recognises only \', \", \t, \n, \\ and \uXXXX — so a pattern like \.pdf$, which reads correctly as "a literal dot" in most regex dialects, is invalid JQL and must be written with the backslash doubled:

issue in attachmentMatch("project = OPS", "\\.pdf$")

This is the first thing most people trip on with the two pattern-matching functions, fieldMatch and attachmentMatch.

Troubleshooting

A function returns nothing, and I expected a match. Check the subquery first: every scanning function only looks inside it, so a subquery that is narrower than intended silently narrows the answer with it. Second, check the JQL escaping note above if the function takes a pattern.

The reference page's "Try it" button opens an empty search. The example is run exactly as written, against your own data — an empty result means no work item on your site currently matches that example, not that the function failed.

A function that reads a sprint or work-item hierarchy needs the matching Jira setup: a Scrum board with active sprints for the sprint functions, and a work item type above the one you are searching (an Epic, for hierarchy functions that walk upward).