From hoopit-dev
Handle any Jira issue end-to-end — an ITSM ticket or a project issue (BAC/WEB/FA). Fetch details (from the linked ITSM ticket when one exists), link or create a project issue only when needed, branch, fix, test, review, and open a PR. Use whenever the user links to or names a Jira issue to fix.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hoopit-dev:handle-jira-issueThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Triggered when the user says something like "fix this issue" and provides any Jira issue key or link — either an ITSM ticket (e.g. `ITSM-1234`) or a project issue (e.g. `BAC-6934`, `WEB-1234`, `FA-987`), or a full Jira URL (e.g. `https://hoopit.atlassian.net/browse/ITSM-1234`).
Triggered when the user says something like "fix this issue" and provides any Jira issue key or link — either an ITSM ticket (e.g. ITSM-1234) or a project issue (e.g. BAC-6934, WEB-1234, FA-987), or a full Jira URL (e.g. https://hoopit.atlassian.net/browse/ITSM-1234).
This skill is project-agnostic. Every Hoopit-specific identifier (Jira keys, the
Jira base URL, the ITSM project key, repo names) comes from the
## Agent skills → ### Workflow skills config block in each repo's
CLAUDE.md. Do not hardcode or guess these — read them from CLAUDE.md. If a
value you need is missing from the relevant repo's CLAUDE.md, stop and ask the
user to add it rather than assuming a default.
The repos are sibling directories under a common parent (HOOPIT_ROOT); derive
it from the repo this skill is invoked in:
HOOPIT_ROOT="$(dirname "$(git rev-parse --show-toplevel)")"
Do not assume a fixed BAC/WEB/FA map. For each sibling repo under
$HOOPIT_ROOT that has a CLAUDE.md, read its declared Jira project key from
the Workflow skills config block. That yields the current Jira key → repo
mapping, so new projects work without editing this skill:
# Prints "KEY<TAB>/path/to/repo" for every sibling repo that declares a Jira key.
for repo in "$HOOPIT_ROOT"/*/; do
cm="$repo/CLAUDE.md"; [ -f "$cm" ] || continue
key="$(grep -iE '^\s*[-*]\s*\*\*Jira project key:\*\*' "$cm" | grep -oE '`[A-Z][A-Z0-9]+`' | tr -d '`' | head -1)"
[ -n "$key" ] && printf '%s\t%s\n' "$key" "${repo%/}"
done
(At the time of writing that resolves to BAC → api, WEB → web-admin,
FA → flutter-app, but always resolve it from CLAUDE.md.)
Once you know TARGET_REPO, read the rest of its Workflow skills config —
Jira base URL, ITSM project key, Default branch — from that repo's
CLAUDE.md and use them in place of the literals below.
Variables used throughout this skill:
TARGET_PROJECT — the Jira project key the fix is tracked under.TARGET_REPO — the repo whose CLAUDE.md declares TARGET_PROJECT.TARGET_KEY — the project issue key in TARGET_PROJECT (e.g. BAC-6934). Becomes the working JIRA_KEY.JIRA_BASE_URL — the Jira base URL from TARGET_REPO's CLAUDE.md (e.g. https://hoopit.atlassian.net).ITSM_PROJECT — the ITSM project key from CLAUDE.md (e.g. ITSM); ITSM keys look like <ITSM_PROJECT>-1234.DEFAULT_BRANCH — TARGET_REPO's default branch from CLAUDE.md (e.g. master).ITSM_ISSUE_KEY — the linked ITSM ticket, if one exists. May be unset.DETAILS_KEY — the issue you read the bug report / symptoms / attachments from: the ITSM ticket when one exists, otherwise the project issue itself.Wherever the steps below show
https://hoopit.atlassian.net,ITSM, ormaster, substitute$JIRA_BASE_URL,$ITSM_PROJECT, and$DEFAULT_BRANCHfrom CLAUDE.md.
PR/Jira link hygiene: when naming the branch (Step 3), writing commit messages (Steps 6–7), or authoring the PR (Step 9), load the
write-pull-requestskill and follow it. For this workflow the work items the PR may link areJIRA_KEYand — only when an ITSM ticket is linked —ITSM_ISSUE_KEY; keep every other Jira key out of those surfaces.
Before anything else, classify the input issue. If a full Jira URL was provided, extract the issue key from it first, then look at the key's prefix:
ITSM-…) — ITSM-originatedITSM_ISSUE_KEY = the input key.DETAILS_KEY = ITSM_ISSUE_KEY.TARGET_PROJECT / TARGET_KEY are resolved in Step 2 (an existing linked project issue, or a new one you create).BAC-…, WEB-…, FA-…) — project-originatedTARGET_KEY = the input key; TARGET_PROJECT = its prefix; TARGET_REPO = the matching repo. No new project issue will ever be created — the input issue is the target.
Check whether it links to an ITSM ticket by fetching the issuelinks field (see the parsing note in Step 2a — inspect both inwardIssue.key and outwardIssue.key):
acli jira workitem view <TARGET_KEY> --fields 'issuelinks' --json
ITSM-… issue found → set ITSM_ISSUE_KEY to it; DETAILS_KEY = ITSM_ISSUE_KEY. (Read details from the ITSM ticket, not the project issue.)ITSM_ISSUE_KEY unset; DETAILS_KEY = TARGET_KEY. (Read details from the project issue itself.)TARGET_PROJECT (ITSM-originated only)For project-originated issues the project is already known from the key prefix. For ITSM-originated issues, resolve the target project as follows:
BAC-, WEB-, or FA-, that is TARGET_PROJECT — no question needed.Jira project key from its CLAUDE.md Workflow skills config — that is TARGET_PROJECT.Always read the bug report and context from DETAILS_KEY — i.e. the linked ITSM ticket when one exists, otherwise the project issue itself. When an ITSM ticket is linked, it is the source of truth for the reported symptoms, repro steps, and attachments; do not rely on the project issue for those details.
acli jira workitem view <DETAILS_KEY> --fields '*all'
Extract and note:
TARGET_PROJECT is appropriate).har) files, screenshots, or logsIf the issue has attached HAR files, download and review them to get a deeper understanding of the endpoints and payloads involved. HAR files capture the full browser network activity at the time of the bug and often reveal the exact request URLs, headers, request bodies, and response payloads that reproduce the problem.
Download attachments with acli:
acli jira workitem attachment download <DETAILS_KEY> --output-directory /tmp/<DETAILS_KEY>-attachments
Then inspect any .har file as JSON — focus on:
Use the findings to narrow down which endpoint, view, component, or screen is involved before starting the investigation.
If the issue cannot be understood or reproduced from the available information, stop and ask the user for clarification.
How this resolves depends on the scenario from Determine the scenario:
BAC/WEB/FA issue): TARGET_KEY is the input issue itself. Do not create or link anything — skip straight to Step 3. (Any linked ITSM ticket was already recorded as ITSM_ISSUE_KEY.)ITSM-… ticket): follow 2a/2b below.Do NOT use acli jira workitem link list — it only returns outwardIssueKey and silently drops inwardIssue data. Target issues are typically linked as inward issues ("ITSM ticket is caused by BAC/WEB/FA bug"), so they will appear missing even when they exist.
Instead, fetch the issuelinks field directly and parse the JSON:
acli jira workitem view <ITSM_ISSUE_KEY> --fields 'issuelinks' --json
Inspect both inwardIssue.key and outwardIssue.key across all entries in the fields.issuelinks array. Look for any linked issue whose key starts with BAC-, WEB-, or FA-.
If such a link exists:
TARGET_PROJECT from its prefix and TARGET_KEY to that key.Resolve TARGET_PROJECT using the rules in How to determine TARGET_PROJECT above. Then map the ITSM request type to the destination issue type. The mapping is the same across all three projects:
| ITSM request type | Issue type in TARGET_PROJECT |
|---|---|
| Problem | Bug |
| Feature request | Story |
| Anything else | Task |
acli jira workitem create \
--project "$TARGET_PROJECT" \
--type '<Bug | Story | Task>' \
--summary '<concise title>' \
--description '## Summary
<1-2 sentence description>
## Root cause / background
<technical explanation or context>
## References
- ITSM: [<ITSM_ISSUE_KEY>]($JIRA_BASE_URL/browse/<ITSM_ISSUE_KEY>)'
Note the new TARGET_KEY printed by the command (e.g. BAC-6934, WEB-1234, FA-987).
Create an "is caused by" link from the ITSM ticket to the new issue (i.e. the ITSM issue is caused by the target bug).
If unsure of the exact link-type name, list available types first:
acli jira workitem link type
Then create the link:
acli jira workitem link create \
--out '<ITSM_ISSUE_KEY>' \
--in '<TARGET_KEY>' \
--type 'Causes' \
--yes
Note: The direction matters —
--outis the outward issue (the effect: ITSM ticket) and--inis the inward issue (the cause: target bug). Verify direction withacli jira workitem link typeif needed.
TARGET_KEY is the JIRA_KEY used for all subsequent steps.
All branch/worktree work happens inside TARGET_REPO. From here on, treat TARGET_REPO as the working repo — cd into it if you aren't already there.
Branch naming convention (same across all three repos): <JIRA_KEY>/bug/<short-kebab-description>
Examples:
BAC-6934/bug/dintero-payment-data-double-serializedWEB-1234/bug/club-admin-roster-export-emptyFA-987/bug/login-screen-crash-on-empty-inputcreate-worktree skillEach repo owns its own worktree/venv/test-DB conventions, so do not hand-roll the worktree setup here. Instead:
Look for TARGET_REPO/.claude/skills/create-worktree/SKILL.md.
If it exists, read it and follow its instructions to create the branch and worktree. That skill is responsible for things like virtualenv wiring, isolated test DBs, or any other per-repo setup the worktree needs.
If it does not exist, fall back to a plain worktree:
cd "$TARGET_REPO"
git fetch origin
BRANCH="<JIRA_KEY>/bug/<short-description>"
WORKTREE_DIR=".worktrees/$(echo $BRANCH | tr '/' '-')"
git worktree add -b "$BRANCH" "$WORKTREE_DIR" origin/master
(Adjust origin/master if the repo's default branch is different — check with git symbolic-ref refs/remotes/origin/HEAD.)
All subsequent steps (4–9) run from $WORKTREE_DIR unless stated otherwise.
$WORKTREE_DIR identified from the issue description and investigation.$TARGET_REPO/.claude/skills/ that apply to the area you're touching (for example, the api repo has models, views, urls, migrations skills; the web-admin repo and flutter-app may have their own). Skip skills that don't exist.Defer to the target repo's testing conventions:
TARGET_REPO/.claude/skills/writing-tests/SKILL.md exists, read and follow it before writing tests.TARGET_REPO/.claude/skills/running-tests/SKILL.md exists, use its instructions to run tests.Goal regardless of stack:
def test_payment_data_not_double_serialized(self):
"""
Regression test for BAC-6934.
payment_data must be passed as a dict, not a JSON string,
when calling the Dintero Google Pay endpoint.
"""
Run the new test (and any related tests) to confirm they pass. If the repo provides no realistic way to add an automated regression test for this kind of bug (e.g. some flutter-app UI bugs), say so explicitly in the PR description instead of skipping silently.
If tests fail, fix the issues before proceeding.
Stage and commit all changes from within the worktree. Include the Refs <ITSM_ISSUE_KEY> footer only when an ITSM ticket is linked — omit it entirely for a project issue with no ITSM link:
cd "$WORKTREE_DIR"
git add -A
git commit -m "<JIRA_KEY>: <short description>
<Optional longer description of what was changed and why.>
Refs <ITSM_ISSUE_KEY>"
Example (ITSM linked):
BAC-6934: Fix double-serialization of payment_data in Dintero Google/Apple Pay
payment_data was being passed through json.dumps() before being added
to the request dict. Since _request() already uses json=data, this
resulted in Dintero receiving a JSON string instead of a JSON object.
Refs ITSM-1234
Read TARGET_REPO/.claude/skills/code-review/SKILL.md and follow its instructions (all three repos have this skill).
Run a review against the repo's default branch from the worktree:
cd "$WORKTREE_DIR"
coderabbit review --prompt-only --base "$DEFAULT_BRANCH"
(Use main instead of master if that is the repo's default branch.)
Group findings by severity (Critical → Warning → Info). For each finding, decide whether to fix or skip it:
Commit each fix as a separate commit. The commit message must not include the Jira key (CodeRabbit findings are not tied to a Jira issue). Instead, write a complete commit message that includes:
cd "$WORKTREE_DIR"
git add <affected files>
git commit -m "<short imperative subject line>
CodeRabbit finding (<severity>):
<paste the full finding text as reported by CodeRabbit>
Solution:
<describe exactly what was changed and why>"
Track every finding you choose NOT to fix — you will need this list for the PR. For each skipped finding, note:
Re-run the review after fixing. Repeat until only Info-level findings remain (or the review is clean).
Push normally — including from a worktree, where the pre-push hooks resolve the main repo's virtualenv on their own:
cd "$WORKTREE_DIR"
git push -u origin <branch-name>
Create a PR using the GitHub CLI. Include the ## ITSM section only when an ITSM ticket is linked — omit it for a project issue with no ITSM link:
cd "$WORKTREE_DIR"
gh pr create \
--title "<branch-name>" \
--body "## Summary
<description of the fix>
## Jira
[<JIRA_KEY>]($JIRA_BASE_URL/browse/<JIRA_KEY>)
## ITSM
[<ITSM_ISSUE_KEY>]($JIRA_BASE_URL/browse/<ITSM_ISSUE_KEY>)
## Changes
- <bullet point summary of changes>
## Testing
- <describe the test(s) added, or state explicitly that no automated regression test was feasible and why>
## Code review notes
### Findings addressed
- <severity>: <finding> — <what was done>
### Findings not addressed
- <severity>: <finding> — <reason for skipping>" \
--base "$DEFAULT_BRANCH"
(Again, swap master for main if that's the repo's default branch.)
Report the PR URL to the user.
npx claudepluginhub hoopit/skills --plugin hoopit-devCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.