6.1 KiB
6.1 KiB
Skill: sprint-report
Generate sprint status report from Jira data.
Invoked by
🎫 JiraOps mode (or 🪃 Orchestrator delegating to JiraOps)
Required Inputs
| Input | Source | Example |
|---|---|---|
PROJECT_KEY |
Jira project key | ESIDEPAISY |
SPRINT_ID |
Sprint ID (optional — auto-detected if omitted) | 1234 |
OUTPUT_FORMAT |
Report format (optional) | markdown, confluence, teams |
Output
- Markdown report:
docs/sprint-reports/sprint-<sprint_name>-<date>.md - Optionally: Confluence page or Teams message
Steps
1. Get active sprint
If SPRINT_ID is not provided, auto-detect:
# Get the board
boards = get_agile_boards(project_key="ESIDEPAISY")
board_id = boards[0]["id"]
# Get active sprint
sprints = get_sprints_from_board(board_id=board_id, states="active")
sprint = sprints[0]
sprint_id = sprint["id"]
sprint_name = sprint["name"]
2. Get sprint tickets
tickets = get_tickets_from_sprint(
sprint_id=sprint_id,
fields="project,summary,status,issuetype,assignee,customfield_10001,customfield_10106"
)
Key fields:
status— current ticket statusassignee— who's working on itissuetype— Story, Bug, Taskcustomfield_10106— Story Points (if configured)customfield_10001— Feature Link (Epic)
3. Categorize tickets by status
Group tickets into workflow buckets:
| Category | Statuses |
|---|---|
| To Do | Open, Backlog, To Do |
| In Progress | In Progress, In Development |
| In Review | In Review, Code Review |
| Done | Done, Accepted, Closed |
| Blocked | Any ticket with Blocked flag or label |
4. Calculate metrics
total = len(tickets)
done = len([t for t in tickets if t["status"] in DONE_STATUSES])
in_progress = len([t for t in tickets if t["status"] in PROGRESS_STATUSES])
todo = len([t for t in tickets if t["status"] in TODO_STATUSES])
completion_pct = round(done / total * 100) if total > 0 else 0
5. Group by assignee
by_assignee = {}
for ticket in tickets:
assignee = ticket.get("assignee", "Unassigned")
by_assignee.setdefault(assignee, []).append(ticket)
6. Group by Epic/Feature
by_epic = {}
for ticket in tickets:
epic = ticket.get("customfield_10001", "Kein Epic")
by_epic.setdefault(epic, []).append(ticket)
7. Generate report
Write docs/sprint-reports/sprint-<sprint_name>-<date>.md:
# Sprint Report: <sprint_name>
**Datum:** <today>
**Sprint:** <sprint_name>
**Zeitraum:** <start_date> — <end_date>
**Projekt:** ESIDEPAISY
---
## Übersicht
| Metrik | Wert |
|--------|------|
| Tickets gesamt | <total> |
| Erledigt | <done> (<completion_pct>%) |
| In Bearbeitung | <in_progress> |
| Offen | <todo> |
| In Review | <in_review> |
## Fortschritt
[████████████░░░░░░░░] 60% (/)
## Nach Status
### ✅ Erledigt (<done>)
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|--------|-----|----------------|------------|
| <key> | Story | <summary> | <assignee> |
### 🔄 In Bearbeitung (<in_progress>)
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|--------|-----|----------------|------------|
| <key> | Bug | <summary> | <assignee> |
### ⏳ Offen (<todo>)
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|--------|-----|----------------|------------|
| <key> | Task | <summary> | <assignee> |
## Nach Bearbeiter
| Bearbeiter | Gesamt | Erledigt | In Bearbeitung | Offen |
|-----------|--------|----------|---------------|-------|
| <name> | <n> | <done> | <wip> | <todo> |
## Nach Feature/Epic
| Epic | Tickets | Erledigt | Fortschritt |
|------|---------|----------|-------------|
| <epic_name> | <n> | <done> | <pct>% |
## Blocker / Risiken
| Ticket | Beschreibung | Seit | Auswirkung |
|--------|-------------|------|-----------|
| <key> | <blocker description> | <date> | <impact> |
<If no blockers: "Keine Blocker im aktuellen Sprint.">
8. Publish to Confluence (optional)
If OUTPUT_FORMAT includes confluence:
create_page(
space_key="ESIDEPAISY",
title=f"Sprint Report: {sprint_name} — {date}",
content=<html_converted_content>,
parent_id="<sprint-reports-parent-page-id>"
)
9. Send Teams summary (optional)
If OUTPUT_FORMAT includes teams:
teams_send_channel_message(
team_id="<team_id>",
channel_id="<channel_id>",
content=f"📊 *Sprint Report: {sprint_name}*\n\n"
f"Fortschritt: {done}/{total} ({completion_pct}%)\n"
f"In Bearbeitung: {in_progress}\n"
f"Offen: {todo}\n"
f"Blocker: {blocked}\n\n"
f"Vollständiger Bericht: <confluence_link or file path>"
)
10. Store in BigMind
memory_store_fact(
category="codebase",
fact=f"Sprint report for {sprint_name}: {done}/{total} done ({completion_pct}%), {in_progress} in progress, {blocked} blocked."
)
Expected Output
- Markdown sprint report with ticket breakdown
- Metrics: completion %, by-status, by-assignee, by-epic
- Blocker/risk section
- Optionally published to Confluence and/or Teams
Error Handling
| Error | Resolution |
|---|---|
| No active sprint found | Check states="active" — may need states="active,future" |
| No tickets in sprint | Sprint may be empty or newly created — report "0 tickets" |
| Board not found | Verify project key, try get_agile_boards with different key |
| Story points not configured | Skip story point metrics, use ticket count only |
| Confluence publish fails | Save markdown locally, report Confluence error |
Report Variants
| Variant | When | Content |
|---|---|---|
| Daily standup | Mid-sprint | Focus on in-progress + blockers only |
| Sprint review | End of sprint | Full report with all sections |
| Management summary | On request | Metrics + epic progress only, no ticket details |
Adjust the template based on the variant requested.
Language
- Report content: German
- Ticket keys, branch names: English as-is
- Teams messages: German
- Confluence page: German