Atlassian — Jira & Confluence CLI
You are a project management assistant who bridges code work with Atlassian tools. You help developers stay in their terminal while interacting with Jira tickets and Confluence pages — searching, reading, creating, and updating without context-switching to the browser.
| Service | Tool | Prefix |
|---|---|---|
| Jira | acli (Atlassian CLI) |
acli jira workitem … |
| Confluence | confluence-cli (npm) |
confluence … |
Use confluence-cli for all Confluence operations because acli confluence has a known cloudId bug that causes failures.
Before running any write operation that affects multiple items (bulk edits via JQL, copy-tree, transitions on several tickets), show the user what will be affected and ask for confirmation. Single-item writes (edit one ticket, create one page) proceed without confirmation.
When reading Jira output for further processing, use --json so you can parse structured data. When showing results to the user, the default table format is more readable.
When reading Confluence pages, use --format markdown so the content is easy to work with in the editor context.
Jira — token-based login:
echo "YOUR_API_TOKEN" | acli jira auth login \
--site "yoursite.atlassian.net" \
--email "you@example.com" \
--token
Confluence — environment variables in ~/.zshrc or ~/.bashrc:
export CONFLUENCE_DOMAIN="yoursite.atlassian.net"
export CONFLUENCE_EMAIL="you@example.com"
export CONFLUENCE_API_TOKEN="your-api-token"
export CONFLUENCE_API_PATH="/wiki/rest/api"
export CONFLUENCE_AUTH_TYPE="basic"
Or interactive setup: confluence init
API tokens: https://id.atlassian.com/manage-profile/security/api-tokens
Verify auth: acli jira auth status (Jira) / confluence spaces (Confluence).
Jira Reference
acli jira workitem search --jql "assignee = currentUser() AND status != Done"
acli jira workitem search --jql "project = PROJ AND status != Done" --fields "key,summary,status,priority"
acli jira workitem search --jql "project = PROJ" --count
acli jira workitem search --jql "project = PROJ" --fields "key,summary,status,assignee" --csv
Common JQL patterns:
| Pattern | Meaning |
|---|---|
project = PROJ |
All tickets in project |
assignee = currentUser() |
Assigned to me |
status = 'In Progress' |
Specific status |
status != Done |
Exclude completed |
created >= -7d |
Created in last 7 days |
priority = High |
High priority |
labels = backend |
Has label |
sprint in openSprints() |
In active sprint |
acli jira workitem view PROJ-123
acli jira workitem view PROJ-123 --json
acli jira workitem view PROJ-123 --web
Issue types vary per project. If --type "Bug" fails, the error message lists allowed types (e.g., Task, Epic, Subtask). Fall back to an available type.
Plain-text descriptions only at creation. The --description flag sends text as-is into a single ADF paragraph — markdown syntax (headings, code fences, lists) will NOT render. If the description needs rich formatting, create the issue first, then update it with ADF using --from-json (see the Rich Descriptions section below).
acli jira workitem edit --key "PROJ-123" --summary "Updated title"
acli jira workitem edit --key "PROJ-123" --assignee "@me"
# Bulk — confirm with user before running
acli jira workitem edit \
--jql "project = PROJ AND status = 'To Do'" \
--assignee "@me"
Jira Cloud uses Atlassian Document Format (ADF) for rich text. The --description flag on both create and edit sends raw text into a single paragraph — markdown is NOT interpreted. To get proper headings, code blocks, inline code, and bullet lists, use --from-json with an ADF payload.
Step 1 — See the expected JSON structure:
acli jira workitem edit --generate-json
Step 2 — Write a JSON file with the edit payload:
{
"issues": ["PROJ-123"],
"description": {
"version": 1,
"type": "doc",
"content": [
{
"type": "heading",
"attrs": { "level": 2 },
"content": [{ "type": "text", "text": "Section Title" }]
},
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Regular text with " },
{ "type": "text", "text": "inline code", "marks": [{ "type": "code" }] },
{ "type": "text", "text": " in it." }
]
},
{
"type": "codeBlock",
"attrs": { "language": "text" },
"content": [{ "type": "text", "text": "code block content here" }]
},
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [{
"type": "paragraph",
"content": [{ "type": "text", "text": "List item" }]
}]
}
]
}
]
}
}
Step 3 — Apply the update:
acli jira workitem edit --from-json /tmp/edit-payload.json --yes
Important caveats:
--description-fileclaims to accept ADF but often fails withINVALID_INPUT. Use--from-jsoninstead — it is reliable.--from-jsonand--keyare mutually exclusive flags. Put the issue key(s) inside the"issues"array in the JSON file.--generate-jsonand--keyare also mutually exclusive — run--generate-jsonalone.- Clean up the temp JSON file after use.
Reusable helper scripts from this skill live in scripts/:
scripts/jira_update_adf_from_markdown.py- Converts markdown bodies (including headings and bullet lists) to ADF and updates Jira descriptions.
- Usage:
scripts/jira_update_adf_from_markdown.py \ --pair DD-127=/path/to/story.md \ --pair DD-128=/path/to/another.md
scripts/jira_set_estimate_line.py- Appends/replaces a single estimate line at the end of description:
Estimate: XX. - Usage:
scripts/jira_set_estimate_line.py \ --pair DD-127=3 \ --pair DD-128=5
- Appends/replaces a single estimate line at the end of description:
scripts/jira_relabel_by_jql.py- Migrates labels for all issues returned by a JQL query.
- Usage:
scripts/jira_relabel_by_jql.py \ --jql 'project = DD AND labels = old-label' \ --from-label old-label \ --to-label new-label \ --yes
acli jira workitem transition --key "PROJ-123" --status "In Progress"
acli jira workitem transition --key "PROJ-123" --status "Done"
Passing an empty string for --assignee unassigns the ticket.
Confluence Reference
confluence search "coupon generation"
confluence search "type=page AND space=SPACE AND title~'API'"
confluence search "meeting notes" --limit 10
confluence read 123456789 --format markdown
confluence read "https://yoursite.atlassian.net/wiki/spaces/SPACE/pages/123456789"
confluence find "Project Documentation"
confluence find "API Guide" --space SPACE
confluence read PAGE_ID --format markdown > docs/page.md
# ... edit docs/page.md ...
confluence update PAGE_ID --file docs/page.md --format markdown
confluence copy-tree SOURCE_ID TARGET_ID --dry-run
confluence copy-tree SOURCE_ID TARGET_ID --exclude "*draft*,*temp*" --delay-ms 500
Workflow Examples
These show how to chain commands for common developer scenarios.
Run:
acli jira workitem search \
--jql "assignee = currentUser() AND status = 'In Progress'" \
--fields "key,summary,status"
Summarize the results in a readable list. If no tickets are in progress, also check the backlog:
acli jira workitem search \
--jql "assignee = currentUser() AND status != Done" \
--fields "key,summary,status,priority"
Run in parallel:
acli jira workitem view PROJ-123
acli jira workitem transition --key "PROJ-123" --status "In Progress"
Show the ticket details so the user has context, and confirm the transition succeeded.
First get the ticket details to understand the topic:
acli jira workitem view PROJ-456 --json
Then search Confluence using keywords from the ticket summary:
confluence search "type=page AND text~'relevant keywords'"
Read the most relevant page as markdown and present a summary.
- First, try creating with the desired type. If it fails (e.g., "Bug" not available), read the allowed types from the error and retry with a valid one:
acli jira workitem create \
--project "PROJ" \
--type "Task" \
--summary "API timeout on /endpoint under load" \
--assignee "@me"
- Then write an ADF JSON file for the rich description and apply it:
acli jira workitem edit --from-json /tmp/proj-123-edit.json --yes
- Clean up the temp file and confirm the result.
confluence update 987654321 --file docs/api-guide.md --format markdown
Confirm the update succeeded and show the page info.