name: jira-fix description: "Automate the full Jira ticket fix workflow: list your assigned tickets, pick one, auto-fix code, create Bitbucket draft PR, and comment on Jira. Also handles reviewer feedback loops. Use this skill whenever the user mentions Jira tickets, fixing a ticket, listing their tasks, creating a PR from a ticket, responding to Jira feedback, or anything involving the Jira-to-code-to-PR pipeline. Trigger phrases include: 'fix PROJ-123', 'show my tickets', 'my Jira tasks', 'what should I work on', 'continue fixing', 'apply feedback', 'create PR for ticket', 'list my bugs'. Even casual phrases like 'what tickets do I have' or 'work on the next bug' should trigger this skill."
Jira Fix Workflow
Automates: Jira ticket → code fix → code review → (optional) Bitbucket draft PR → (optional) Jira comment → feedback loop.
Scope: Only comments on Jira. Never changes ticket status. PO manages lifecycle. A code review always runs before committing. Creating a PR is optional — the skill asks first, and PRs are always draft so a human reviews before merge.
SKILL_DIR resolution
SKILL_DIR refers to the directory where this SKILL.md file lives. Determine it by resolving the path of this file's parent directory. All relative paths in this document (.env, scripts/) are relative to SKILL_DIR.
Prerequisites
jq,curl,gitavailable in PATH (pre-installed on macOS)- Atlassian MCP (optional — preferred when available, auto-fallback to bash API otherwise)
First-time setup
Before first use, check if SKILL_DIR/.env exists and contains valid (non-placeholder) values. If not, run the interactive setup below.
Step 1 — Ask for a Jira ticket URL:
Ask the user: "Paste a link to any Jira ticket (e.g. from your browser address bar)."
The user will provide something like:
https://acme.atlassian.net/browse/PROJ-123 or https://acme.atlassian.net/jira/software/c/projects/PROJ/boards/1?assignee=...
Extract from the URL:
- JIRA_URL: the origin part →
https://acme.atlassian.net - Project prefix: the ticket key prefix →
PROJ(store this for later use in branch naming and JQL)
Step 2 — Auto-detect Bitbucket workspace:
git remote get-url origin
If the remote contains bitbucket.org, extract the workspace:
git@bitbucket.org:myworkspace/myrepo.git→BB_WORKSPACE=myworkspacehttps://bitbucket.org/myworkspace/myrepo.git→BB_WORKSPACE=myworkspace
If not a Bitbucket remote, ask the user for BB_WORKSPACE.
Step 3 — Detect default branch:
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'
Use the result as MAIN_BRANCH. Fall back to develop if detection fails.
Step 4 — Check for Atlassian MCP:
Check if plugin-atlassian-atlassian MCP server is available by attempting a lightweight call:
CallMcpTool(server:"plugin-atlassian-atlassian", toolName:"getAccessibleAtlassianResources", arguments:{})
- If MCP responds: Tell the user "Atlassian MCP is connected. Jira operations will use MCP (faster, no extra token needed for read)."
- If MCP is not available: Tell the user:
Proceed with setup regardless of the answer — the skill works with or without MCP.Atlassian MCP is not installed. The skill will use direct API calls instead (works fine, just needs an API token).
To install the MCP for a better experience:
- Open Cursor Settings → MCP
- Search for "Atlassian" and enable it
- Follow the OAuth login prompt
Would you like to continue without MCP, or set it up first?
Step 5 — Create .env:
cp SKILL_DIR/.env.example SKILL_DIR/.env
chmod 600 SKILL_DIR/.env
Then write the auto-detected values into SKILL_DIR/.env:
ATLASSIAN_EMAIL= # ask the user
ATLASSIAN_API_TOKEN= # ask the user (see token creation below)
BB_API_TOKEN= # ask the user (see token creation below)
JIRA_URL= # auto-detected from step 1
BB_WORKSPACE= # auto-detected from step 2
MAIN_BRANCH= # auto-detected from step 3
TEST_URL_PATTERN= # ask the user (optional)
Step 6 — Guide token creation:
Ask the user for their Atlassian email, then guide them to create tokens:
Go to https://id.atlassian.com/manage-profile/security
Click "Create and manage API tokens" → "Create API token with scopes":
Token 1 — Jira (
ATLASSIAN_API_TOKEN):
- Name:
jira-fix-jira- App: Jira
Token 2 — Bitbucket (
BB_API_TOKEN):
- Name:
jira-fix-bitbucket- App: Bitbucket
- Scopes: Repositories Read + Write, Pull Requests Read + Write
Both tokens are created on the same page. They look similar but have different scopes.
Collect the email and both tokens from the user, then write them into SKILL_DIR/.env.
Step 7 — Verify:
bash SKILL_DIR/scripts/jira-api.sh list
If it returns tickets, tell the user setup is complete. If it fails, read the error and help troubleshoot (common issues: wrong email, expired token, incorrect JIRA_URL).
.env variables
All environment-specific values are read from SKILL_DIR/.env:
- JIRA_URL: Your Atlassian site (e.g.
https://your-site.atlassian.net) - BB_WORKSPACE: Your Bitbucket workspace slug
- MAIN_BRANCH: Target branch for PRs (default:
develop) - TEST_URL_PATTERN: Optional test URL pattern with
{TICKET_NUMBER}placeholder - TEST_CMD: Custom test command (default: auto-detect from
package.json) - LINT_CMD: Custom lint command (skipped if not set)
- FMT_CMD: Custom format command (skipped if not set)
- JIRA_LIST_JQL: Custom JQL for ticket listing (optional)
- Bitbucket repo: auto-detected from
git remote
Jira access: MCP-first, bash-fallback
For every Jira operation, prefer MCP if available; fall back to bash script if not.
MCP (preferred)
Use when plugin-atlassian-atlassian MCP server is connected:
Read JIRA_URL from SKILL_DIR/.env to get the cloudId (the hostname part, e.g. your-site.atlassian.net):
- List tickets:
CallMcpTool(server:"plugin-atlassian-atlassian", toolName:"searchJiraIssuesUsingJql", arguments:{cloudId:"<JIRA_HOST>", jql:"...", maxResults:20, fields:["summary","status","issuetype","priority","updated"], responseContentFormat:"markdown"}) - Get ticket:
CallMcpTool(server:"plugin-atlassian-atlassian", toolName:"getJiraIssue", arguments:{cloudId:"<JIRA_HOST>", issueIdOrKey:"TICKET-KEY", responseContentFormat:"markdown"}) - Add comment:
CallMcpTool(server:"plugin-atlassian-atlassian", toolName:"addCommentToJiraIssue", arguments:{cloudId:"<JIRA_HOST>", issueIdOrKey:"TICKET-KEY", commentBody:"TEXT", contentFormat:"markdown"})
Bash fallback
Use when MCP is not available:
- List tickets:
bash SKILL_DIR/scripts/jira-api.sh list - Get ticket:
bash SKILL_DIR/scripts/jira-api.sh get TICKET-KEY - Add comment:
bash SKILL_DIR/scripts/jira-api.sh comment TICKET-KEY "TEXT"
Bitbucket (bash only — no MCP available)
- Create draft PR:
bash SKILL_DIR/scripts/bb-pr.sh TICKET-KEY "TITLE" BRANCH "DESCRIPTION"
Workflows
Resolving commands for test, lint, format
Before running test/lint/format, check SKILL_DIR/.env for custom overrides:
- TEST_CMD: if set, use it. Otherwise auto-detect: look for
package.jsonscripts — preferyarn run testiftestscript exists, elsenpm test. - LINT_CMD: if set, use it. Otherwise skip lint (not all projects have one).
- FMT_CMD: if set, use it. Otherwise skip format (not all projects have one).
1. List my tickets
When user says things like "show my tickets", "what should I work on", "my Jira tasks":
Jira: list tickets (MCP or bash — see above)
Default JQL: assignee = currentUser() AND status not in (Done, Cancelled) ORDER BY priority ASC, updated DESC
Present the tickets clearly. Let the user pick one, or suggest the highest-priority actionable ticket.
2. Fix a ticket
When user says "fix PROJ-123" or picks a ticket from the list:
Read MAIN_BRANCH from SKILL_DIR/.env (default: develop). Use this value wherever MAIN_BRANCH appears below.
Step 1 — Fetch ticket details:
Jira: get ticket (MCP or bash)
Read the output — it contains summary, type, priority, and description. Share this with the user for confirmation before proceeding.
Step 2 — Pull latest & create branch (BEFORE any code work):
This step MUST complete before reading, exploring, or modifying any code:
STASHED=false
if ! git diff --quiet HEAD 2>/dev/null || [ -n "$(git ls-files --others --exclude-standard)" ]; then
git stash --include-untracked && STASHED=true
fi
git checkout MAIN_BRANCH
git pull origin MAIN_BRANCH
# Check if branch already exists
BRANCH="<prefix>/TICKET-KEY-short-description"
if git show-ref --verify --quiet "refs/heads/${BRANCH}"; then
git checkout "${BRANCH}"
git merge MAIN_BRANCH
else
git checkout -b "${BRANCH}"
fi
$STASHED && echo "NOTE: You have stashed changes. Run 'git stash pop' if you need them."
Branch prefix by ticket type:
- Bug →
fix/TICKET-KEY-short-desc(e.g.fix/PROJ-123-header-overlap) - Story / Feature →
feature/TICKET-KEY-short-desc(e.g.feature/PROJ-456-user-avatar) - Other (Task, Chore, etc.) →
fix/TICKET-KEY-short-desc
Generate a short kebab-case suffix from the ticket summary (3-5 words max).
Step 3 — Implement the fix:
Only start after the feature branch is checked out:
- Read the codebase to understand relevant code
- Plan the fix based on ticket description
- Implement with clean, tested code
- Run existing tests
- Add or update tests for changes
- Keep changes minimal and focused on the ticket
Step 4 — Test (auto-retry up to 3 times):
Run the test command (see "Resolving commands" above). If tests fail, read the output and fix. Retry up to 3 times. If still failing after 3 attempts, tell the user and ask whether to comment on Jira.
Step 5 — Format & Lint (must pass before commit):
Run format command then lint command (see "Resolving commands" above). Only run these if the commands are available (configured in .env or auto-detected).
If lint errors are found, fix them and re-run until clean. Do NOT skip this step if commands are available — PRs that fail CI lint will be rejected.
Step 6 — Code review (mandatory, before committing):
After test, format, and lint pass, a code review is REQUIRED. Do NOT skip it and do NOT commit before it is done.
- Look for a review skill in the current project. Search the project's skill directories —
.cursor/skills/,.agents/skills/,.claude/skills/,.codex/skills/— and the skills available in the current session for any whose name or description mentions "review" (e.g.review-pr,code-review,bugbot,security-review). - If a review skill exists: invoke it to review the current changes (the feature branch diff against
MAIN_BRANCH) and follow whatever workflow that skill defines. - If no review skill exists: review the changes yourself. Run
git diff MAIN_BRANCHand check: does the change fully address the ticket, are there bugs or unhandled edge cases, is the code clean and consistent with the surrounding codebase, is test coverage adequate. - Fix every valid issue the review surfaces. After fixing, re-run test (Step 4) and format & lint (Step 5) until they pass again.
- Summarize the review findings and the fixes you made for the user.
Step 7 — Commit and push:
Use conventional commit format: type(scope): TICKET-KEY module - description
- type:
featfor Story/Feature,fixfor Bug,refactor/chore/docsas appropriate - scope: the top-level package or area of the project (e.g.
client,server,api,web) - module: the feature/module within the scope — e.g.
nav,chat,profile,payment
Examples:
fix(client): PROJ-123 nav - fix header overlap on mobilefeat(server): PROJ-456 auth - add OAuth2 support
git add -A
git commit -m "MESSAGE"
git push -u origin BRANCH
Step 8 — Ask what to do next (create PR? comment on Jira?):
The fix is reviewed, committed, and pushed. Creating a PR and commenting on Jira are BOTH optional — do neither automatically. Ask the user which they want (they may choose one, both, or neither):
- Create a Bitbucket draft PR?
- Post a comment on Jira?
If the user wants a PR — PR title follows the same convention as commit messages: type(scope): TICKET-KEY module - description
bash SKILL_DIR/scripts/bb-pr.sh TICKET-KEY "type(scope): TICKET-KEY module - description" BRANCH "PR description text"
The script will prefix [DRAFT] to the title. If description is omitted, no description body is sent. Share the PR URL with the user.
If the user wants a Jira comment — build it from what actually happened. If a PR was created:
Draft PR created
PR: PR_URL
Branch: BRANCH
Please review and mark ready when satisfied
If no PR was created:
Fix pushed to branch BRANCH
Please review
If TEST_URL_PATTERN is set in .env, include a test link by replacing {TICKET_NUMBER} with the numeric part of the ticket key.
Only call Jira: add comment (MCP or bash) if the user explicitly confirms.
3. Apply feedback (continue fixing)
When user says "continue fixing PROJ-123", "apply feedback", "address the review comments":
Read MAIN_BRANCH from SKILL_DIR/.env (default: develop).
Step 1 — Get latest feedback:
Jira: get ticket (MCP or bash)
Step 2 — Checkout existing branch: Find and checkout the branch matching the ticket key.
Step 3 — Make targeted fixes:
Read the feedback, check current changes with git diff MAIN_BRANCH, make only the fixes that were requested. Do NOT rewrite from scratch.
Step 4 — Format & Lint: Run format and lint commands if available (see "Resolving commands" above).
Step 5 — Code review (mandatory, before committing):
Run the same mandatory code review as in "Fix a ticket" Step 6 — find and invoke the project's review skill if one exists, otherwise review the git diff MAIN_BRANCH yourself. Fix every valid issue, then re-run format & lint until clean.
Step 6 — Push and reply:
git add -A
git commit -m "fix(scope): TICKET-KEY module - address review feedback"
git push --force-with-lease origin BRANCH
Print the following message in the chat and ask the user whether to post it on Jira:
Feedback addressed and pushed.
Changes: SUMMARY
If TEST_URL_PATTERN is set in .env, include a test link.
Only call Jira: add comment (MCP or bash) if the user explicitly confirms.
4. Dry run (plan only)
When user says "plan for PROJ-123" or "what would you change for this ticket":
Fetch the ticket (MCP or bash), read the codebase, output a detailed fix plan in markdown. Do NOT create a branch, modify code, or create a PR. This is just planning.
Important rules
- Never change Jira ticket status — only add comments
- Always code-review before committing — use the project's review skill if one exists, otherwise review the diff yourself, and fix what it finds
- Creating a PR is optional — ask before creating one; PRs are always draft and the user decides when to publish
- Commit messages always include the ticket key — format:
type(scope): TICKET-KEY module - description - Ask before acting on ambiguous tickets — if the description is vague, ask the user for clarification before coding
- Feedback fixes are surgical — don't rewrite the whole thing, only address what was flagged