commit 569ae39e1bc7903f8995b3f50c8e13252350c92d Author: Zhongwei Li Date: Sun Nov 30 08:46:30 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..17ab724 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "hyperfleet-jira", + "description": "JIRA integration for HyperFleet team - sprint management, task tracking, ticket creation with proper JIRA wiki markup, hygiene validation, and story point estimation", + "version": "0.3.3", + "author": { + "name": "Ciaran Roche", + "email": "croche@redhat.com" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5ddd16b --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# hyperfleet-jira + +JIRA integration for HyperFleet team - sprint management, task tracking, ticket creation with proper JIRA wiki markup, hygiene validation, and story point estimation diff --git a/commands/hygiene-check.md b/commands/hygiene-check.md new file mode 100644 index 0000000..bc9ff60 --- /dev/null +++ b/commands/hygiene-check.md @@ -0,0 +1,125 @@ +--- +description: Audit sprint tickets for missing required fields and quality issues +allowed-tools: Bash +argument-hint: [scope: sprint|backlog|all] +--- + +# Hygiene Check + +Audit JIRA tickets for missing required fields and quality issues. + +## Arguments +- `$1` (optional): Scope of check + - `sprint` (default): Current sprint tickets only + - `backlog`: Backlog items + - `all`: All recent tickets + +## Instructions + +1. **Get tickets to audit (current sprint by default):** + ```bash + jira sprint list --current -p HYPERFLEET --json 2>/dev/null + ``` + +2. **Find tickets without story points:** + ```bash + jira issue list -q"project = HYPERFLEET AND 'Story Points' is EMPTY AND sprint in openSprints() AND issuetype in (Story, Task, Bug)" --plain 2>/dev/null + ``` + +3. **Find tickets with minimal description:** + ```bash + jira issue list -q"project = HYPERFLEET AND sprint in openSprints() AND description is EMPTY" --plain 2>/dev/null + ``` + +4. **Find unassigned tickets in sprint:** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee is EMPTY AND sprint in openSprints()" --plain 2>/dev/null + ``` + +5. **Find tickets without components:** + ```bash + jira issue list -q"project = HYPERFLEET AND component is EMPTY AND sprint in openSprints()" --plain 2>/dev/null + ``` + +6. **Find stale tickets (no updates in 7+ days):** + ```bash + jira issue list -q"project = HYPERFLEET AND sprint in openSprints() AND status != Done AND updated < -7d" --plain 2>/dev/null + ``` + +7. **Find tickets without labels:** + ```bash + jira issue list -q"project = HYPERFLEET AND labels is EMPTY AND sprint in openSprints()" --plain 2>/dev/null + ``` + +8. **For detailed ticket inspection, view individual tickets:** + ```bash + jira issue view TICKET-KEY --plain 2>/dev/null + ``` + +## Output Format + +### Hygiene Report + +#### Missing Story Points +| Ticket | Summary | Type | Assignee | +|--------|---------|------|----------| +| TICKET-1 | [Summary] | Story | [Name] | + +**Action Required:** These tickets need estimation before sprint planning. + +--- + +#### Missing/Inadequate Description +| Ticket | Summary | Description Length | +|--------|---------|-------------------| +| TICKET-1 | [Summary] | Empty | +| TICKET-2 | [Summary] | < 50 chars | + +**Action Required:** Add detailed description with context and acceptance criteria. + +--- + +#### Unassigned Tickets +| Ticket | Summary | Priority | Days in Sprint | +|--------|---------|----------|----------------| + +**Action Required:** Assign owner or move to backlog. + +--- + +#### Missing Components +| Ticket | Summary | +|--------|---------| + +**Action Required:** Assign appropriate component for tracking. + +--- + +#### Stale Tickets (No Update 7+ Days) +| Ticket | Summary | Status | Last Updated | +|--------|---------|--------|--------------| + +**Action Required:** Update status or add comment on progress. + +--- + +### Summary Score + +| Check | Pass | Fail | Score | +|-------|------|------|-------| +| Story Points | X | X | X% | +| Description | X | X | X% | +| Assignee | X | X | X% | +| Component | X | X | X% | +| Freshness | X | X | X% | +| **Overall** | | | **X%** | + +### Sprint Readiness +- **Ready for Sprint:** X tickets +- **Needs Work:** X tickets +- **Critical Issues:** X tickets + +### Top Priority Fixes +1. [Most critical hygiene issue] +2. [Second priority] +3. [Third priority] diff --git a/commands/my-sprint.md b/commands/my-sprint.md new file mode 100644 index 0000000..00fffcb --- /dev/null +++ b/commands/my-sprint.md @@ -0,0 +1,50 @@ +--- +description: Show current sprint and your assigned tasks +allowed-tools: Bash +--- + +# My Sprint + +Show the current sprint information and the user's assigned tickets. + +## Instructions + +1. **Get current sprint overview:** + ```bash + jira sprint list --current -p HYPERFLEET --plain 2>/dev/null || echo "Error: Could not fetch sprint. Is jira-cli configured?" + ``` + +2. **Get user's assigned tickets in current sprint:** + ```bash + jira sprint list --current -p HYPERFLEET -a$(jira me) --plain 2>/dev/null + ``` + +3. **Get ticket status breakdown:** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee = currentUser()" --created-after "-30d" --plain 2>/dev/null + ``` + +## Output Format + +Summarize the results in a clear format: + +### Sprint Overview +- Sprint name and goal (if available) +- Days remaining in sprint +- Sprint progress indicator + +### Your Tickets +Group by status: +- **To Do**: List tickets not yet started +- **In Progress**: List tickets being worked on +- **In Review/QA**: List tickets awaiting review +- **Done**: List completed tickets + +### Summary +- Total tickets assigned: X +- Story points assigned: X (if visible) +- Any blockers or high-priority items to highlight + +If jira-cli is not installed or configured, inform the user they need to: +1. Install jira-cli: `brew install ankitpokhrel/jira-cli/jira-cli` +2. Configure it: `jira init` diff --git a/commands/my-tasks.md b/commands/my-tasks.md new file mode 100644 index 0000000..ff3c5cd --- /dev/null +++ b/commands/my-tasks.md @@ -0,0 +1,50 @@ +--- +description: List all your assigned JIRA tasks across projects +allowed-tools: Bash +--- + +# My Tasks + +Show all JIRA tickets currently assigned to the user. + +## Instructions + +1. **Get all assigned tickets (recent, sorted by updated):** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee = currentUser()" --order-by updated --reverse --plain 2>/dev/null + ``` + +2. **For more detail with JSON output:** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee = currentUser()" --order-by updated --reverse --json 2>/dev/null | head -100 + ``` + +## Output Format + +Present tickets grouped by status: + +### In Progress +| Key | Summary | Priority | Updated | +|-----|---------|----------|---------| + +### To Do +| Key | Summary | Priority | Created | +|-----|---------|----------|---------| + +### Blocked / On Hold +| Key | Summary | Blocker Reason | +|-----|---------|----------------| + +### Recently Completed (last 7 days) +| Key | Summary | Completed | +|-----|---------|-----------| + +## Summary Stats +- Total active tickets: X +- Oldest ticket age: X days +- Tickets updated today: X + +## Tips +- Highlight any tickets not updated in 7+ days +- Flag high-priority tickets that need attention +- Note any tickets missing story points diff --git a/commands/new-comments.md b/commands/new-comments.md new file mode 100644 index 0000000..bd46d13 --- /dev/null +++ b/commands/new-comments.md @@ -0,0 +1,48 @@ +--- +description: Find tickets with new comments you may have missed +allowed-tools: Bash +--- + +# New Comments + +Find JIRA tickets with recent comments that the user should be aware of. + +## Instructions + +1. **Find tickets you're involved with that have recent comments:** + ```bash + jira issue list -q"project = HYPERFLEET AND (assignee = currentUser() OR reporter = currentUser() OR watcher = currentUser()) AND updated >= -1d" --order-by updated --reverse --plain 2>/dev/null + ``` + +2. **Alternative - find recently updated tickets you're assigned to:** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee = currentUser()" --updated-after "-1d" --order-by updated --reverse --plain 2>/dev/null + ``` + +3. **View specific ticket to see comments (for each relevant ticket):** + ```bash + jira issue view TICKET-KEY --comments 5 --plain 2>/dev/null + ``` + +## Output Format + +### Tickets with Recent Activity + +For each ticket with new comments: + +**TICKET-KEY: Summary** +- Last updated: [timestamp] +- Latest comment by: [author] +- Comment preview: [first 100 chars of comment] + +--- + +### Summary +- Tickets with new comments: X +- Comments requiring your response: X (where you were @mentioned) + +## Notes +- Focus on tickets updated in the last 24 hours by default +- If user specifies a different timeframe (e.g., "last week"), adjust the JQL accordingly +- Highlight any comments that directly mention the user +- Flag urgent/blocking discussions diff --git a/commands/sprint-status.md b/commands/sprint-status.md new file mode 100644 index 0000000..ac0593c --- /dev/null +++ b/commands/sprint-status.md @@ -0,0 +1,94 @@ +--- +description: Sprint health overview for team leads - progress, blockers, and risks +allowed-tools: Bash +argument-hint: [project-key] +--- + +# Sprint Status (Team Lead View) + +Comprehensive sprint health report for team leads and scrum masters. + +## Arguments +- `$1` (optional): Project key (e.g., HYPERFLEET). If not provided, uses HYPERFLEET as default. + +## Instructions + +1. **Get current sprint info:** + ```bash + jira sprint list --current -p HYPERFLEET --plain 2>/dev/null + ``` + +2. **Get all tickets in current sprint:** + ```bash + jira sprint list --current -p HYPERFLEET --plain 2>/dev/null + ``` + +3. **Get tickets by status - To Do:** + ```bash + jira issue list -q"project = HYPERFLEET AND status = 'To Do'" --created-after "-30d" --plain 2>/dev/null + ``` + +4. **Get tickets by status - In Progress:** + ```bash + jira issue list -q"project = HYPERFLEET AND status = 'In Progress'" --plain 2>/dev/null + ``` + +5. **Get tickets by status - Done (this sprint):** + ```bash + jira issue list -q"project = HYPERFLEET AND status = Done" --updated-after "-14d" --plain 2>/dev/null + ``` + +6. **Find blockers (high priority not done):** + ```bash + jira issue list -q"project = HYPERFLEET AND priority = Highest AND status != Done" --plain 2>/dev/null + jira issue list -q"project = HYPERFLEET AND priority = High AND status != Done" --plain 2>/dev/null + ``` + +7. **Find unassigned tickets:** + ```bash + jira issue list -q"project = HYPERFLEET AND assignee is EMPTY AND sprint in openSprints()" --plain 2>/dev/null + ``` + +## Output Format + +### Sprint Overview +``` +Sprint: [Sprint Name] +Duration: [Start Date] - [End Date] +Days Remaining: X days +``` + +### Progress Summary +| Status | Count | Story Points | +|--------|-------|--------------| +| To Do | X | X pts | +| In Progress | X | X pts | +| Done | X | X pts | +| **Total** | **X** | **X pts** | + +Progress: [=========> ] 65% complete + +### Risk Assessment + +#### Blockers & High Priority +- TICKET-1: [Summary] - Assigned to [Name] - [X days in status] +- TICKET-2: [Summary] - **UNASSIGNED** + +#### At-Risk Items +- Tickets in progress > 5 days without update +- Tickets without story points +- Unassigned tickets + +#### Carry-Over Risk +- Tickets likely to spill: X +- Story points at risk: X + +### Team Workload +| Team Member | To Do | In Progress | Done | +|-------------|-------|-------------|------| +| [Name] | X | X | X | + +### Recommendations +- List actionable items for the team lead +- Highlight tickets needing attention +- Suggest re-assignments if workload is unbalanced diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..84d0e05 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,73 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:openshift-hyperfleet/hyperfleet-claude-plugins:hyperfleet-jira", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "eee84ea4b554795433577dc7d8bc2832274fce9a", + "treeHash": "0f113ab8d3b1c6099bacad1c9898f9a97c2daa48fda02b4409e86d96b208fe5f", + "generatedAt": "2025-11-28T10:27:32.194465Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "hyperfleet-jira", + "description": "JIRA integration for HyperFleet team - sprint management, task tracking, ticket creation with proper JIRA wiki markup, hygiene validation, and story point estimation", + "version": "0.3.3" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "3a0912ed51e107cf1d5abbbc7e76457c047c2dea506eea20940bcd4e9112fabd" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "f36f534283484f663472b7f9dbf2f0a102b9e550051589569e65657b618fff5b" + }, + { + "path": "commands/my-tasks.md", + "sha256": "573924a96d06c8b4f0c10d197e4f19a7f57cb65bab6b9ed77e38d8c8e4388527" + }, + { + "path": "commands/new-comments.md", + "sha256": "f96da651cd2c61834d80ab332fb3a14d361aba81bbe0abc2282709dd6d888848" + }, + { + "path": "commands/my-sprint.md", + "sha256": "3c2539e5a2ddf82326c0aa7ee556d632ef01593a27db0627f4fca43096d73870" + }, + { + "path": "commands/sprint-status.md", + "sha256": "23615c241278ecf92e3e83f217247fcbb7e8ccf12fbddad7528ec268dc38d7d9" + }, + { + "path": "commands/hygiene-check.md", + "sha256": "0580a9e3cf81b1d21cd4712a3799207800918383428fd1d5cd76bbfbfb6827b2" + }, + { + "path": "skills/jira-ticket-creator/SKILL.md", + "sha256": "962533f3220dcfaf9fab16c47b162f057f0248666f6f7673b7afb021711ff9bf" + }, + { + "path": "skills/jira-hygiene/SKILL.md", + "sha256": "e5c8df8409a873c641cf4e08e1bfb4e3f0dafaca7b0f479a1a6290dec13d9468" + }, + { + "path": "skills/jira-story-pointer/SKILL.md", + "sha256": "390125bf4c5ce118ae0c2ec118cbec2aab8a517ec1fed6e6e4765dd2df15cbf8" + } + ], + "dirSha256": "0f113ab8d3b1c6099bacad1c9898f9a97c2daa48fda02b4409e86d96b208fe5f" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/jira-hygiene/SKILL.md b/skills/jira-hygiene/SKILL.md new file mode 100644 index 0000000..c0bc4d4 --- /dev/null +++ b/skills/jira-hygiene/SKILL.md @@ -0,0 +1,127 @@ +--- +name: JIRA Ticket Hygiene Checker +description: Validates JIRA tickets have required fields and sufficient information for development. Activates when users ask about ticket quality, readiness, or completeness, or when reviewing tickets before sprint planning. +--- + +# JIRA Ticket Hygiene Skill + +## When to Use This Skill + +Activate this skill when the user: +- Asks if a ticket is "ready", "complete", or "well-defined" +- Asks about ticket quality or completeness +- Wants to review a ticket before sprint planning +- Asks "does this ticket have enough information?" +- Wants to validate tickets meet team standards +- Asks about missing fields or requirements + +## Hygiene Checklist + +### Required Fields (Must Have) +- [ ] **Title**: Clear, actionable, under 100 characters +- [ ] **Description**: Detailed context (recommend > 100 characters) +- [ ] **Acceptance Criteria**: At least 2 clear, testable criteria +- [ ] **Story Points**: Set for Stories, Tasks, and Bugs (use scale: 0, 1, 3, 5, 8, 13) +- [ ] **Assignee**: Someone owns the ticket +- [ ] **Component**: Assigned to track by area +- [ ] **Activity Type**: Must be set for capacity planning (see Activity Types below) + +### Recommended Fields +- [ ] **Labels**: At least 1 relevant label +- [ ] **Epic Link**: Connected to parent epic (for Stories) +- [ ] **Fix Version**: Target release identified +- [ ] **Priority**: Explicitly set (not just default) + +### Quality Checks +- [ ] No ambiguous language ("maybe", "probably", "TBD", "possibly") +- [ ] Technical approach outlined or referenced +- [ ] Dependencies identified and linked +- [ ] Not a duplicate of existing ticket +- [ ] Scope is achievable in one sprint + +## How to Check a Ticket + +Use jira-cli to fetch ticket details: + +```bash +jira issue view TICKET-KEY --plain 2>/dev/null +``` + +For JSON output with all fields: +```bash +jira issue view TICKET-KEY --json 2>/dev/null +``` + +## Output Format + +When analyzing a ticket, provide: + +### Ticket: TICKET-KEY + +**Summary:** [Ticket title] + +#### Hygiene Assessment + +| Check | Status | Notes | +|-------|--------|-------| +| Title | PASS/FAIL | [Issue if any] | +| Description | PASS/FAIL | [Length: X chars] | +| Acceptance Criteria | PASS/FAIL | [Count: X criteria] | +| Story Points | PASS/FAIL | [Value or "Missing"] | +| Assignee | PASS/FAIL | [Name or "Unassigned"] | +| Component | PASS/FAIL | [Component or "None"] | +| Activity Type | PASS/FAIL | [Type or "Uncategorized"] | + +#### Overall Score: X/7 Required Checks Passed + +#### Verdict +- **READY FOR SPRINT** - All required fields present, good quality +- **NEEDS MINOR FIXES** - 1-2 issues to address +- **NOT READY** - Multiple critical issues + +#### Recommended Actions +1. [Specific action to fix issue 1] +2. [Specific action to fix issue 2] + +## Activity Types (Sankey Capacity Allocation) + +Activity Type is **required** for sprint/kanban capacity planning. Tickets without an Activity Type appear as "Uncategorized" and cannot be properly allocated. + +### Reactive Work (Non-Negotiable First) +| Activity Type | Description | Examples | +|---------------|-------------|----------| +| **Associate Wellness & Development** | Onboarding, team growth, training, associate experience | Training sessions, mentorship | +| **Incidents & Support** | Escalations, production issues | Customer escalations, outages | +| **Security & Compliance** | Vulnerabilities and weaknesses, CVEs | Security patches, compliance fixes | + +### Core Principles (Quality Focus) +| Activity Type | Description | Examples | +|---------------|-------------|----------| +| **Quality / Stability / Reliability** | Bugs, SLOs, chores, tech debt, PMR action items, toil reduction | Bug fixes, performance improvements | + +### Proactive Work (Balance Remaining Capacity) +| Activity Type | Description | Examples | +|---------------|-------------|----------| +| **Future Sustainability** | Productivity improvements, team improvements, upstream, proactive architecture, enablement | Tooling, automation, refactoring | +| **Product / Portfolio Work** | Strategic portfolio (HATSTRAT), strategic product, product outcome, BU features | New features, product enhancements | + +### Priority Order +1. **Non-Negotiable**: Achieve SLAs for Escalations & CVEs +2. **Core Principles**: Reduce bug backlog, ensure quality/stability/reliability +3. **Then Balance**: Set up for long-term success by balancing remaining capacity between Future Sustainability and Product Work + +## Red Flags to Highlight + +- Descriptions under 50 characters +- "TBD" or placeholder text in any field +- Story points of 13+ (must be broken down) +- No acceptance criteria at all +- Vague titles like "Fix bug" or "Update feature" +- Tickets open > 30 days without progress +- **Missing Activity Type** (appears as Uncategorized in capacity planning) + +## Integration with Commands + +This skill complements the `/hygiene-check` command: +- Command: Bulk audit of sprint tickets +- Skill: Deep-dive on individual ticket quality diff --git a/skills/jira-story-pointer/SKILL.md b/skills/jira-story-pointer/SKILL.md new file mode 100644 index 0000000..89c98ae --- /dev/null +++ b/skills/jira-story-pointer/SKILL.md @@ -0,0 +1,152 @@ +--- +name: JIRA Story Point Estimator +description: Estimates story points for JIRA tickets by analyzing complexity, scope, and comparing to historical team data. Activates when users ask to estimate, point, or size a ticket, or ask "how many points should this be?" +--- + +# JIRA Story Point Estimator Skill + +## When to Use This Skill + +Activate this skill when the user: +- Asks "estimate this ticket" or "how many story points?" +- Asks to "size" or "point" a ticket +- Asks "what should this be pointed at?" +- Wants help with sprint planning estimation +- Asks "is X points right for this ticket?" +- Reviews a ticket that needs story points + +## Story Point Scale Reference + +HyperFleet uses a modified Fibonacci sequence for story points: + +| Points | Meaning | Typical Scope | Notes | +|--------|---------|---------------|-------| +| **0** | Tracking Only | Quick/easy task with stakeholder value | Rarely used. For tasks worth tracking but with negligible effort compared to a 1-pointer | +| **1** | Trivial | One-line change, extremely simple task | The smallest issue possible - everything scales from here. No risk, very low effort, very low complexity | +| **3** | Straightforward | Time consuming but fairly straightforward work | Doesn't have to be complex, but usually time consuming. Minor risks possible | +| **5** | Medium | Requires investigation, design, collaboration | Probably needs discussion with others. Can be quite time consuming or complex. Risks involved | +| **8** | Large | Big task requiring investigation and design | Requires collaboration with others. Solution can be quite challenging. Risks are expected. **Design doc required** | +| **13** | Too Large | Should be split into smaller stories | Ideally, this shouldn't be used. If you see an issue this big, it must be broken down | + +## Estimation Methodology + +### Step 1: Fetch Ticket Details + +```bash +jira issue view TICKET-KEY --plain 2>/dev/null +``` + +### Step 2: Analyze Complexity Factors + +**Scope Indicators (examine description and acceptance criteria):** +- Number of acceptance criteria +- Number of components/files likely affected +- Integration points mentioned +- Testing requirements + +**Complexity Indicators:** +- New feature vs. modification vs. bug fix +- Requires new patterns or unfamiliar technology +- External dependencies (APIs, services) +- Database/schema changes +- Security implications +- Documentation requirements + +**Risk Indicators:** +- Ambiguity in requirements +- Dependencies on other tickets +- Time-sensitive (blocks other work) +- Requires coordination with other teams + +### Step 3: Find Similar Historical Tickets + +Search for comparable completed tickets: + +```bash +jira issue list -q"project = HYPERFLEET AND status = Done AND type = Story" --plain 2>/dev/null | head -20 +``` + +```bash +jira issue list -q"project = HYPERFLEET AND status = Done AND 'Story Points' is not EMPTY AND type = Story" --plain 2>/dev/null | head -20 +``` + +### Step 4: Provide Estimation + +## Output Format + +### Estimation for: TICKET-KEY + +**Summary:** [Ticket title] +**Type:** [Story/Task/Bug] + +--- + +#### Complexity Analysis + +| Factor | Assessment | Impact | +|--------|------------|--------| +| Scope | [Small/Medium/Large] | [Description] | +| Technical Complexity | [Low/Medium/High] | [Why] | +| Dependencies | [None/Few/Many] | [List if any] | +| Testing Effort | [Minimal/Moderate/Extensive] | [Why] | +| Risk/Uncertainty | [Low/Medium/High] | [Why] | + +--- + +#### Recommendation + +**Suggested Story Points: X** + +**Confidence Level:** [High/Medium/Low] + +**Reasoning:** +- [Primary factor 1] +- [Primary factor 2] +- [Comparison to similar work] + +--- + +#### Similar Completed Tickets (for reference) + +| Ticket | Summary | Points | Similarity | +|--------|---------|--------|------------| +| TICKET-A | [Summary] | 5 | High - similar scope | +| TICKET-B | [Summary] | 3 | Medium - simpler version | + +--- + +#### Considerations + +- **If higher:** [What would make this larger] +- **If lower:** [What would make this smaller] +- **Break-down suggestion:** [If 13+ points, suggest how to split] + +## Setting Story Points + +Once agreed, set story points using: + +```bash +jira issue edit TICKET-KEY --custom story-points=X --no-input +``` + +Or for Story Point Estimate field (Next-gen projects): + +```bash +jira issue edit TICKET-KEY --custom story-point-estimate=X --no-input +``` + +## Team Calibration Notes + +When estimating, consider: +- Team's typical velocity (points completed per sprint) +- Recent similar work and how long it actually took +- Team familiarity with the codebase area +- Current sprint load and focus + +## Anti-Patterns to Flag + +- **Anchoring**: Don't let existing (wrong) estimates bias you +- **Scope Creep**: Point what's written, not what might be added +- **Hero Estimates**: Assume average team member, not expert +- **Planning Fallacy**: Add buffer for unknowns +- **Story Point Inflation**: Keep consistent with team baseline diff --git a/skills/jira-ticket-creator/SKILL.md b/skills/jira-ticket-creator/SKILL.md new file mode 100644 index 0000000..9750895 --- /dev/null +++ b/skills/jira-ticket-creator/SKILL.md @@ -0,0 +1,696 @@ +--- +name: JIRA Ticket Creator +description: Creates well-structured JIRA tickets in the HYPERFLEET project with required fields including What/Why/Acceptance Criteria, story points, and activity type. Activates when users ask to create a ticket, story, task, or epic. +--- + +# JIRA Ticket Creator Skill + +## ⚠️ CRITICAL: JIRA Uses Wiki Markup, NOT Markdown! + +**YOU MUST USE JIRA WIKI MARKUP SYNTAX - NEVER USE MARKDOWN!** + +| Element | ❌ WRONG | ✅ CORRECT | +|---------|----------|------------| +| **Header** | `### What` | `h3. What` (space required!) | +| **Bullets** | `- Item` or `• Item` | `* Item` | +| **Nested** | ` - Nested` | `** Nested` | +| **Inline Code** | `` `code` `` | `{{code}}` | +| **Bold** | `**text**` | `*text*` | +| **Path Params** | `/api/{id}` | `/api/:id` or `/api/ID` | +| **Placeholders** | `{customer-id}` | `CUSTOMER_ID` or `:customer_id` | + +**If you use Markdown syntax, the ticket will render incorrectly in JIRA!** + +See "CRITICAL: JIRA Wiki Markup Formatting" section below for complete reference. + +--- + +## When to Use This Skill + +Activate this skill when the user: +- Asks to "create a ticket" or "create a story/task/epic" +- Says "I need a JIRA ticket for..." +- Asks "can you create a ticket for [feature/bug/task]?" +- Wants to document work as a JIRA issue +- Asks to "file a ticket" or "add a story" +- Provides work that needs to be tracked + +## Required Ticket Structure + +Every ticket created MUST include: + +### 1. **What** (Required) +Clear, concise description of what needs to be done. Should be 2-4 sentences explaining the work. + +### 2. **Why** (Required) +Business justification and context. Explain: +- Why this work matters +- Who benefits (users, team, system) +- What problem it solves or value it delivers + +### 3. **Acceptance Criteria** (Required) +Minimum 2-3 clear, testable criteria that define "done": +- Must be objective and verifiable +- Should cover functional requirements and edge cases +- Use bullet format with specific details + +### 4. **Story Points** (Required for Stories/Tasks/Bugs) +All Stories, Tasks, and Bugs must have story points: +- Use scale: 0, 1, 3, 5, 8, 13 +- Follow the team's estimation guide (see Story Points section) + +### 5. **Activity Type** (Required for Stories/Tasks/Bugs) +Must set activity type for capacity planning. Valid types: +- `Associate Wellness & Development` +- `Incidents & Support` +- `Security & Compliance` +- `Quality / Stability / Reliability` +- `Future Sustainability` +- `Product / Portfolio Work` + +### 6. Optional Context +Additional sections can be added as needed: +- **Technical Notes**: High-level implementation plan +- **Dependencies**: Linked tickets or external dependencies +- **Out of Scope**: Explicitly state what's NOT included + +## CRITICAL: JIRA Wiki Markup Formatting + +**JIRA uses wiki markup, NOT Markdown!** + +### Headers +``` +h3. What ✅ Correct (space after period!) +h3. Why ✅ Correct +**What** ❌ Wrong (Markdown syntax) +### What ❌ Wrong (Markdown syntax) +``` + +### Bullets +``` +* Item 1 ✅ Correct +** Nested item ✅ Correct (two asterisks) +- Item 1 ❌ Wrong (Markdown syntax) +• Item 1 ❌ Wrong (Unicode bullet) + - Nested ❌ Wrong (indentation + dash) +``` + +**Real Example - HYPERFLEET-255 (WRONG):** +``` +### Summary ❌ Markdown header - won't render! + +• POST /api/... ❌ Unicode bullet - won't render! +``` + +**Should Have Been:** +``` +h3. Summary ✅ JIRA wiki header + +* POST /api/... ✅ JIRA wiki bullet +``` + +### Inline Code +``` +{{package/path}} ✅ Correct +{{variable_name}} ✅ Correct +`package/path` ❌ Wrong (Markdown syntax) +``` + +### Bold/Italic +``` +*bold text* ✅ Correct +_italic text_ ✅ Correct +**bold** ❌ Wrong (Markdown syntax) +``` + +### Code Blocks +**DO NOT use code blocks in CLI-created tickets!** They don't render properly. + +``` +{code:go} ❌ Don't use via CLI (renders as empty gray box) +package main +{/code} +``` + +**Instead:** +- Use inline code: `{{package_name}}` +- Add code examples manually via web UI after creation +- Or use descriptive text with inline code references + +### API Endpoints +``` +*POST* /api/v1/clusters/:id ✅ Correct (bold HTTP method, colon notation) +*GET* /api/v1/clusters/CLUSTER_ID ✅ Correct (placeholder text) +*POST* /api/v1/clusters/{id} ❌ Wrong - curly braces break rendering! +{{POST /api/v1/clusters/{id}}} ❌ Wrong (nested braces break rendering) +``` + +### Curly Braces Warning +**NEVER use curly braces `{}` in ticket descriptions - they break JIRA rendering!** + +``` +wif-{customer-id}-key ❌ Wrong - curly braces break rendering! +{{wif-{customer-id}-key}} ❌ Wrong - nested braces also break! +wif-CUSTOMER_ID-key ✅ Correct - use CAPS or other notation +/api/v1/clusters/{id} ❌ Wrong - path parameter braces break! +/api/v1/clusters/:id ✅ Correct - use colon notation +/api/v1/clusters/CLUSTER_ID ✅ Correct - use placeholder text +``` + +**Alternatives to curly braces:** +* Use SCREAMING_CASE: `wif-CUSTOMER_ID-key` +* Use colon notation: `/api/v1/clusters/:id` +* Use angle brackets: `wif--key` +* Use square brackets: `wif-[customer-id]-key` + +### YAML in Code Blocks +**NEVER include YAML comments in code blocks!** The `#` character is interpreted as `h1.` header. + +**Wrong:** +``` +{code:yaml} +# This is a comment +field: value +{/code} +``` + +**Correct Option 1 - Descriptive text:** +``` +Configuration fields: +* {{field: value}} - Description of field +``` + +**Correct Option 2 - Code block without comments:** +``` +{code:yaml} +field: value +{/code} + +Explanation outside code block... +``` + +## Ticket Creation Workflow + +### Step 1: Gather Requirements + +Ask the user clarifying questions if needed: +- What type of ticket? (Epic, Story, Task, Bug) +- What needs to be done? (What) +- Why is this important? (Why) +- How will we know it's done? (Acceptance Criteria) +- How complex/large is this work? (for story points) +- What category of work is this? (for activity type) + +### Step 2: Create Description File + +**⚠️ CRITICAL: Always create a temporary file with JIRA wiki markup (NOT Markdown!):** + +**DO NOT USE:** +- `### Headers` (Markdown) +- `- bullets` or `• bullets` (Markdown/Unicode) +- `` `inline code` `` (Markdown) +- `**bold**` (Markdown) + +**USE ONLY:** +- `h3. Headers` (JIRA wiki - space required!) +- `* bullets` (JIRA wiki) +- `{{inline code}}` (JIRA wiki) +- `*bold*` (JIRA wiki) + +**Template for Stories/Tasks (JIRA Wiki Markup):** +``` +h3. What + +Brief description paragraph. + +Detailed explanation paragraph (optional). + +h3. Why + +* Reason 1 +* Reason 2 +* Reason 3 + +h3. Acceptance Criteria: + +* {{Component}} created/implemented/configured +* Feature X works correctly: +** Detail 1 +** Detail 2 +* Tests achieve >80% coverage +* Documentation updated + +h3. Technical Notes: + +* Use {{package-name}} for implementation +* Configuration in {{/path/to/config.yaml}} +* Important consideration +* Reference {{AnotherComponent}} + +h3. Out of Scope: + +* Item not included +* Another exclusion +``` + +**Template for Epics:** +``` +h1. Epic Title + +h3. Overview + +Brief overview paragraph. + +h3. What + +* Key deliverable 1 +* Key deliverable 2 +** Sub-item +* Key deliverable 3 + +h3. Why + +Explanation of business value and impact. + +h3. Scope + +*In Scope*: +* Item 1 +* Item 2 + +*Out of Scope*: +* Item 3 +* Item 4 + +h3. Success Criteria + +* Criterion 1 +* Criterion 2 +* Criterion 3 +``` + +### Step 3: Determine Story Points + +Use the estimation scale: + +| Points | Meaning | Typical Scope | +|--------|---------|---------------| +| **0** | Tracking Only | Quick/easy task, negligible effort | +| **1** | Trivial | One-line change, extremely simple | +| **3** | Straightforward | Time consuming but straightforward | +| **5** | Medium | Requires investigation, design, collaboration | +| **8** | Large | Big task, investigation & design required, needs design doc | +| **13** | Too Large | MUST be broken down into smaller stories | + +Consider: +- Scope (lines of code, files affected, integration points) +- Complexity (new patterns, unfamiliar tech) +- Risk (ambiguity, dependencies, unknowns) +- Testing effort + +### Step 4: Assign Activity Type + +Choose based on work category: + +**Reactive Work (Non-Negotiable First):** +- `Associate Wellness & Development` - Training, onboarding, team growth +- `Incidents & Support` - Customer escalations, production issues +- `Security & Compliance` - CVEs, security patches, compliance + +**Core Principles (Quality Focus):** +- `Quality / Stability / Reliability` - Bugs, tech debt, toil reduction, SLOs + +**Proactive Work (Balance Capacity):** +- `Future Sustainability` - Tooling, automation, architecture improvements +- `Product / Portfolio Work` - New features, strategic product work + +### Step 5: Create the Ticket via jira-cli + +**IMPORTANT: Use the patterns that actually work!** + +#### Creating a Story + +```bash +# 1. Save description to temporary file +cat > /tmp/story-description.txt << 'EOF' +h3. What + +Description of what needs to be done. + +h3. Why + +* Reason 1 +* Reason 2 + +h3. Acceptance Criteria: + +* Criterion 1 +* Criterion 2 +* Criterion 3 + +h3. Technical Notes: + +* Use {{package-name}} +* Configuration in {{/path/to/config}} +EOF + +# 2. Create story (NOTE: Do NOT use --custom for story points via CLI - set via web UI) +jira issue create --project HYPERFLEET --type Story \ + --summary "Story Title (< 100 chars)" \ + --no-input \ + -b "$(cat /tmp/story-description.txt)" + +# 3. Note the ticket number from output (e.g., HYPERFLEET-123) + +# 4. Set story points via web UI (jira-cli custom fields can be unreliable) +``` + +#### Creating a Task + +```bash +# Same as Story, just change --type to Task +cat > /tmp/task-description.txt << 'EOF' +h3. What + +Task description. + +h3. Why + +Justification. + +h3. Acceptance Criteria: + +* Criterion 1 +* Criterion 2 +EOF + +jira issue create --project HYPERFLEET --type Task \ + --summary "Task Title" \ + --no-input \ + -b "$(cat /tmp/task-description.txt)" +``` + +#### Creating an Epic + +**CRITICAL: Epics require the Epic Name field!** + +```bash +# 1. Create description file +cat > /tmp/epic-description.txt << 'EOF' +h1. Epic Full Title + +h3. Overview + +Overview paragraph. + +h3. What + +* Deliverable 1 +* Deliverable 2 + +h3. Why + +Explanation. + +h3. Success Criteria + +* Criterion 1 +* Criterion 2 +EOF + +# 2. Create epic with Epic Name (required field!) +jira issue create --project HYPERFLEET --type Epic \ + --summary "Epic: Full Title Here" \ + --custom epic-name="Short Name" \ + --template /tmp/epic-description.txt \ + --no-input + +# Note: Use --custom epic-name="Name" (not epicName or customfield_12311141) +``` + +#### Creating a Bug + +```bash +cat > /tmp/bug-description.txt << 'EOF' +h3. What + +Description of the bug and its impact. + +h3. Why + +Why this needs to be fixed urgently. + +h3. Acceptance Criteria: + +* Bug is reproducible +* Root cause identified +* Fix is verified +* Regression test added +EOF + +jira issue create --project HYPERFLEET --type Bug \ + --summary "Bug: Brief Description" \ + --no-input \ + -b "$(cat /tmp/bug-description.txt)" +``` + +### Step 6: Post-Creation Manual Steps + +After creating a ticket via CLI, these must be done manually via web UI: + +1. **Set Story Points** + - Edit ticket → Story Points field + - Custom fields via CLI are unreliable + +2. **Set Activity Type** + - Edit ticket → Activity Type field + - Select from dropdown + +3. **Link to Epic** (for Stories) + - Edit ticket → Link → "is child of" → Epic ticket + +4. **Add Labels** + - Edit ticket → Labels field + - Add relevant tags + +5. **Add Code Examples** (if needed) + - Edit description via web UI + - Add `{code:language}...{/code}` blocks + - Code blocks don't render properly via CLI + +### Step 7: Verify and Return Details + +```bash +# View created ticket +jira issue view HYPERFLEET-XXX --plain + +# Check in web UI +# URL: https://issues.redhat.com/browse/HYPERFLEET-XXX +``` + +Return to user: +- Ticket key (e.g., HYPERFLEET-123) +- Link: https://issues.redhat.com/browse/HYPERFLEET-123 +- Summary of what was created +- **List of manual steps needed** (story points, activity type, etc.) + +## Output Format + +When creating a ticket, provide this output to the user: + +``` +### Ticket Created: HYPERFLEET-XXX + +**Type:** [Story/Task/Epic/Bug] +**Summary:** [Title] +**Link:** https://issues.redhat.com/browse/HYPERFLEET-XXX + +--- + +#### Description Structure (✅ Created via CLI) + +**What:** +[What description] + +**Why:** +[Why description] + +**Acceptance Criteria:** +* Criterion 1 +* Criterion 2 +* Criterion 3 + +--- + +#### Manual Steps Required (⚠️ Must be done via Web UI) + +Please complete these steps in the JIRA web interface: + +1. **Set Story Points**: [Recommended: X points based on complexity] +2. **Set Activity Type**: [Recommended: {activity type}] +3. **Link to Epic**: [If applicable: Link to HYPERFLEET-XXX] +4. **Add Labels**: [Suggested: label1, label2] +5. **Add Code Examples**: [If needed: Add via web UI description editor] + +**Why manual?** Custom fields and code blocks don't render reliably via jira-cli. +``` + +## Common Pitfalls to Avoid + +### ❌ DON'T: + +**FORMATTING (Most Common Mistakes!):** +1. ❌ Use Markdown headers: `### What`, `## Summary` +2. ❌ Use Markdown/Unicode bullets: `- Item`, `• Item` +3. ❌ Use Markdown inline code: `` `code` `` +4. ❌ Use Markdown bold: `**text**` +5. ❌ Forget space after JIRA headers: `h3.What` (needs `h3. What`) + +**TICKET EXAMPLES OF WRONG FORMATTING:** +- HYPERFLEET-255: Used `### Summary` and `• bullets` - headers didn't render! + +**CURLY BRACES (Break JIRA Rendering!):** +6. ❌ Use curly braces `{}` anywhere - e.g., `{customer-id}`, `/api/{id}` - breaks rendering! +7. ❌ Use `{{}}` around content with braces - doubly broken! + +**OTHER MISTAKES:** +8. ❌ Include code blocks with `{code}...{/code}` via CLI (renders as empty boxes) +9. ❌ Put YAML comments (`#`) in code blocks (breaks rendering) +10. ❌ Use `--custom` fields via CLI (unreliable for story points, activity type) +11. ❌ Use `--body-file` flag (doesn't exist!) +12. ❌ Mix Markdown and JIRA wiki markup in same ticket + +**TICKET EXAMPLES OF CURLY BRACE ISSUES:** +- HYPERFLEET-258: Used `{customer-id}` - broke rendering! Fixed with CUSTOMER_ID + +### ✅ DO: +1. Use JIRA wiki markup consistently +2. Save descriptions to temporary files: `-b "$(cat /tmp/file.txt)"` +3. Test with ONE ticket before creating multiple +4. Use `--no-input` for non-interactive creation +5. Set custom fields via web UI after creation +6. Add code examples via web UI +7. Use bold for HTTP methods: `*POST* /api/path` +8. Use inline code for paths: `{{/path/to/file}}` + +## Troubleshooting + +### Issue: Epic Name Required Error +``` +Error: customfield_12311141: Epic Name is required. +``` + +**Solution:** +```bash +--custom epic-name="Short Name" ✅ Correct +--custom epicName="Name" ❌ Wrong +--custom customfield_12311141 ❌ Wrong +``` + +### Issue: Code Blocks Show as Empty Gray Boxes + +**Solution:** Don't include code blocks via CLI. Add them manually via web UI after creation. + +### Issue: Headers Not Rendering + +**Solution:** Ensure space after period: `h3. What` (not `h3.What`) + +### Issue: Bullets Not Working + +**Solution:** Use `*` not `-`, and `**` for nested (not indentation) + +### Issue: Custom Fields Won't Set + +**Solution:** Set story points and activity type via web UI. The jira-cli custom field handling is unreliable. + +## Best Practices + +### 1. Always Test First +```bash +# Create ONE test ticket +jira issue create --project HYPERFLEET --type Story \ + --summary "TEST - Delete Me" \ + -b "$(cat /tmp/test-description.txt)" \ + --no-input + +# Verify in CLI and web UI +jira issue view HYPERFLEET-XXX + +# If good, create remaining tickets +# Delete test ticket when done +``` + +### 2. Store Description Files +Don't create tickets with inline strings. Always use files: +```bash +# Good +cat > /tmp/description.txt << 'EOF' +... +EOF +jira issue create ... -b "$(cat /tmp/description.txt)" + +# Bad +jira issue create ... -b "h3. What\n\nLong description..." +``` + +### 3. Document Ticket Numbers +As tickets are created, track them: +```bash +# Epic created: HYPERFLEET-105 +# Stories: HYPERFLEET-106, HYPERFLEET-107, HYPERFLEET-108 +``` + +### 4. Batch Manual Steps +After creating multiple tickets via CLI: +1. List all ticket numbers +2. Open each in web UI +3. Batch set: story points, activity type, labels, epic links +4. More efficient than doing each individually + +## Integration with Other Skills + +This skill complements: +- **jira-story-pointer**: Use to refine story point estimates after creation +- **jira-hygiene**: Use to validate ticket quality after creation +- **jira-cli**: All operations use jira-cli under the hood + +## Quick Reference Card + +**Create Story:** +```bash +cat > /tmp/desc.txt << 'EOF' +h3. What +... +h3. Why +... +h3. Acceptance Criteria: +* ... +EOF + +jira issue create --project HYPERFLEET --type Story \ + --summary "Title" --no-input \ + -b "$(cat /tmp/desc.txt)" +``` + +**Create Epic:** +```bash +jira issue create --project HYPERFLEET --type Epic \ + --summary "Epic: Title" \ + --custom epic-name="Short Name" \ + --template /tmp/epic-desc.txt \ + --no-input +``` + +**Manual Steps (Web UI):** +1. Story Points +2. Activity Type +3. Link to Epic +4. Labels +5. Code examples + +**Formatting:** +- Headers: `h3. Text` (space!) +- Bullets: `*` and `**` +- Inline code: `{{code}}` +- Bold: `*text*` +- API endpoints: `*POST* /api/path/{id}`