Add BMAD Atlassian adapter module for Jira/Confluence output via MCP
Implements a new `src/atlassian/` module that routes BMAD artefacts to Jira (epics, stories, subtasks, transitions, sprints) and Confluence (PRDs, architecture docs, UX designs) via the Atlassian MCP server. Key components: - module.yaml: Configuration schema (project keys, transition IDs, dual-write toggle) - artefact-mapping.yaml: Authoritative mapping of every BMAD artefact to MCP tool calls - transition-discovery.md: Setup workflow to discover Jira workflow transition IDs - 4 reusable tasks: write-to-confluence, transition-jira-issue, lock-issue, read-jira-context - 5 workflow overrides: epics output, sprint planning, create-story, dev-story, code-review - 6 agent injection YAMLs: one per BMAD agent role - Automated orchestrator: JQL-based state polling + dispatch rules for agent invocation https://claude.ai/code/session_01GE7R9vLGsTa785ieSmeTT4
This commit is contained in:
parent
110d4cbc03
commit
c34898cdba
|
|
@ -0,0 +1,15 @@
|
|||
# Atlassian Adapter Injection for Analyst Agent (Mary)
|
||||
# Appended to analyst.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-analyst
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for all artefact output instead of writing local files"
|
||||
- "Read artefact mapping from {project-root}/_bmad/atlassian/artefact-mapping.yaml for output routing"
|
||||
- "Use {key_map_file} for Jira issue key and Confluence page ID lookups"
|
||||
- "When writing research reports or product briefs: invoke the write-to-confluence task at {project-root}/_bmad/atlassian/tasks/write-to-confluence.md"
|
||||
- "Title format for Confluence pages: '[{jira_project_key}] {artefact_type}: {title}'"
|
||||
- "Apply label '{agent_label_prefix}analyst' to every Confluence page you create"
|
||||
- "Store created page IDs in {key_map_file} under confluence_pages"
|
||||
- "If output_mode is 'dual': also write the artefact to the local file path as usual"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Atlassian Adapter Injection for Architect Agent (Winston)
|
||||
# Appended to architect.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-architect
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for all artefact output instead of writing local files"
|
||||
- "Read artefact mapping from {project-root}/_bmad/atlassian/artefact-mapping.yaml for output routing"
|
||||
- "Use {key_map_file} for Jira issue key and Confluence page ID lookups"
|
||||
- "Architecture Decision Document output: invoke the write-to-confluence task. Title: '[{jira_project_key}] Architecture: {project_name}'"
|
||||
- "Store page ID as confluence_pages.architecture in key map"
|
||||
- "After creating the Architecture page: link it from relevant Epics via Create Remote Issue Link"
|
||||
- "To find relevant Epics: look up epic keys from {key_map_file} or call Search Issues with JQL: project = {jira_project_key} AND issuetype = Epic"
|
||||
- "Apply label '{agent_label_prefix}architect' to every Confluence page you create"
|
||||
- "When reading PRD for architecture inputs: fetch from Confluence via Get Page using the page ID from {key_map_file}"
|
||||
- "If output_mode is 'dual': also write the architecture document to the local file path as usual"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Atlassian Adapter Injection for Developer Agent (Amelia)
|
||||
# Appended to dev.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-dev
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for status tracking and completion records"
|
||||
- "Read artefact mapping from {project-root}/_bmad/atlassian/artefact-mapping.yaml for output routing"
|
||||
- "Use {key_map_file} for Jira issue key lookups"
|
||||
- "Dev Story: use the Jira workflow override at {project-root}/_bmad/atlassian/workflow-overrides/4-implementation/dev-story/"
|
||||
- "Code Review: use the Jira workflow override at {project-root}/_bmad/atlassian/workflow-overrides/4-implementation/code-review/"
|
||||
- "Find next story via JQL: project = {jira_project_key} AND issuetype = Story AND status = 'Ready for Dev' ORDER BY rank ASC"
|
||||
- "Load story details from Jira via Get Issue instead of reading local story files"
|
||||
- "Before starting implementation: invoke lock-issue task with action 'lock'. On completion: invoke with action 'unlock'"
|
||||
- "Transition stories through In Progress → Review using transition-jira-issue reusable task"
|
||||
- "Post Dev Agent Record as a Jira comment on the story issue: include agent model, files changed, completion notes, test results"
|
||||
- "Post Code Review results as a Jira comment: include findings, AC verification, test coverage"
|
||||
- "Apply label '{agent_label_prefix}dev' to every Jira issue you modify"
|
||||
- "When review passes: transition to Done. When all Epic stories are Done: transition Epic to Done"
|
||||
- "If output_mode is 'dual': also update local story files with task completion markers"
|
||||
|
||||
menu_overrides:
|
||||
- trigger: DS
|
||||
workflow: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/dev-story/workflow-jira.yaml"
|
||||
description: "[DS] Dev Story (Jira): Implement a story with Jira status tracking"
|
||||
- trigger: CR
|
||||
workflow: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/code-review/workflow-jira.yaml"
|
||||
description: "[CR] Code Review (Jira): Review code and post findings to Jira"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Atlassian Adapter Injection for PM Agent (John)
|
||||
# Appended to pm.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-pm
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for all artefact output instead of writing local files"
|
||||
- "Read artefact mapping from {project-root}/_bmad/atlassian/artefact-mapping.yaml for output routing"
|
||||
- "Use {key_map_file} for Jira issue key and Confluence page ID lookups"
|
||||
- "PRD output: invoke the write-to-confluence task. Title: '[{jira_project_key}] PRD: {project_name}'. Store page ID as confluence_pages.prd in key map"
|
||||
- "Epic/Story output: use the Jira override step at {project-root}/_bmad/atlassian/workflow-overrides/3-solutioning/create-epics-and-stories/steps/step-04-jira-output.md"
|
||||
- "Create Epics as Jira Epic issues, Stories as Jira Story issues linked to their parent Epic via Link to Epic"
|
||||
- "Include PRD summary in each Epic description. Include acceptance criteria (Given/When/Then) in each Story description"
|
||||
- "Apply label '{agent_label_prefix}pm' to every Jira issue and Confluence page you create"
|
||||
- "After creating Epics: link each one to the PRD Confluence page via Create Remote Issue Link"
|
||||
- "Store all created issue keys in {key_map_file} under epics and stories sections"
|
||||
- "If output_mode is 'dual': also write artefacts to local files as usual"
|
||||
|
||||
menu_overrides:
|
||||
- trigger: CE
|
||||
description: "Uses Jira output step instead of local file write for epics/stories"
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Atlassian Adapter Injection for QA Agent (Quinn)
|
||||
# Appended to qa.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-qa
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for test reporting"
|
||||
- "Use {key_map_file} for Jira issue key lookups"
|
||||
- "After generating tests: post a test summary as a Jira comment on the relevant story issue via Add Comment"
|
||||
- "Comment format: list test files created, test count, coverage areas, and any gaps identified"
|
||||
- "Apply label '{agent_label_prefix}qa' to every Jira issue you comment on"
|
||||
- "Apply label 'bmad-tested' to stories that have test coverage"
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Atlassian Adapter Injection for Scrum Master Agent (Bob)
|
||||
# Appended to sm.agent.yaml critical_actions when atlassian module is installed
|
||||
|
||||
target_agent: bmad-sm
|
||||
injection_point: critical_actions
|
||||
|
||||
inject:
|
||||
- "When tracking_system is 'jira': use Atlassian MCP tools for all artefact output instead of writing local files"
|
||||
- "Read artefact mapping from {project-root}/_bmad/atlassian/artefact-mapping.yaml for output routing"
|
||||
- "Use {key_map_file} for Jira issue key and Confluence page ID lookups"
|
||||
- "Sprint Planning: use the Jira workflow override at {project-root}/_bmad/atlassian/workflow-overrides/4-implementation/sprint-planning/"
|
||||
- "Create Story: use the Jira workflow override at {project-root}/_bmad/atlassian/workflow-overrides/4-implementation/create-story/"
|
||||
- "When preparing stories: update the Jira Story description with enriched dev context via Update Issue, post dev notes as a comment via Add Comment"
|
||||
- "Create Jira Subtasks for each task/subtask in the story using Create Issue with issue_type Sub-task"
|
||||
- "Transition stories using the transition-jira-issue reusable task — always call Get Transitions first"
|
||||
- "Apply label '{agent_label_prefix}sm' to every Jira issue you create or modify"
|
||||
- "Before working on an issue: invoke lock-issue task with action 'lock'. On completion: invoke with action 'unlock'"
|
||||
- "If output_mode is 'dual': also write sprint-status.yaml and story files to local paths"
|
||||
|
||||
menu_overrides:
|
||||
- trigger: SP
|
||||
workflow: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/sprint-planning/workflow-jira.yaml"
|
||||
description: "[SP] Sprint Planning (Jira): Manage sprints and assign stories via Jira"
|
||||
- trigger: CS
|
||||
workflow: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/create-story/workflow-jira.yaml"
|
||||
description: "[CS] Create Story (Jira): Prepare a story with dev context, output to Jira"
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
# BMAD Artefact-to-Atlassian Mapping
|
||||
# Authoritative reference for how each BMAD artefact maps to Jira/Confluence.
|
||||
# Agents consult this file to determine which MCP tool to call for each output.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 1 — ANALYSIS (Analyst Agent / Mary)
|
||||
# ============================================================================
|
||||
|
||||
phase_1_analysis:
|
||||
|
||||
research_report:
|
||||
bmad_source: "{planning_artifacts}/research-*.md"
|
||||
destination: confluence
|
||||
mcp_tool: create_page
|
||||
parameters:
|
||||
space_key: "{confluence_space_key}"
|
||||
title: "[{jira_project_key}] Research: {research_type}"
|
||||
content: "{report_body_markdown}"
|
||||
parent_id: "{confluence_parent_page_id}"
|
||||
labels:
|
||||
- "{agent_label_prefix}analyst"
|
||||
- "bmad-research"
|
||||
notes: "One page per research type (market, domain, technical)"
|
||||
|
||||
product_brief:
|
||||
bmad_source: "{planning_artifacts}/product-brief.md"
|
||||
destination: confluence
|
||||
mcp_tool: create_page
|
||||
parameters:
|
||||
space_key: "{confluence_space_key}"
|
||||
title: "[{jira_project_key}] Product Brief"
|
||||
content: "{brief_body_markdown}"
|
||||
parent_id: "{confluence_parent_page_id}"
|
||||
labels:
|
||||
- "{agent_label_prefix}analyst"
|
||||
- "bmad-brief"
|
||||
notes: "Input document for PRD creation. Created once, updated if revised."
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 2 — PLANNING (PM Agent / John + UX Designer / Sally)
|
||||
# ============================================================================
|
||||
|
||||
phase_2_planning:
|
||||
|
||||
prd:
|
||||
bmad_source: "{planning_artifacts}/prd.md"
|
||||
destination: confluence
|
||||
mcp_tool: create_page
|
||||
parameters:
|
||||
space_key: "{confluence_space_key}"
|
||||
title: "[{jira_project_key}] PRD: {project_name}"
|
||||
content: "{prd_body_markdown}"
|
||||
parent_id: "{confluence_parent_page_id}"
|
||||
labels:
|
||||
- "{agent_label_prefix}pm"
|
||||
- "bmad-prd"
|
||||
cross_links:
|
||||
- type: remote_issue_link
|
||||
description: "Link from each Epic back to the PRD page"
|
||||
mcp_tool: create_remote_issue_link
|
||||
parameters:
|
||||
issue_key: "{epic_issue_key}"
|
||||
url: "{confluence_page_url}"
|
||||
title: "PRD: {project_name}"
|
||||
|
||||
epics:
|
||||
bmad_source: "{planning_artifacts}/epics.md"
|
||||
destination: jira
|
||||
description: "Each Epic heading becomes a Jira Epic issue"
|
||||
creation_flow:
|
||||
- step: 1
|
||||
action: "Parse epic headings from markdown"
|
||||
pattern: "## Epic {N}: {title}"
|
||||
- step: 2
|
||||
action: "Create Jira Epic"
|
||||
mcp_tool: create_issue
|
||||
parameters:
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Epic"
|
||||
summary: "Epic {N}: {title}"
|
||||
description: "{epic_goal_and_fr_coverage}"
|
||||
additional_fields:
|
||||
labels:
|
||||
- "{agent_label_prefix}pm"
|
||||
- "bmad-epic"
|
||||
- step: 3
|
||||
action: "Store epic key in .jira-key-map.yaml"
|
||||
key_map_entry: "epics.epic-{N}: {created_issue_key}"
|
||||
|
||||
stories:
|
||||
bmad_source: "{planning_artifacts}/epics.md"
|
||||
destination: jira
|
||||
description: "Each Story under an Epic becomes a Jira Story linked to the parent Epic"
|
||||
creation_flow:
|
||||
- step: 1
|
||||
action: "Parse story entries from epic section"
|
||||
pattern: "### Story {N}.{M}: {title}"
|
||||
- step: 2
|
||||
action: "Create Jira Story"
|
||||
mcp_tool: create_issue
|
||||
parameters:
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Story"
|
||||
summary: "Story {N}.{M}: {title}"
|
||||
description: |
|
||||
**User Story:**
|
||||
As a {user_type}, I want {capability}, so that {value_benefit}.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
{acceptance_criteria_given_when_then}
|
||||
additional_fields:
|
||||
labels:
|
||||
- "{agent_label_prefix}pm"
|
||||
- "bmad-story"
|
||||
- step: 3
|
||||
action: "Link Story to its Epic"
|
||||
mcp_tool: link_to_epic
|
||||
parameters:
|
||||
issue_key: "{story_issue_key}"
|
||||
epic_key: "{parent_epic_key}"
|
||||
- step: 4
|
||||
action: "Store story key in .jira-key-map.yaml"
|
||||
key_map_entry: "stories.{N}-{M}-{kebab_title}: {created_issue_key}"
|
||||
|
||||
ux_design:
|
||||
bmad_source: "{planning_artifacts}/ux-design.md"
|
||||
destination: confluence
|
||||
mcp_tool: create_page
|
||||
parameters:
|
||||
space_key: "{confluence_space_key}"
|
||||
title: "[{jira_project_key}] UX Design: {project_name}"
|
||||
content: "{ux_design_body_markdown}"
|
||||
parent_id: "{confluence_parent_page_id}"
|
||||
labels:
|
||||
- "{agent_label_prefix}ux-designer"
|
||||
- "bmad-ux"
|
||||
cross_links:
|
||||
- type: remote_issue_link
|
||||
description: "Link from each Epic back to the UX Design page"
|
||||
mcp_tool: create_remote_issue_link
|
||||
parameters:
|
||||
issue_key: "{epic_issue_key}"
|
||||
url: "{confluence_page_url}"
|
||||
title: "UX Design: {project_name}"
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 3 — SOLUTIONING (Architect Agent / Winston)
|
||||
# ============================================================================
|
||||
|
||||
phase_3_solutioning:
|
||||
|
||||
architecture_decision_doc:
|
||||
bmad_source: "{planning_artifacts}/architecture.md"
|
||||
destination: confluence
|
||||
mcp_tool: create_page
|
||||
parameters:
|
||||
space_key: "{confluence_space_key}"
|
||||
title: "[{jira_project_key}] Architecture: {project_name}"
|
||||
content: "{architecture_body_markdown}"
|
||||
parent_id: "{confluence_parent_page_id}"
|
||||
labels:
|
||||
- "{agent_label_prefix}architect"
|
||||
- "bmad-architecture"
|
||||
cross_links:
|
||||
- type: remote_issue_link
|
||||
description: "Link from relevant Epics back to Architecture page"
|
||||
mcp_tool: create_remote_issue_link
|
||||
parameters:
|
||||
issue_key: "{epic_issue_key}"
|
||||
url: "{confluence_page_url}"
|
||||
title: "Architecture Decision Document"
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 4 — IMPLEMENTATION (SM / Bob, Dev / Amelia, QA / Quinn)
|
||||
# ============================================================================
|
||||
|
||||
phase_4_implementation:
|
||||
|
||||
sprint:
|
||||
bmad_source: "{implementation_artifacts}/sprint-status.yaml"
|
||||
destination: jira
|
||||
description: "Sprint status tracked via Jira Sprints instead of local YAML"
|
||||
creation_flow:
|
||||
- step: 1
|
||||
action: "Find or create Jira sprint"
|
||||
mcp_tool: get_sprints_from_board
|
||||
parameters:
|
||||
board_id: "{jira_board_id}"
|
||||
state: "active"
|
||||
- step: 2
|
||||
action: "Create sprint if none active"
|
||||
mcp_tool: create_sprint
|
||||
parameters:
|
||||
board_id: "{jira_board_id}"
|
||||
name: "{project_name} Sprint {sprint_number}"
|
||||
start_date: "{sprint_start}"
|
||||
end_date: "{sprint_end}"
|
||||
- step: 3
|
||||
action: "Add stories to sprint"
|
||||
mcp_tool: add_issues_to_sprint
|
||||
parameters:
|
||||
sprint_id: "{active_sprint_id}"
|
||||
issue_keys: "{selected_story_keys}"
|
||||
|
||||
story_preparation:
|
||||
bmad_source: "{implementation_artifacts}/{story-key}.md"
|
||||
destination: jira
|
||||
description: "SM prepares story by enriching the Jira Story description with dev context"
|
||||
creation_flow:
|
||||
- step: 1
|
||||
action: "Look up Jira key from key map"
|
||||
lookup: "stories.{story-key}"
|
||||
- step: 2
|
||||
action: "Update story description with dev context"
|
||||
mcp_tool: update_issue
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
fields:
|
||||
description: "{enriched_story_description}"
|
||||
- step: 3
|
||||
action: "Add dev notes as comment"
|
||||
mcp_tool: add_comment
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
body: "{dev_notes_and_references}"
|
||||
- step: 4
|
||||
action: "Transition to Ready for Dev"
|
||||
mcp_tool: transition_issue
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
transition_id: "{status_transitions.story.backlog_to_ready_for_dev}"
|
||||
labels:
|
||||
- "{agent_label_prefix}sm"
|
||||
|
||||
story_tasks:
|
||||
bmad_source: "Tasks/subtasks within story file"
|
||||
destination: jira
|
||||
description: "Each task in the story becomes a Jira Subtask"
|
||||
creation_flow:
|
||||
- step: 1
|
||||
action: "Parse tasks from story content"
|
||||
- step: 2
|
||||
action: "Create subtask for each task"
|
||||
mcp_tool: create_issue
|
||||
parameters:
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Sub-task"
|
||||
summary: "{task_description}"
|
||||
description: "{task_details_and_ac_refs}"
|
||||
additional_fields:
|
||||
parent:
|
||||
key: "{story_jira_key}"
|
||||
labels:
|
||||
- "{agent_label_prefix}sm"
|
||||
- "bmad-task"
|
||||
|
||||
dev_story_execution:
|
||||
bmad_source: "Dev agent record in story file"
|
||||
destination: jira
|
||||
description: "Dev agent transitions stories and posts completion notes"
|
||||
execution_flow:
|
||||
- step: 1
|
||||
action: "Find next story to implement"
|
||||
mcp_tool: search_issues
|
||||
parameters:
|
||||
jql: "project = {jira_project_key} AND issuetype = Story AND status = 'Ready for Dev' ORDER BY rank ASC"
|
||||
fields: "summary,description"
|
||||
limit: 1
|
||||
- step: 2
|
||||
action: "Lock the story"
|
||||
invoke_task: "lock-issue"
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
action: "lock"
|
||||
- step: 3
|
||||
action: "Transition to In Progress"
|
||||
mcp_tool: transition_issue
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
transition_id: "{status_transitions.story.ready_for_dev_to_in_progress}"
|
||||
- step: 4
|
||||
action: "Post completion record as comment"
|
||||
mcp_tool: add_comment
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
body: |
|
||||
**Dev Agent Record**
|
||||
- Agent Model: {agent_model}
|
||||
- Files Changed: {file_list}
|
||||
- Completion Notes: {completion_notes}
|
||||
- step: 5
|
||||
action: "Transition to Review"
|
||||
mcp_tool: transition_issue
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
transition_id: "{status_transitions.story.in_progress_to_review}"
|
||||
- step: 6
|
||||
action: "Unlock the story"
|
||||
invoke_task: "lock-issue"
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
action: "unlock"
|
||||
|
||||
code_review:
|
||||
bmad_source: "Code review results"
|
||||
destination: jira
|
||||
description: "Code review findings posted as Jira comment on the Story"
|
||||
execution_flow:
|
||||
- step: 1
|
||||
action: "Post review findings"
|
||||
mcp_tool: add_comment
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
body: "{code_review_markdown}"
|
||||
- step: 2
|
||||
action: "Transition to Done (if review passes)"
|
||||
mcp_tool: transition_issue
|
||||
parameters:
|
||||
issue_key: "{story_jira_key}"
|
||||
transition_id: "{status_transitions.story.review_to_done}"
|
||||
labels:
|
||||
- "{agent_label_prefix}dev"
|
||||
- "bmad-reviewed"
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# BMAD Atlassian Key Map
|
||||
# Auto-generated and maintained by the Atlassian adapter.
|
||||
# Maps BMAD identifiers to Jira issue keys and Confluence page IDs.
|
||||
#
|
||||
# DO NOT EDIT MANUALLY — this file is updated by agent workflows.
|
||||
# If Jira issues are created outside BMAD, run the orchestrator's
|
||||
# state reader to refresh this map from Jira via JQL.
|
||||
|
||||
project_key: "{jira_project_key}"
|
||||
last_updated: "{date}"
|
||||
|
||||
# Confluence page IDs (returned by Create Page / Search Content)
|
||||
confluence_pages:
|
||||
# product_brief: "page-id"
|
||||
# research_market: "page-id"
|
||||
# research_domain: "page-id"
|
||||
# research_technical: "page-id"
|
||||
# prd: "page-id"
|
||||
# ux_design: "page-id"
|
||||
# architecture: "page-id"
|
||||
|
||||
# Jira Epic keys (returned by Create Issue)
|
||||
epics:
|
||||
# epic-1: "PROJ-10"
|
||||
# epic-2: "PROJ-11"
|
||||
|
||||
# Jira Story keys (returned by Create Issue + Link to Epic)
|
||||
stories:
|
||||
# 1-1-user-authentication: "PROJ-12"
|
||||
# 1-2-account-management: "PROJ-13"
|
||||
|
||||
# Jira Sprint IDs (returned by Create Sprint / Get Sprints from Board)
|
||||
sprints:
|
||||
# sprint-1: "42"
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
code: atlassian
|
||||
name: "Atlassian Jira/Confluence Adapter"
|
||||
description: "Routes BMAD artefacts to Jira and Confluence via the Atlassian MCP server"
|
||||
default_selected: false
|
||||
depends_on: bmm
|
||||
|
||||
# --- Jira Configuration ---
|
||||
|
||||
jira_project_key:
|
||||
prompt: "What is your Jira project key? (e.g., PROJ, MYAPP)"
|
||||
default: "PROJ"
|
||||
result: "{value}"
|
||||
|
||||
jira_board_id:
|
||||
prompt:
|
||||
- "What is your Jira Agile board ID?"
|
||||
- "Run the transition-discovery workflow to find this automatically."
|
||||
default: ""
|
||||
result: "{value}"
|
||||
|
||||
# --- Confluence Configuration ---
|
||||
|
||||
confluence_space_key:
|
||||
prompt: "What is your Confluence space key?"
|
||||
default: "{jira_project_key}"
|
||||
result: "{value}"
|
||||
|
||||
confluence_parent_page_id:
|
||||
prompt:
|
||||
- "What is the Confluence parent page ID under which BMAD artefacts will be created?"
|
||||
- "Leave blank to create pages at the space root."
|
||||
default: ""
|
||||
result: "{value}"
|
||||
|
||||
# --- Output Mode ---
|
||||
|
||||
output_mode:
|
||||
prompt:
|
||||
- "How should artefacts be written?"
|
||||
- "Dual mode writes to both Jira/Confluence AND local files. Jira-only skips local files."
|
||||
default: "dual"
|
||||
result: "{value}"
|
||||
single-select:
|
||||
- value: "dual"
|
||||
label: "Dual - Write to Jira/Confluence and local files"
|
||||
- value: "jira-only"
|
||||
label: "Jira Only - Write exclusively to Jira/Confluence"
|
||||
|
||||
# --- Status Transition Mapping ---
|
||||
# Maps BMAD abstract statuses to Jira transition IDs.
|
||||
# Users must populate these for their specific Jira workflow.
|
||||
# Run transition-discovery.md to auto-discover these values.
|
||||
|
||||
status_transitions:
|
||||
prompt: "Status transition mapping (run transition-discovery workflow to populate)"
|
||||
default: |
|
||||
epic:
|
||||
backlog_to_in_progress: ""
|
||||
in_progress_to_done: ""
|
||||
story:
|
||||
backlog_to_ready_for_dev: ""
|
||||
ready_for_dev_to_in_progress: ""
|
||||
in_progress_to_review: ""
|
||||
review_to_done: ""
|
||||
result: "{value}"
|
||||
|
||||
# --- Label Conventions ---
|
||||
|
||||
agent_label_prefix:
|
||||
prompt: "Prefix for labels applied by BMAD agents to Jira issues"
|
||||
default: "bmad-agent-"
|
||||
result: "{value}"
|
||||
|
||||
lock_label:
|
||||
prompt: "Label used to indicate an agent is actively working on an issue"
|
||||
default: "agent-active"
|
||||
result: "{value}"
|
||||
|
||||
# --- Tracking System Override ---
|
||||
# These override the bmm module defaults to route through Jira
|
||||
|
||||
tracking_system:
|
||||
result: "jira"
|
||||
|
||||
project_key:
|
||||
result: "{jira_project_key}"
|
||||
|
||||
story_location:
|
||||
result: "jira://{jira_project_key}"
|
||||
|
||||
# --- Key Map ---
|
||||
# Local file mapping BMAD identifiers to Jira issue keys and Confluence page IDs
|
||||
|
||||
key_map_file:
|
||||
result: "{project-root}/_bmad/atlassian/.jira-key-map.yaml"
|
||||
|
||||
# --- Directories to create during installation ---
|
||||
|
||||
directories:
|
||||
- "{project-root}/_bmad/atlassian"
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
# Agent Dispatch Rules — Automated Orchestrator
|
||||
|
||||
**Purpose:** Given the `ProjectState` from the Jira State Reader, determine which BMAD agent and workflow to invoke next. Implements the automated polling mode where the orchestrator drives the project forward based on Jira state.
|
||||
|
||||
---
|
||||
|
||||
## Dispatch Priority
|
||||
|
||||
Rules are evaluated in order. The first matching rule fires. If no rule matches, the project is either complete or blocked.
|
||||
|
||||
---
|
||||
|
||||
## Rule Definitions
|
||||
|
||||
<rules>
|
||||
|
||||
<rule n="1" name="Blocked — Agent Active">
|
||||
<condition>project_state.locked_issues is not empty (after stale lock clearing)</condition>
|
||||
<action>WAIT — another agent is currently working</action>
|
||||
<message>Agent is active on: {locked_issue_keys}. Waiting for completion.</message>
|
||||
<retry>Poll again in 30 seconds</retry>
|
||||
</rule>
|
||||
|
||||
<rule n="2" name="Phase 1 — Product Brief Needed">
|
||||
<condition>project_state.artefacts.product_brief.exists == false</condition>
|
||||
<agent>Analyst (Mary)</agent>
|
||||
<workflow>Create Brief [CB]</workflow>
|
||||
<context_to_load>None (user provides initial input)</context_to_load>
|
||||
<message>No product brief found. Starting with Analyst to create the product brief.</message>
|
||||
<notes>This is typically the entry point for a new project. The user should have an idea to discuss.</notes>
|
||||
</rule>
|
||||
|
||||
<rule n="3" name="Phase 2 — PRD Needed">
|
||||
<condition>
|
||||
project_state.artefacts.product_brief.exists == true
|
||||
AND project_state.artefacts.prd.exists == false
|
||||
</condition>
|
||||
<agent>PM (John)</agent>
|
||||
<workflow>Create PRD [CP]</workflow>
|
||||
<context_to_load>
|
||||
- Product Brief from Confluence (page_id from key map)
|
||||
- Any research reports from Confluence
|
||||
</context_to_load>
|
||||
<message>Product brief exists. Invoking PM to create the PRD.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="4" name="Phase 2 — UX Design Needed">
|
||||
<condition>
|
||||
project_state.artefacts.prd.exists == true
|
||||
AND project_state.artefacts.ux_design.exists == false
|
||||
</condition>
|
||||
<agent>UX Designer (Sally)</agent>
|
||||
<workflow>Create UX Design [CU]</workflow>
|
||||
<context_to_load>
|
||||
- PRD from Confluence
|
||||
- Product Brief from Confluence
|
||||
</context_to_load>
|
||||
<message>PRD exists. Invoking UX Designer for UX design.</message>
|
||||
<notes>UX Design is recommended but optional. If user wants to skip, proceed to epics.</notes>
|
||||
</rule>
|
||||
|
||||
<rule n="5" name="Phase 2/3 — Epics and Stories Needed">
|
||||
<condition>
|
||||
project_state.artefacts.prd.exists == true
|
||||
AND project_state.epics.total == 0
|
||||
</condition>
|
||||
<agent>PM (John)</agent>
|
||||
<workflow>Create Epics and Stories [CE] — with Jira output override</workflow>
|
||||
<context_to_load>
|
||||
- PRD from Confluence
|
||||
- UX Design from Confluence (if exists)
|
||||
</context_to_load>
|
||||
<message>PRD exists but no epics in Jira. Invoking PM to create epics and stories.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="6" name="Phase 3 — Architecture Needed">
|
||||
<condition>
|
||||
project_state.epics.total > 0
|
||||
AND project_state.artefacts.architecture.exists == false
|
||||
</condition>
|
||||
<agent>Architect (Winston)</agent>
|
||||
<workflow>Create Architecture [CA]</workflow>
|
||||
<context_to_load>
|
||||
- PRD from Confluence
|
||||
- Epic summaries from Jira (Search Issues: issuetype = Epic)
|
||||
- UX Design from Confluence (if exists)
|
||||
</context_to_load>
|
||||
<message>Epics exist but no architecture document. Invoking Architect.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="7" name="Phase 3 — Implementation Readiness Check">
|
||||
<condition>
|
||||
project_state.artefacts.architecture.exists == true
|
||||
AND project_state.stories.by_status.ready_for_dev == 0
|
||||
AND project_state.stories.by_status.in_progress == 0
|
||||
AND project_state.stories.by_status.backlog > 0
|
||||
AND project_state.active_sprint.exists == false
|
||||
</condition>
|
||||
<agent>PM (John) or Architect (Winston)</agent>
|
||||
<workflow>Implementation Readiness [IR]</workflow>
|
||||
<context_to_load>
|
||||
- PRD, UX Design, Architecture from Confluence
|
||||
- All Epics and Stories from Jira
|
||||
</context_to_load>
|
||||
<message>Architecture exists. Running implementation readiness check before sprint planning.</message>
|
||||
<notes>This is an optional quality gate. Can be skipped if user wants to proceed directly.</notes>
|
||||
</rule>
|
||||
|
||||
<rule n="8" name="Phase 4 — Sprint Planning Needed">
|
||||
<condition>
|
||||
project_state.artefacts.architecture.exists == true
|
||||
AND project_state.active_sprint.exists == false
|
||||
AND project_state.stories.by_status.backlog > 0
|
||||
</condition>
|
||||
<agent>SM (Bob)</agent>
|
||||
<workflow>Sprint Planning [SP] — Jira override</workflow>
|
||||
<context_to_load>
|
||||
- All Epics and Stories from Jira
|
||||
</context_to_load>
|
||||
<message>No active sprint. Invoking SM for sprint planning.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="9" name="Phase 4 — Story Preparation Needed">
|
||||
<condition>
|
||||
project_state.stories.by_status.backlog > 0
|
||||
AND project_state.stories.by_status.ready_for_dev == 0
|
||||
AND project_state.stories.by_status.in_progress == 0
|
||||
</condition>
|
||||
<agent>SM (Bob)</agent>
|
||||
<workflow>Create Story [CS] — Jira override</workflow>
|
||||
<context_to_load>
|
||||
- Next backlog story from Jira
|
||||
- Architecture from Confluence
|
||||
- Previous story learnings from Jira comments
|
||||
</context_to_load>
|
||||
<message>Stories in backlog need dev context. Invoking SM to prepare the next story.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="10" name="Phase 4 — Development">
|
||||
<condition>project_state.stories.by_status.ready_for_dev > 0</condition>
|
||||
<agent>Dev (Amelia)</agent>
|
||||
<workflow>Dev Story [DS] — Jira override</workflow>
|
||||
<context_to_load>
|
||||
- Next "Ready for Dev" story from Jira
|
||||
- Architecture from Confluence
|
||||
</context_to_load>
|
||||
<message>Stories ready for development. Invoking Dev agent.</message>
|
||||
</rule>
|
||||
|
||||
<rule n="11" name="Phase 4 — Code Review">
|
||||
<condition>project_state.stories.by_status.review > 0</condition>
|
||||
<agent>Dev (Amelia)</agent>
|
||||
<workflow>Code Review [CR] — Jira override</workflow>
|
||||
<context_to_load>
|
||||
- Story in "Review" status from Jira
|
||||
- Dev agent record from Jira comments
|
||||
</context_to_load>
|
||||
<message>Stories awaiting review. Invoking code review.</message>
|
||||
<notes>Recommended: use a fresh context window and different LLM for adversarial review</notes>
|
||||
</rule>
|
||||
|
||||
<rule n="12" name="Phase 4 — More Stories to Prepare">
|
||||
<condition>
|
||||
project_state.stories.by_status.backlog > 0
|
||||
AND (project_state.stories.by_status.in_progress > 0 OR project_state.stories.by_status.review > 0)
|
||||
</condition>
|
||||
<agent>SM (Bob)</agent>
|
||||
<workflow>Create Story [CS] — Jira override</workflow>
|
||||
<context_to_load>
|
||||
- Next backlog story
|
||||
- Previous story learnings
|
||||
</context_to_load>
|
||||
<message>Dev is busy. Preparing the next story in parallel.</message>
|
||||
<notes>Only if team capacity allows parallel work. Default: sequential story prep.</notes>
|
||||
</rule>
|
||||
|
||||
<rule n="13" name="Epic Retrospective">
|
||||
<condition>
|
||||
Any epic where all stories are "done" AND epic status is "in_progress"
|
||||
</condition>
|
||||
<agent>SM (Bob)</agent>
|
||||
<workflow>Epic Retrospective [ER]</workflow>
|
||||
<context_to_load>
|
||||
- All done stories in the epic from Jira
|
||||
- Dev agent records from Jira comments
|
||||
</context_to_load>
|
||||
<message>All stories complete for Epic {epic_key}. Running retrospective.</message>
|
||||
<post_action>Transition Epic to Done via transition-jira-issue task</post_action>
|
||||
</rule>
|
||||
|
||||
<rule n="14" name="Project Complete">
|
||||
<condition>
|
||||
project_state.epics.by_status.done == project_state.epics.total
|
||||
AND project_state.epics.total > 0
|
||||
</condition>
|
||||
<action>COMPLETE</action>
|
||||
<message>All epics are done. Project implementation is complete! 🎉</message>
|
||||
</rule>
|
||||
|
||||
<rule n="15" name="No Action — Fallback">
|
||||
<condition>No other rule matched</condition>
|
||||
<action>ASK_USER</action>
|
||||
<message>Unable to determine next action automatically. Current state: {state_summary}. What would you like to do?</message>
|
||||
</rule>
|
||||
|
||||
</rules>
|
||||
|
||||
---
|
||||
|
||||
## Orchestrator Loop
|
||||
|
||||
When running in automated mode, the orchestrator repeats:
|
||||
|
||||
```
|
||||
1. Run jira-state-reader to poll project state
|
||||
2. Evaluate dispatch rules against state
|
||||
3. If agent should be invoked:
|
||||
a. Load the specified context
|
||||
b. Invoke the agent with its workflow
|
||||
c. Wait for agent completion
|
||||
d. Return to step 1
|
||||
4. If WAIT: pause and re-poll after 30 seconds
|
||||
5. If COMPLETE or ASK_USER: stop and report to user
|
||||
```
|
||||
|
||||
The user can interrupt at any time to override the automated dispatch or switch to manual mode.
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
# Jira State Reader — Automated Project State Polling
|
||||
|
||||
**Purpose:** Read the current state of a BMAD project from Jira and Confluence via MCP tools. Returns a structured state model that the agent dispatch rules use to determine which agent to invoke next.
|
||||
|
||||
---
|
||||
|
||||
## When to Run
|
||||
|
||||
- At the start of every automated orchestrator cycle
|
||||
- When a user asks "what's next?" or "show project status"
|
||||
- After any agent completes its workflow (to determine the next action)
|
||||
|
||||
---
|
||||
|
||||
## State Model
|
||||
|
||||
The state reader builds a `ProjectState` object with the following structure:
|
||||
|
||||
```yaml
|
||||
project_state:
|
||||
project_key: "{jira_project_key}"
|
||||
timestamp: "{current_time}"
|
||||
|
||||
# Planning artefacts (from Confluence)
|
||||
artefacts:
|
||||
product_brief: { exists: bool, page_id: str }
|
||||
prd: { exists: bool, page_id: str }
|
||||
ux_design: { exists: bool, page_id: str }
|
||||
architecture: { exists: bool, page_id: str }
|
||||
|
||||
# Jira state
|
||||
epics:
|
||||
total: int
|
||||
by_status: { backlog: int, in_progress: int, done: int }
|
||||
details: [{ key: str, summary: str, status: str }]
|
||||
|
||||
stories:
|
||||
total: int
|
||||
by_status: { backlog: int, ready_for_dev: int, in_progress: int, review: int, done: int }
|
||||
|
||||
# Active work
|
||||
locked_issues: [{ key: str, summary: str, locked_since: str }]
|
||||
stale_locks: [{ key: str, summary: str, locked_since: str }]
|
||||
|
||||
# Sprint
|
||||
active_sprint: { exists: bool, name: str, sprint_id: str, story_count: int }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Polling Sequence
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Check Confluence for planning artefacts">
|
||||
<action>For each artefact type, check the key map file first:</action>
|
||||
<action>Read `{key_map_file}` and check `confluence_pages` section for existing page IDs</action>
|
||||
|
||||
<action>For any missing entries, search Confluence:</action>
|
||||
|
||||
```
|
||||
Search Content: query = "space = {confluence_space_key} AND label = bmad-brief" → product_brief
|
||||
Search Content: query = "space = {confluence_space_key} AND label = bmad-prd" → prd
|
||||
Search Content: query = "space = {confluence_space_key} AND label = bmad-ux" → ux_design
|
||||
Search Content: query = "space = {confluence_space_key} AND label = bmad-architecture" → architecture
|
||||
```
|
||||
|
||||
<action>Record existence and page IDs for each</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Query Jira for epics">
|
||||
<action>Call `Search Issues` with JQL:</action>
|
||||
|
||||
```
|
||||
project = {jira_project_key} AND issuetype = Epic ORDER BY rank ASC
|
||||
```
|
||||
|
||||
`fields: "summary,status,labels"` and `limit: 50`
|
||||
|
||||
<action>Count epics by status category</action>
|
||||
<action>Record each epic's key, summary, and status</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Query Jira for stories">
|
||||
<action>Call `Search Issues` with JQL:</action>
|
||||
|
||||
```
|
||||
project = {jira_project_key} AND issuetype = Story ORDER BY rank ASC
|
||||
```
|
||||
|
||||
`fields: "summary,status,labels"` and `limit: 50`
|
||||
|
||||
<action>Count stories by status. Map Jira status names to BMAD statuses:</action>
|
||||
|
||||
| Jira Status (common names) | BMAD Status |
|
||||
|---|---|
|
||||
| To Do, Backlog, Open | backlog |
|
||||
| Ready for Dev, Selected for Development | ready_for_dev |
|
||||
| In Progress, In Development | in_progress |
|
||||
| In Review, Code Review, Review | review |
|
||||
| Done, Closed, Resolved | done |
|
||||
|
||||
<action>If pagination is needed (more than 50 stories), make additional calls with `start_at`</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Check for locked issues">
|
||||
<action>Call `Search Issues` with JQL:</action>
|
||||
|
||||
```
|
||||
project = {jira_project_key} AND labels = "{lock_label}"
|
||||
```
|
||||
|
||||
`fields: "summary,labels,updated"`
|
||||
|
||||
<action>For each locked issue, check if it's stale (updated more than 1 hour ago)</action>
|
||||
<action>Record locked issues and flag stale locks</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Check active sprint">
|
||||
<action>If `{jira_board_id}` is configured:</action>
|
||||
<action>Call `Get Sprints from Board` with `board_id: "{jira_board_id}"` and `state: "active"`</action>
|
||||
<action>If active sprint found, call `Get Sprint Issues` with `sprint_id` and count stories</action>
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Clear stale locks (if any)">
|
||||
<action>For each stale lock found in step 4:</action>
|
||||
<action>Call `Get Issue` with `issue_key` and `fields: "labels"` to get current labels</action>
|
||||
<action>Build new labels array without `{lock_label}`</action>
|
||||
<action>Call `Update Issue` to remove the lock label</action>
|
||||
<action>Call `Add Comment`: "🔓 Stale lock cleared by orchestrator (locked for >1 hour with no activity)"</action>
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Sync key map">
|
||||
<action>Update `{key_map_file}` with any newly discovered Jira keys or Confluence page IDs that weren't previously recorded</action>
|
||||
<action>Update `last_updated` timestamp</action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Output
|
||||
|
||||
Returns the `ProjectState` object to the calling orchestrator or agent dispatch rules.
|
||||
|
||||
For human display, format as:
|
||||
|
||||
```
|
||||
📊 Project Status: {jira_project_key}
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Planning Artefacts:
|
||||
Product Brief: {✅ | ❌}
|
||||
PRD: {✅ | ❌}
|
||||
UX Design: {✅ | ❌}
|
||||
Architecture: {✅ | ❌}
|
||||
|
||||
Epics: {total} ({done} done, {in_progress} active, {backlog} backlog)
|
||||
Stories: {total} ({done} done, {review} review, {in_progress} active, {ready_for_dev} ready, {backlog} backlog)
|
||||
|
||||
Sprint: {sprint_name or "None active"}
|
||||
Locked Issues: {count} ({stale_count} stale — auto-cleared)
|
||||
```
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
# Lock/Unlock Jira Issue — Reusable Task
|
||||
|
||||
**Purpose:** Implement simple agent locking by adding or removing the `agent-active` label on a Jira issue. Prevents multiple agents from working on the same issue simultaneously.
|
||||
|
||||
---
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|---|---|---|
|
||||
| `issue_key` | Yes | Jira issue key (e.g., `PROJ-42`) |
|
||||
| `action` | Yes | `"lock"` or `"unlock"` |
|
||||
| `agent_name` | No | Name of the agent acquiring/releasing the lock (for comment) |
|
||||
|
||||
---
|
||||
|
||||
## Execution
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Read current labels">
|
||||
<action>Call `Get Issue` with `issue_key: "{issue_key}"` and `fields: "labels"`</action>
|
||||
<action>Record the current labels array</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Check lock state and act">
|
||||
|
||||
**If action is "lock":**
|
||||
<action>Check if `{lock_label}` is already in the labels array</action>
|
||||
- If already locked → STOP. Report: "Issue {issue_key} is already locked by another agent. Wait and retry, or check if the lock is stale."
|
||||
- If not locked → proceed to add the label
|
||||
|
||||
<action>Build new labels array: current labels + `"{lock_label}"`</action>
|
||||
<action>Call `Update Issue` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{issue_key}"
|
||||
fields: {}
|
||||
additional_fields:
|
||||
labels: ["{existing_labels}", "{lock_label}"]
|
||||
```
|
||||
|
||||
<action>If `agent_name` is provided, call `Add Comment` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{issue_key}"
|
||||
body: "🔒 Locked by BMAD agent: {agent_name}"
|
||||
```
|
||||
|
||||
**If action is "unlock":**
|
||||
<action>Build new labels array: current labels minus `"{lock_label}"`</action>
|
||||
<action>Call `Update Issue` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{issue_key}"
|
||||
fields: {}
|
||||
additional_fields:
|
||||
labels: ["{remaining_labels}"]
|
||||
```
|
||||
|
||||
<action>If `agent_name` is provided, call `Add Comment` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{issue_key}"
|
||||
body: "🔓 Unlocked by BMAD agent: {agent_name}"
|
||||
```
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Stale Lock Detection
|
||||
|
||||
A lock is considered stale if the issue has been locked for more than 1 hour without any agent activity (no comments or updates). The orchestrator's state reader checks for stale locks during polling and can force-unlock them.
|
||||
|
||||
To check for stale locks:
|
||||
1. Call `Search Issues` with JQL: `project = {jira_project_key} AND labels = "{lock_label}" AND updated < -1h`
|
||||
2. For any results, force-unlock by removing the label and adding a comment: "🔓 Stale lock cleared by orchestrator"
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
# Read Jira Context — Reusable Task
|
||||
|
||||
**Purpose:** Fetch relevant Jira issues and Confluence pages to build context for an agent. Returns only what the agent needs for its current task, keeping the context window narrow.
|
||||
|
||||
---
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|---|---|---|
|
||||
| `context_type` | Yes | Type of context needed (see context types below) |
|
||||
| `scope_key` | No | Specific epic key, story key, or identifier to scope the query |
|
||||
| `fields` | No | Jira fields to include (defaults vary by context type) |
|
||||
|
||||
---
|
||||
|
||||
## Context Types
|
||||
|
||||
### `project_overview`
|
||||
|
||||
**Used by:** Orchestrator, PM (initial PRD creation)
|
||||
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Epic ORDER BY rank ASC` and `fields: "summary,status,description"`</action>
|
||||
<action>Call `Search Content` with `query: "space = {confluence_space_key} AND label = bmad-prd"` to find PRD page</action>
|
||||
<action>Call `Search Content` with `query: "space = {confluence_space_key} AND label = bmad-architecture"` to find Architecture page</action>
|
||||
|
||||
**Returns:** List of epics with statuses, PRD page ID (if exists), Architecture page ID (if exists)
|
||||
|
||||
---
|
||||
|
||||
### `epic_detail`
|
||||
|
||||
**Used by:** SM (create-story), Architect (architecture decisions)
|
||||
|
||||
<action>Call `Get Issue` with `issue_key: "{scope_key}"` and `fields: "summary,description,status,labels"`</action>
|
||||
<action>Call `Search Issues` with JQL: `"Epic Link" = {scope_key} AND issuetype = Story ORDER BY rank ASC` and `fields: "summary,status,description"`</action>
|
||||
|
||||
**Returns:** Epic details + all stories under that epic with their statuses
|
||||
|
||||
---
|
||||
|
||||
### `story_detail`
|
||||
|
||||
**Used by:** Dev (dev-story), SM (create-story enrichment)
|
||||
|
||||
<action>Call `Get Issue` with `issue_key: "{scope_key}"` and `fields: "summary,description,status,labels,comment"` and `comment_limit: 5`</action>
|
||||
<action>Look up the parent Epic from the issue's epic link field</action>
|
||||
<action>If Architecture page exists in key map, call `Get Page` with `page_id: "{architecture_page_id}"` to fetch architecture context</action>
|
||||
|
||||
**Returns:** Full story details with recent comments, parent epic summary, architecture excerpts
|
||||
|
||||
---
|
||||
|
||||
### `sprint_status`
|
||||
|
||||
**Used by:** SM (sprint planning), Orchestrator
|
||||
|
||||
<action>Call `Get Sprints from Board` with `board_id: "{jira_board_id}"` and `state: "active"`</action>
|
||||
<action>If active sprint found, call `Get Sprint Issues` with `sprint_id: "{active_sprint_id}"` and `fields: "summary,status,assignee"`</action>
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Story AND sprint is EMPTY AND status != Done ORDER BY rank ASC` and `fields: "summary,status"` to find unplanned stories</action>
|
||||
|
||||
**Returns:** Active sprint issues with statuses, backlog stories not yet in a sprint
|
||||
|
||||
---
|
||||
|
||||
### `confluence_artefact`
|
||||
|
||||
**Used by:** Any agent needing a specific Confluence document
|
||||
|
||||
<action>Look up `{scope_key}` in `.jira-key-map.yaml` under `confluence_pages`</action>
|
||||
<action>If found, call `Get Page` with `page_id: "{page_id}"`</action>
|
||||
<action>If not found, call `Search Content` with `query: "space = {confluence_space_key} AND label = bmad-{scope_key}"`</action>
|
||||
|
||||
**Returns:** Page content in markdown format
|
||||
|
||||
---
|
||||
|
||||
### `previous_story_learnings`
|
||||
|
||||
**Used by:** SM (create-story, to incorporate learnings from previous stories)
|
||||
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Story AND status = Done ORDER BY updated DESC` and `limit: 3` and `fields: "summary,comment"`</action>
|
||||
<action>Extract completion notes from the most recent comments on each done story</action>
|
||||
|
||||
**Returns:** Summary of last 3 completed stories' dev agent records and completion notes
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
|
||||
The task returns a structured context block that the calling workflow injects into the agent's prompt:
|
||||
|
||||
```markdown
|
||||
## Jira Context for {agent_name}
|
||||
|
||||
### {context_section_1_title}
|
||||
{content}
|
||||
|
||||
### {context_section_2_title}
|
||||
{content}
|
||||
```
|
||||
|
||||
This replaces the file-system pattern of reading local markdown files. The agent receives the same information but sourced from Jira/Confluence.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Transition Jira Issue — Reusable Task
|
||||
|
||||
**Purpose:** Safely transition a Jira issue to a new status. Always verifies the transition is available before attempting it. Handles cases where the target status is already reached or the transition is not available.
|
||||
|
||||
---
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|---|---|---|
|
||||
| `issue_key` | Yes | Jira issue key (e.g., `PROJ-42`) |
|
||||
| `transition_id` | Yes | Target transition ID from `status_transitions` config |
|
||||
| `comment` | No | Optional comment to add during transition |
|
||||
| `fallback_status_name` | No | Target status name for fuzzy matching if transition_id fails |
|
||||
|
||||
---
|
||||
|
||||
## Execution
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Verify transition is available">
|
||||
<action>Call `Get Transitions` with `issue_key: "{issue_key}"`</action>
|
||||
<action>The response lists all currently available transitions with their IDs and target status names</action>
|
||||
|
||||
**Check for the configured transition:**
|
||||
- If `{transition_id}` appears in the available transitions → proceed to step 2
|
||||
- If `{transition_id}` is empty (no-op configured) → skip transition, report success
|
||||
- If `{transition_id}` is not in available transitions:
|
||||
- Check if the issue is already in the target state (transition already happened)
|
||||
- If already in target state → skip transition, report success
|
||||
- If `{fallback_status_name}` is provided, search available transitions for one whose target name matches → use that transition ID
|
||||
- If no match found → report warning: "Transition {transition_id} not available for {issue_key}. Available transitions: {list}. The Jira workflow may need updating or the status_transitions config may need adjustment."
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Execute the transition">
|
||||
<action>Call `Transition Issue` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{issue_key}"
|
||||
transition_id: "{verified_transition_id}"
|
||||
comment: "{comment}" # omit if empty
|
||||
```
|
||||
|
||||
<action>Verify the transition succeeded by checking the response</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Report result">
|
||||
<action>If transition succeeded: report the new status to the calling workflow</action>
|
||||
<action>If transition failed: report the error and suggest the user check their Jira workflow configuration</action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Scenario | Action |
|
||||
|---|---|
|
||||
| Transition ID not found | Search by `fallback_status_name`, then warn user |
|
||||
| Issue already in target state | Skip silently, return success |
|
||||
| Transition ID empty (no-op) | Skip silently, return success |
|
||||
| Permission denied | Report to user — they may need Jira project permissions |
|
||||
| Network error | Retry once after 2 seconds, then report failure |
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
# Write to Confluence — Reusable Task
|
||||
|
||||
**Purpose:** Create or update a Confluence page idempotently. Checks if the page already exists before creating a new one.
|
||||
|
||||
---
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|---|---|---|
|
||||
| `title` | Yes | Page title (should include project key prefix) |
|
||||
| `body_content` | Yes | Markdown content for the page body |
|
||||
| `space_key` | Yes | Confluence space key (from `{confluence_space_key}`) |
|
||||
| `parent_page_id` | No | Parent page ID (defaults to `{confluence_parent_page_id}`) |
|
||||
| `labels` | No | Array of labels to apply after creation |
|
||||
| `link_to_jira_issue` | No | Jira issue key to link this page from (via remote issue link) |
|
||||
| `key_map_id` | No | Identifier to store the page ID under in `.jira-key-map.yaml` |
|
||||
|
||||
---
|
||||
|
||||
## Execution
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Check if page already exists">
|
||||
<action>Call `Search Content` with `query: "title = \"{title}\""` and `spaces_filter: "{space_key}"`</action>
|
||||
<action>If a matching page is found, record its `page_id` and proceed to step 3 (update)</action>
|
||||
<action>If no match found, proceed to step 2 (create)</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Create new page">
|
||||
<action>Call `Create Page` with:</action>
|
||||
|
||||
```
|
||||
space_key: "{space_key}"
|
||||
title: "{title}"
|
||||
content: "{body_content}"
|
||||
parent_id: "{parent_page_id}" # omit if empty
|
||||
```
|
||||
|
||||
<action>Record the returned `page_id`</action>
|
||||
<action>Proceed to step 4</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Update existing page">
|
||||
<action>Call `Update Page` with:</action>
|
||||
|
||||
```
|
||||
page_id: "{existing_page_id}"
|
||||
title: "{title}"
|
||||
content: "{body_content}"
|
||||
version_comment: "Updated by BMAD agent"
|
||||
```
|
||||
|
||||
<action>Record the `page_id`</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Apply labels (if provided)">
|
||||
<action>For each label in `{labels}`:</action>
|
||||
<action>Call `Add Label` with `page_id: "{page_id}"` and `name: "{label}"`</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Link from Jira issue (if provided)">
|
||||
<action>If `link_to_jira_issue` is provided:</action>
|
||||
<action>Call `Create Remote Issue Link` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{link_to_jira_issue}"
|
||||
url: "{confluence_base_url}/pages/{page_id}"
|
||||
title: "{title}"
|
||||
summary: "BMAD artefact published to Confluence"
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Update key map (if key_map_id provided)">
|
||||
<action>If `key_map_id` is provided:</action>
|
||||
<action>Update `{key_map_file}` under `confluence_pages.{key_map_id}` with the `page_id`</action>
|
||||
<action>Update `last_updated` timestamp</action>
|
||||
|
||||
**If output_mode is "dual":**
|
||||
<action>Also write the content to the local file path as specified by the calling workflow</action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Return Value
|
||||
|
||||
Returns `page_id` (string) for use by the calling workflow for cross-linking.
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
# Transition Discovery — Jira Workflow Setup
|
||||
|
||||
**Purpose:** Discover the Jira transition IDs for your project's workflow and populate the `status_transitions` configuration. Run this once during initial setup and again if your Jira workflow changes.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- The Atlassian MCP server must be connected and authenticated
|
||||
- You need at least one existing issue in your Jira project (any type)
|
||||
- You need your Jira project key (e.g., `PROJ`)
|
||||
|
||||
---
|
||||
|
||||
## Discovery Workflow
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Discover the Jira Agile board">
|
||||
<action>Call `Get Agile Boards` with `project_key: "{jira_project_key}"`</action>
|
||||
<action>Record the `board_id` from the response — this is needed for sprint operations</action>
|
||||
<action>If multiple boards are returned, ask the user which one to use</action>
|
||||
|
||||
**Expected output:** Board ID (integer)
|
||||
|
||||
**Update config:** Set `jira_board_id` to the discovered board ID
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Find or create a sample Epic to discover Epic transitions">
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Epic ORDER BY created DESC` and `limit: 1`</action>
|
||||
<action>If no Epic exists, call `Create Issue` with `project_key: "{jira_project_key}"`, `issue_type: "Epic"`, `summary: "[BMAD Setup] Transition Discovery - Delete After Setup"` to create a temporary one</action>
|
||||
<action>Record the Epic issue key (e.g., `PROJ-1`)</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Discover Epic transitions">
|
||||
<action>Call `Get Transitions` with `issue_key: "{epic_issue_key}"`</action>
|
||||
<action>The response will list available transitions with their IDs and target status names</action>
|
||||
|
||||
**Map each transition to the BMAD status flow:**
|
||||
|
||||
```
|
||||
Epic flow: Backlog → In Progress → Done
|
||||
```
|
||||
|
||||
For each transition returned, identify:
|
||||
- Which transition moves the epic to an "In Progress" equivalent → `backlog_to_in_progress`
|
||||
- Which transition moves the epic to a "Done" equivalent → `in_progress_to_done`
|
||||
|
||||
**Note:** You may need to transition the epic to intermediate states to discover all transitions. Call `Transition Issue` to move it forward, then call `Get Transitions` again to see what's available from the new state.
|
||||
|
||||
<action>Record the transition IDs for the Epic status flow</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Find or create a sample Story to discover Story transitions">
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Story ORDER BY created DESC` and `limit: 1`</action>
|
||||
<action>If no Story exists, call `Create Issue` with `project_key: "{jira_project_key}"`, `issue_type: "Story"`, `summary: "[BMAD Setup] Transition Discovery - Delete After Setup"` to create a temporary one</action>
|
||||
<action>Record the Story issue key</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Discover Story transitions through the full workflow">
|
||||
<action>Call `Get Transitions` with `issue_key: "{story_issue_key}"` from the initial state</action>
|
||||
|
||||
**Map transitions to the BMAD Story status flow:**
|
||||
|
||||
```
|
||||
Story flow: Backlog → Ready for Dev → In Progress → Review → Done
|
||||
```
|
||||
|
||||
For each state in the flow:
|
||||
1. Record the available transitions
|
||||
2. Identify the transition that moves to the next BMAD-equivalent state
|
||||
3. Call `Transition Issue` to advance to that state
|
||||
4. Call `Get Transitions` again to discover the next set
|
||||
|
||||
Build the complete mapping:
|
||||
- `backlog_to_ready_for_dev`: transition ID from Backlog → Ready for Dev (or equivalent)
|
||||
- `ready_for_dev_to_in_progress`: transition ID from Ready for Dev → In Progress
|
||||
- `in_progress_to_review`: transition ID from In Progress → Review (or "In Review")
|
||||
- `review_to_done`: transition ID from Review → Done
|
||||
|
||||
**If your Jira workflow has fewer states** (e.g., To Do → In Progress → Done):
|
||||
- Map "To Do" to both `backlog` and `ready_for_dev`
|
||||
- Set `backlog_to_ready_for_dev` to empty (no-op, status is already equivalent)
|
||||
- The adapter will skip no-op transitions
|
||||
|
||||
**If your Jira workflow has more states** (e.g., additional QA or UAT states):
|
||||
- Map the closest equivalent states
|
||||
- Document the extra states and how they should be handled
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Clean up temporary issues">
|
||||
<action>If temporary issues were created in steps 2 and 4, call `Delete Issue` to remove them</action>
|
||||
<action>Only delete issues whose summary starts with "[BMAD Setup]"</action>
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Output the configuration">
|
||||
<action>Present the discovered configuration to the user:</action>
|
||||
|
||||
```yaml
|
||||
# Paste this into your _bmad/atlassian/config.yaml under status_transitions:
|
||||
|
||||
jira_board_id: {discovered_board_id}
|
||||
|
||||
status_transitions:
|
||||
epic:
|
||||
backlog_to_in_progress: "{epic_transition_id_1}"
|
||||
in_progress_to_done: "{epic_transition_id_2}"
|
||||
story:
|
||||
backlog_to_ready_for_dev: "{story_transition_id_1}"
|
||||
ready_for_dev_to_in_progress: "{story_transition_id_2}"
|
||||
in_progress_to_review: "{story_transition_id_3}"
|
||||
review_to_done: "{story_transition_id_4}"
|
||||
```
|
||||
|
||||
<action>Confirm with the user that the mapping looks correct</action>
|
||||
<action>If any transitions couldn't be discovered (workflow mismatch), flag them and suggest the user update their Jira workflow or adjust the mapping</action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"No transitions available"**: The issue may be in a terminal state or restricted by Jira workflow conditions. Check Jira workflow permissions.
|
||||
|
||||
**"Transition not found for target state"**: Your Jira workflow may use different status names. The adapter supports configurable mapping — use whatever transition IDs your workflow provides, even if the status names differ from BMAD's defaults.
|
||||
|
||||
**Multiple transitions to the same state**: Some workflows have conditional transitions (e.g., "Start Progress" vs "Resume"). Use the most general one. The adapter calls `Get Transitions` before every transition to verify availability.
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# Step 4: Output Epics and Stories to Jira
|
||||
|
||||
**This step replaces the default file-write output step.** The elicitation and analysis steps (1–3) remain unchanged — they build the epics/stories structure in the agent's working memory. This step writes that structure to Jira.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Steps 1–3 have completed: you have a fully formed epics/stories structure with:
|
||||
- Epic titles, goals, and FR coverage
|
||||
- Story titles, user stories (As a / I want / So that), and acceptance criteria (Given/When/Then)
|
||||
- Configuration loaded: `{jira_project_key}`, `{confluence_space_key}`, `{agent_label_prefix}`, `{key_map_file}`
|
||||
- PRD Confluence page exists (look up `confluence_pages.prd` in `{key_map_file}`)
|
||||
|
||||
---
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="4.1" goal="Create Jira Epics">
|
||||
<action>For each Epic in the structure, call `Create Issue`:</action>
|
||||
|
||||
```
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Epic"
|
||||
summary: "Epic {N}: {epic_title}"
|
||||
description: |
|
||||
## Goal
|
||||
{epic_goal}
|
||||
|
||||
## Requirements Coverage
|
||||
{fr_coverage_for_this_epic}
|
||||
additional_fields:
|
||||
labels: ["{agent_label_prefix}pm", "bmad-epic"]
|
||||
```
|
||||
|
||||
<action>Record each returned issue key (e.g., `PROJ-10`, `PROJ-11`)</action>
|
||||
<action>Update `{key_map_file}` under `epics`: `epic-{N}: "{issue_key}"`</action>
|
||||
</step>
|
||||
|
||||
<step n="4.2" goal="Create Jira Stories and link to Epics">
|
||||
<action>For each Story under each Epic, call `Create Issue`:</action>
|
||||
|
||||
```
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Story"
|
||||
summary: "Story {N}.{M}: {story_title}"
|
||||
description: |
|
||||
## User Story
|
||||
As a {user_type},
|
||||
I want {capability},
|
||||
So that {value_benefit}.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
{for_each_ac}
|
||||
**Given** {precondition}
|
||||
**When** {action}
|
||||
**Then** {expected_outcome}
|
||||
{end_for_each}
|
||||
additional_fields:
|
||||
labels: ["{agent_label_prefix}pm", "bmad-story"]
|
||||
```
|
||||
|
||||
<action>After each Story is created, call `Link to Epic`:</action>
|
||||
|
||||
```
|
||||
issue_key: "{story_issue_key}"
|
||||
epic_key: "{parent_epic_issue_key}"
|
||||
```
|
||||
|
||||
<action>Update `{key_map_file}` under `stories`: `{N}-{M}-{kebab_title}: "{story_issue_key}"`</action>
|
||||
|
||||
**Kebab-case conversion rules (same as sprint-planning):**
|
||||
- Replace period with dash: `1.1` → `1-1`
|
||||
- Convert title to kebab-case: `User Authentication` → `user-authentication`
|
||||
- Final key: `1-1-user-authentication`
|
||||
</step>
|
||||
|
||||
<step n="4.3" goal="Link PRD Confluence page to Epics">
|
||||
<action>Look up `confluence_pages.prd` in `{key_map_file}` to get the PRD page ID</action>
|
||||
<action>For each Epic created, call `Create Remote Issue Link`:</action>
|
||||
|
||||
```
|
||||
issue_key: "{epic_issue_key}"
|
||||
url: "{confluence_base_url}/pages/{prd_page_id}"
|
||||
title: "PRD: {project_name}"
|
||||
summary: "Product Requirements Document"
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="4.4" goal="Dual-write to local files (if configured)">
|
||||
<action>If `{output_mode}` is `"dual"`:</action>
|
||||
<action>Also write the complete epics/stories document to `{planning_artifacts}/epics.md` using the standard bmm template</action>
|
||||
<action>This ensures local file access remains available as a cache</action>
|
||||
</step>
|
||||
|
||||
<step n="4.5" goal="Report results">
|
||||
<action>Present a summary to the user:</action>
|
||||
|
||||
**Jira Output Complete**
|
||||
|
||||
| Type | Count | Project |
|
||||
|---|---|---|
|
||||
| Epics created | {epic_count} | {jira_project_key} |
|
||||
| Stories created | {story_count} | {jira_project_key} |
|
||||
| Epic-Story links | {link_count} | — |
|
||||
| PRD remote links | {epic_count} | — |
|
||||
|
||||
**Key Map Updated:** `{key_map_file}`
|
||||
|
||||
**Next Steps:**
|
||||
1. Review the created issues in Jira: `project = {jira_project_key} AND labels = bmad-epic`
|
||||
2. Run the Architect workflow to create the Architecture Decision Document
|
||||
3. Run Sprint Planning to organise stories into sprints
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
# Code Review — Jira Integration
|
||||
|
||||
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
|
||||
<critical>You MUST have already loaded and processed: the workflow-jira.yaml for this workflow</critical>
|
||||
|
||||
## Overview
|
||||
|
||||
Runs the standard bmm code review checklist and posts the results as a structured Jira comment on the story. If the review passes, transitions the story to Done. If it fails, adds findings and keeps the story in Review for fixes.
|
||||
|
||||
---
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Identify the story under review">
|
||||
<action>Call `Search Issues` with JQL:</action>
|
||||
|
||||
```
|
||||
project = {jira_project_key} AND issuetype = Story AND status = "Review" ORDER BY updated DESC
|
||||
```
|
||||
|
||||
`fields: "summary,description,labels"` and `limit: 5`
|
||||
|
||||
<action>If user specified a story key, use that instead</action>
|
||||
<action>Present candidates and wait for selection</action>
|
||||
<action>Call `Get Issue` with `issue_key: "{selected_issue_key}"` and `fields: "summary,description,comment"` and `comment_limit: 10` to load the dev agent record</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Lock the story and run code review">
|
||||
<action>Invoke `lock-issue` task with `issue_key: "{selected_issue_key}"`, `action: "lock"`, `agent_name: "code-review"`</action>
|
||||
|
||||
<action>Follow the standard bmm code review checklist at `{bmm_checklist}`</action>
|
||||
|
||||
Review the implementation across all quality facets:
|
||||
- Code correctness and completeness against acceptance criteria
|
||||
- Test coverage and quality
|
||||
- Architecture alignment
|
||||
- Security considerations
|
||||
- Performance implications
|
||||
- Code style and maintainability
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Post review results to Jira">
|
||||
<action>Call `Add Comment` with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
body: |
|
||||
## Code Review Results
|
||||
|
||||
**Reviewer:** BMAD Code Review Agent
|
||||
**Date:** {date}
|
||||
**Verdict:** {PASS | FAIL | PASS_WITH_NOTES}
|
||||
|
||||
### Summary
|
||||
{review_summary}
|
||||
|
||||
### Findings
|
||||
|
||||
{for_each_finding}
|
||||
#### {finding_severity}: {finding_title}
|
||||
- **Location:** {file_path}:{line_number}
|
||||
- **Description:** {finding_description}
|
||||
- **Recommendation:** {recommendation}
|
||||
{end_for_each}
|
||||
|
||||
### Acceptance Criteria Verification
|
||||
{for_each_ac}
|
||||
- [x] AC #{ac_number}: {ac_description} — {verification_status}
|
||||
{end_for_each}
|
||||
|
||||
### Test Coverage
|
||||
- Unit Tests: {unit_test_count}
|
||||
- Integration Tests: {integration_test_count}
|
||||
- Coverage: {coverage_percentage}
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Transition based on review outcome">
|
||||
|
||||
**If review PASSES:**
|
||||
<action>Invoke `transition-jira-issue` task:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
transition_id: "{status_transitions.story.review_to_done}"
|
||||
comment: "Code review passed. Story complete."
|
||||
fallback_status_name: "Done"
|
||||
```
|
||||
|
||||
<action>Call `Update Issue` to add review label:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
fields: {}
|
||||
additional_fields:
|
||||
labels: ["{existing_labels}", "bmad-reviewed", "review-passed"]
|
||||
```
|
||||
|
||||
<action>Check if all stories in the parent Epic are now Done:</action>
|
||||
<action>Call `Search Issues` with JQL: `"Epic Link" = {parent_epic_key} AND issuetype = Story AND status != Done`</action>
|
||||
<action>If no results (all done), invoke `transition-jira-issue` to transition the Epic to Done using `{status_transitions.epic.in_progress_to_done}`</action>
|
||||
|
||||
**If review FAILS:**
|
||||
<action>Call `Update Issue` to add review label:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
fields: {}
|
||||
additional_fields:
|
||||
labels: ["{existing_labels}", "bmad-reviewed", "review-failed"]
|
||||
```
|
||||
|
||||
<action>Do NOT transition — keep in Review status for the dev agent to address findings</action>
|
||||
<action>Report the specific findings that need to be addressed</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Unlock and report">
|
||||
<action>Invoke `lock-issue` task with `issue_key: "{selected_issue_key}"`, `action: "unlock"`, `agent_name: "code-review"`</action>
|
||||
|
||||
<action>Report to user:</action>
|
||||
|
||||
**Code Review: {verdict}**
|
||||
|
||||
- **Story:** {selected_issue_key} — {story_title}
|
||||
- **Findings:** {finding_count} ({critical_count} critical, {major_count} major, {minor_count} minor)
|
||||
- **AC Verified:** {verified_count}/{total_ac_count}
|
||||
|
||||
{if_passed}
|
||||
Story transitioned to **Done**. {if_epic_complete} Epic {parent_epic_key} also marked Done — all stories complete!{end_if}
|
||||
{end_if}
|
||||
|
||||
{if_failed}
|
||||
Story remains in **Review**. Address the findings and re-run [CR] Code Review.
|
||||
{end_if}
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
name: code-review-jira
|
||||
description: 'Run code review with results posted to Jira. Use when tracking_system is "jira".'
|
||||
author: "BMad"
|
||||
|
||||
# Critical variables from config
|
||||
config_source: "{project-root}/_bmad/atlassian/config.yaml"
|
||||
bmm_config: "{project-root}/_bmad/bmm/config.yaml"
|
||||
user_name: "{bmm_config}:user_name"
|
||||
communication_language: "{bmm_config}:communication_language"
|
||||
date: system-generated
|
||||
|
||||
# Atlassian-specific config
|
||||
jira_project_key: "{config_source}:jira_project_key"
|
||||
key_map_file: "{config_source}:key_map_file"
|
||||
status_transitions: "{config_source}:status_transitions"
|
||||
|
||||
# Workflow components
|
||||
installed_path: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/code-review"
|
||||
instructions: "{installed_path}/instructions-jira.md"
|
||||
bmm_checklist: "{project-root}/_bmad/bmm/workflows/4-implementation/code-review/checklist.md"
|
||||
|
||||
# Reusable tasks
|
||||
transition_task: "{project-root}/_bmad/atlassian/tasks/transition-jira-issue.md"
|
||||
lock_task: "{project-root}/_bmad/atlassian/tasks/lock-issue.md"
|
||||
|
||||
# Tracking system
|
||||
tracking_system: "jira"
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
# Create Story — Jira Output
|
||||
|
||||
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
|
||||
<critical>You MUST have already loaded and processed: the workflow-jira.yaml for this workflow</critical>
|
||||
|
||||
## Overview
|
||||
|
||||
Prepares a story with full development context. The analysis steps follow the standard bmm create-story checklist. The output step writes to Jira (updating the Story issue description and adding dev notes as a comment) and transitions the story to "Ready for Dev".
|
||||
|
||||
---
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Identify the story to prepare">
|
||||
<action>Ask the user which story to prepare, or present the next unprepared story from the backlog</action>
|
||||
<action>Invoke `read-jira-context` task with `context_type: "sprint_status"` to find stories in Backlog status</action>
|
||||
<action>Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Story AND status = Backlog ORDER BY rank ASC` and `limit: 5`</action>
|
||||
|
||||
<action>Present candidates to the user:</action>
|
||||
|
||||
| # | Key | Story | Epic |
|
||||
|---|---|---|---|
|
||||
| 1 | PROJ-12 | Story 1.1: User Authentication | Epic 1 |
|
||||
| 2 | PROJ-13 | Story 1.2: Account Management | Epic 1 |
|
||||
|
||||
<action>Wait for user selection</action>
|
||||
<action>Call `Get Issue` with the selected `issue_key` and `fields: "summary,description,labels"` to load full story details</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Gather context from Jira and Confluence">
|
||||
<action>Invoke `read-jira-context` task with `context_type: "story_detail"` and `scope_key: "{selected_issue_key}"` to fetch:</action>
|
||||
- Full story description and acceptance criteria from Jira
|
||||
- Parent Epic details
|
||||
- Architecture document from Confluence (if exists)
|
||||
|
||||
<action>Invoke `read-jira-context` task with `context_type: "previous_story_learnings"` to fetch:</action>
|
||||
- Completion notes from the last 3 done stories (for incorporating learnings)
|
||||
|
||||
<action>Read the project context file if it exists: `{project_context}`</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Analyse and prepare story content">
|
||||
<action>Follow the standard bmm create-story checklist at `{bmm_checklist}`:</action>
|
||||
|
||||
1. Validate the story has clear acceptance criteria
|
||||
2. Identify relevant architecture patterns and constraints
|
||||
3. Map tasks to the project's source tree
|
||||
4. Determine testing strategy and standards
|
||||
5. Check for dependencies on other stories
|
||||
6. Identify files and modules that will be touched
|
||||
|
||||
<action>Build the enriched story content using the bmm story template at `{bmm_template}` as the structure guide</action>
|
||||
|
||||
The enriched content includes:
|
||||
- **User Story** (from Jira issue description)
|
||||
- **Acceptance Criteria** (from Jira, validated for completeness)
|
||||
- **Tasks / Subtasks** (decomposed from AC, ordered for implementation)
|
||||
- **Dev Notes** (architecture patterns, source tree components, testing standards)
|
||||
- **Project Structure Notes** (alignment with project conventions)
|
||||
- **References** (source paths, relevant documentation sections)
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Write enriched story to Jira">
|
||||
<action>Call `Update Issue` to replace the story's description with the enriched content:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
fields:
|
||||
description: |
|
||||
{enriched_story_description_in_markdown}
|
||||
additional_fields:
|
||||
labels: ["{existing_labels}", "{agent_label_prefix}sm"]
|
||||
```
|
||||
|
||||
<action>Call `Add Comment` to post the dev notes separately (keeps them visible in the comment stream):</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
body: |
|
||||
## Dev Notes — Prepared by SM Agent
|
||||
|
||||
### Architecture Context
|
||||
{architecture_patterns_and_constraints}
|
||||
|
||||
### Source Tree Components
|
||||
{files_and_modules_to_touch}
|
||||
|
||||
### Testing Standards
|
||||
{testing_approach}
|
||||
|
||||
### References
|
||||
{cited_sources_with_paths}
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Create subtasks in Jira (if tasks were decomposed)">
|
||||
<action>For each Task/Subtask identified in step 3:</action>
|
||||
<action>Call `Create Issue`:</action>
|
||||
|
||||
```
|
||||
project_key: "{jira_project_key}"
|
||||
issue_type: "Sub-task"
|
||||
summary: "{task_description} (AC: #{ac_number})"
|
||||
description: "{task_details}"
|
||||
additional_fields:
|
||||
parent:
|
||||
key: "{selected_issue_key}"
|
||||
labels: ["{agent_label_prefix}sm", "bmad-task"]
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Transition story to Ready for Dev">
|
||||
<action>Invoke `transition-jira-issue` task with:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
transition_id: "{status_transitions.story.backlog_to_ready_for_dev}"
|
||||
comment: "Story prepared with full dev context by SM agent"
|
||||
fallback_status_name: "Ready for Dev"
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Dual-write and report">
|
||||
<action>If `{output_mode}` is `"dual"`:</action>
|
||||
<action>Also write the enriched story to local file: `{implementation_artifacts}/{story-key}.md`</action>
|
||||
|
||||
<action>Report to user:</action>
|
||||
|
||||
**Story Prepared: {story_title}**
|
||||
|
||||
- **Jira Issue:** {selected_issue_key}
|
||||
- **Status:** Ready for Dev
|
||||
- **Tasks Created:** {task_count} subtasks
|
||||
- **Dev Notes:** Posted as comment on {selected_issue_key}
|
||||
|
||||
**Next Steps:**
|
||||
1. Dev agent can pick up this story with [DS] Dev Story
|
||||
2. Or prepare the next story with [CS] Create Story
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
name: create-story-jira
|
||||
description: 'Prepare a story with full dev context, writing to Jira. Use when tracking_system is "jira".'
|
||||
author: "BMad"
|
||||
|
||||
# Critical variables from config
|
||||
config_source: "{project-root}/_bmad/atlassian/config.yaml"
|
||||
bmm_config: "{project-root}/_bmad/bmm/config.yaml"
|
||||
user_name: "{bmm_config}:user_name"
|
||||
communication_language: "{bmm_config}:communication_language"
|
||||
date: system-generated
|
||||
|
||||
# Atlassian-specific config
|
||||
jira_project_key: "{config_source}:jira_project_key"
|
||||
key_map_file: "{config_source}:key_map_file"
|
||||
status_transitions: "{config_source}:status_transitions"
|
||||
output_mode: "{config_source}:output_mode"
|
||||
|
||||
# BMM config for dual-write fallback
|
||||
implementation_artifacts: "{bmm_config}:implementation_artifacts"
|
||||
planning_artifacts: "{bmm_config}:planning_artifacts"
|
||||
|
||||
# Workflow components — reuses bmm's analysis steps, adds Jira output step
|
||||
installed_path: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/create-story"
|
||||
instructions: "{installed_path}/instructions-jira.md"
|
||||
bmm_checklist: "{project-root}/_bmad/bmm/workflows/4-implementation/create-story/checklist.md"
|
||||
bmm_template: "{project-root}/_bmad/bmm/workflows/4-implementation/create-story/template.md"
|
||||
|
||||
# Reusable tasks
|
||||
transition_task: "{project-root}/_bmad/atlassian/tasks/transition-jira-issue.md"
|
||||
context_task: "{project-root}/_bmad/atlassian/tasks/read-jira-context.md"
|
||||
|
||||
# Tracking system
|
||||
tracking_system: "jira"
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
# Dev Story — Jira-Tracked Implementation
|
||||
|
||||
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
|
||||
<critical>You MUST have already loaded and processed: the workflow-jira.yaml for this workflow</critical>
|
||||
|
||||
## Overview
|
||||
|
||||
Executes a story implementation with Jira as the tracking system. The dev agent finds the next story from Jira (instead of local files), locks it, transitions through statuses, and posts completion records as Jira comments.
|
||||
|
||||
---
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Find the next story to implement">
|
||||
<action>Call `Search Issues` with JQL:</action>
|
||||
|
||||
```
|
||||
project = {jira_project_key} AND issuetype = Story AND status = "Ready for Dev" ORDER BY rank ASC
|
||||
```
|
||||
|
||||
`fields: "summary,description,labels"` and `limit: 5`
|
||||
|
||||
<action>If user specified a story key, use that instead</action>
|
||||
<action>Present candidates to the user:</action>
|
||||
|
||||
| # | Key | Story | Status |
|
||||
|---|---|---|---|
|
||||
| 1 | PROJ-12 | Story 1.1: User Authentication | Ready for Dev |
|
||||
| 2 | PROJ-13 | Story 1.2: Account Management | Ready for Dev |
|
||||
|
||||
<action>Wait for user selection (or auto-select the first one if running in automated mode)</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Load story details and lock">
|
||||
<action>Call `Get Issue` with `issue_key: "{selected_issue_key}"` and `fields: "summary,description,labels,comment"` and `comment_limit: 10`</action>
|
||||
<action>Parse the story description to extract: user story, acceptance criteria, tasks/subtasks, dev notes</action>
|
||||
|
||||
<action>Invoke `lock-issue` task with `issue_key: "{selected_issue_key}"`, `action: "lock"`, `agent_name: "dev"`</action>
|
||||
|
||||
<action>Invoke `transition-jira-issue` task to move to In Progress:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
transition_id: "{status_transitions.story.ready_for_dev_to_in_progress}"
|
||||
comment: "Dev agent starting implementation"
|
||||
fallback_status_name: "In Progress"
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Load architecture and project context">
|
||||
<action>Invoke `read-jira-context` task with `context_type: "confluence_artefact"` and `scope_key: "architecture"` to fetch the Architecture document</action>
|
||||
<action>Read the project context file if it exists: `**/project-context.md`</action>
|
||||
<action>These provide the technical constraints and patterns the dev agent must follow</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Execute implementation">
|
||||
<action>Follow the standard bmm dev-story checklist at `{bmm_checklist}`:</action>
|
||||
|
||||
**Critical Dev Agent Rules (unchanged from bmm):**
|
||||
- READ the entire story BEFORE any implementation
|
||||
- Execute tasks/subtasks IN ORDER as written
|
||||
- Mark task complete ONLY when both implementation AND tests pass
|
||||
- Run full test suite after each task
|
||||
- Execute continuously without pausing until all tasks complete
|
||||
- NEVER lie about tests being written or passing
|
||||
|
||||
<action>For each task/subtask in the story:</action>
|
||||
1. Implement the code changes
|
||||
2. Write comprehensive unit tests
|
||||
3. Run the full test suite — all tests must pass
|
||||
4. Mark the task as complete
|
||||
|
||||
<action>If dual-write mode: update the local story file at `{implementation_artifacts}/{story-key}.md` with task completion markers `[x]`</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Post completion record to Jira">
|
||||
<action>Call `Add Comment` on the story issue:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
body: |
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model
|
||||
{agent_model_name_version}
|
||||
|
||||
### Implementation Summary
|
||||
{what_was_implemented}
|
||||
|
||||
### Tests Created
|
||||
{list_of_test_files_and_what_they_cover}
|
||||
|
||||
### Decisions Made
|
||||
{any_implementation_decisions_or_deviations}
|
||||
|
||||
### Files Changed
|
||||
{complete_list_of_changed_files}
|
||||
|
||||
### All Tests Passing
|
||||
✅ Full test suite passes ({test_count} tests)
|
||||
```
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Update subtask statuses">
|
||||
<action>For each subtask under this story in Jira:</action>
|
||||
<action>Call `Search Issues` with JQL: `parent = {selected_issue_key} AND issuetype = Sub-task`</action>
|
||||
<action>For each subtask, invoke `transition-jira-issue` to mark as Done</action>
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Transition to Review and unlock">
|
||||
<action>Invoke `transition-jira-issue` task:</action>
|
||||
|
||||
```
|
||||
issue_key: "{selected_issue_key}"
|
||||
transition_id: "{status_transitions.story.in_progress_to_review}"
|
||||
comment: "Implementation complete. Ready for code review."
|
||||
fallback_status_name: "Review"
|
||||
```
|
||||
|
||||
<action>Invoke `lock-issue` task with `issue_key: "{selected_issue_key}"`, `action: "unlock"`, `agent_name: "dev"`</action>
|
||||
|
||||
<action>Report to user:</action>
|
||||
|
||||
**Story Complete: {story_title}**
|
||||
|
||||
- **Jira Issue:** {selected_issue_key}
|
||||
- **Status:** Review
|
||||
- **Files Changed:** {file_count}
|
||||
- **Tests:** {test_count} passing
|
||||
|
||||
**Next Steps:**
|
||||
1. Run Code Review [CR] for adversarial review (recommended: fresh context, different LLM)
|
||||
2. Or pick up the next story with [DS] Dev Story
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
name: dev-story-jira
|
||||
description: 'Execute a story implementation with Jira status tracking. Use when tracking_system is "jira".'
|
||||
author: "BMad"
|
||||
|
||||
# Critical variables from config
|
||||
config_source: "{project-root}/_bmad/atlassian/config.yaml"
|
||||
bmm_config: "{project-root}/_bmad/bmm/config.yaml"
|
||||
user_name: "{bmm_config}:user_name"
|
||||
communication_language: "{bmm_config}:communication_language"
|
||||
date: system-generated
|
||||
|
||||
# Atlassian-specific config
|
||||
jira_project_key: "{config_source}:jira_project_key"
|
||||
key_map_file: "{config_source}:key_map_file"
|
||||
status_transitions: "{config_source}:status_transitions"
|
||||
output_mode: "{config_source}:output_mode"
|
||||
|
||||
# BMM config
|
||||
implementation_artifacts: "{bmm_config}:implementation_artifacts"
|
||||
|
||||
# Workflow components
|
||||
installed_path: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/dev-story"
|
||||
instructions: "{installed_path}/instructions-jira.md"
|
||||
bmm_checklist: "{project-root}/_bmad/bmm/workflows/4-implementation/dev-story/checklist.md"
|
||||
|
||||
# Reusable tasks
|
||||
transition_task: "{project-root}/_bmad/atlassian/tasks/transition-jira-issue.md"
|
||||
lock_task: "{project-root}/_bmad/atlassian/tasks/lock-issue.md"
|
||||
context_task: "{project-root}/_bmad/atlassian/tasks/read-jira-context.md"
|
||||
|
||||
# Tracking system
|
||||
tracking_system: "jira"
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
# Sprint Planning — Jira Sprint Management
|
||||
|
||||
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
|
||||
<critical>You MUST have already loaded and processed: the workflow-jira.yaml for this workflow</critical>
|
||||
|
||||
## Overview
|
||||
|
||||
This workflow replaces the file-based sprint-status.yaml generation with Jira Sprint operations. It discovers stories from Jira, creates/manages sprints, and assigns stories to sprints.
|
||||
|
||||
---
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Read current Jira project state">
|
||||
<action>Communicate in {communication_language} with {user_name}</action>
|
||||
<action>Invoke the `read-jira-context` task with `context_type: "sprint_status"`</action>
|
||||
|
||||
This will:
|
||||
1. Call `Get Sprints from Board` with `board_id: "{jira_board_id}"` and `state: "active"` to find current sprint
|
||||
2. If active sprint exists, call `Get Sprint Issues` to get issues in the sprint
|
||||
3. Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Story AND sprint is EMPTY AND status != Done ORDER BY rank ASC` to find unplanned stories
|
||||
4. Call `Search Issues` with JQL: `project = {jira_project_key} AND issuetype = Epic ORDER BY rank ASC` to get epic overview
|
||||
|
||||
<action>Build a complete inventory of all epics, stories, and their current states from Jira</action>
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Determine sprint action">
|
||||
<action>Present the current state to the user:</action>
|
||||
|
||||
**Current Sprint Status:**
|
||||
- Active Sprint: {sprint_name} (or "None")
|
||||
- Stories in Sprint: {count} ({done_count} done, {in_progress_count} in progress)
|
||||
- Backlog Stories: {backlog_count} (not in any sprint)
|
||||
|
||||
**Options:**
|
||||
1. **[C] Continue** - Add backlog stories to the current sprint
|
||||
2. **[N] New Sprint** - Create a new sprint and select stories
|
||||
3. **[R] Review Only** - Just show the status, don't modify anything
|
||||
|
||||
<action>Wait for user selection</action>
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Create new sprint (if selected)">
|
||||
<action>If user selected [N] or no active sprint exists:</action>
|
||||
<action>Ask user for sprint name (default: `"{project_name} Sprint {next_number}"`) and duration (default: 2 weeks)</action>
|
||||
<action>Call `Create Sprint` with:</action>
|
||||
|
||||
```
|
||||
board_id: "{jira_board_id}"
|
||||
name: "{sprint_name}"
|
||||
start_date: "{today_iso}"
|
||||
end_date: "{end_date_iso}"
|
||||
goal: "{sprint_goal}" # Ask user for optional sprint goal
|
||||
```
|
||||
|
||||
<action>Record the returned `sprint_id`</action>
|
||||
<action>Update `{key_map_file}` under `sprints`: `sprint-{N}: "{sprint_id}"`</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Select and assign stories to sprint">
|
||||
<action>Present the backlog stories to the user as a numbered list:</action>
|
||||
|
||||
| # | Key | Story | Epic | Status |
|
||||
|---|---|---|---|---|
|
||||
| 1 | PROJ-12 | Story 1.1: User Authentication | Epic 1 | Backlog |
|
||||
| 2 | PROJ-13 | Story 1.2: Account Management | Epic 1 | Backlog |
|
||||
| ... | ... | ... | ... | ... |
|
||||
|
||||
<action>Ask user to select stories by number (comma-separated) or "all" for all backlog stories</action>
|
||||
<action>Call `Add Issues to Sprint` with:</action>
|
||||
|
||||
```
|
||||
sprint_id: "{active_or_new_sprint_id}"
|
||||
issue_keys: "{selected_story_keys_comma_separated}"
|
||||
```
|
||||
|
||||
<action>For each story added, if it's the first story from its Epic being worked on:</action>
|
||||
<action>Invoke `transition-jira-issue` task to transition the Epic from Backlog to In Progress using `{status_transitions.epic.backlog_to_in_progress}`</action>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Generate status summary and dual-write">
|
||||
<action>Build the sprint status summary:</action>
|
||||
|
||||
**Sprint Planning Complete**
|
||||
|
||||
- **Sprint:** {sprint_name}
|
||||
- **Stories Added:** {added_count}
|
||||
- **Total in Sprint:** {total_count}
|
||||
- **Epics Active:** {active_epic_count}
|
||||
|
||||
**Sprint Board:** View in Jira at your project board
|
||||
|
||||
<action>If `{output_mode}` is `"dual"`, also write a `sprint-status.yaml` to `{default_output_file}` with the same status information, using the same format as the bmm sprint-status template but with Jira issue keys embedded:</action>
|
||||
|
||||
```yaml
|
||||
generated: {date}
|
||||
last_updated: {date}
|
||||
project: {project_name}
|
||||
project_key: {jira_project_key}
|
||||
tracking_system: jira
|
||||
story_location: jira://{jira_project_key}
|
||||
sprint: {sprint_name}
|
||||
sprint_id: {sprint_id}
|
||||
|
||||
development_status:
|
||||
epic-1: in-progress # PROJ-10
|
||||
1-1-user-authentication: ready-for-dev # PROJ-12
|
||||
1-2-account-management: backlog # PROJ-13
|
||||
epic-1-retrospective: optional
|
||||
```
|
||||
|
||||
**Next Steps:**
|
||||
1. Use SM's **Create Story** ([CS]) to prepare stories with dev context
|
||||
2. Stories will transition: Backlog → Ready for Dev → In Progress → Review → Done
|
||||
3. Re-run Sprint Planning to refresh status from Jira
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
---
|
||||
|
||||
## Status Flow Reference (Jira-mapped)
|
||||
|
||||
```
|
||||
Epic: Backlog → In Progress → Done
|
||||
(Transition IDs from status_transitions.epic)
|
||||
|
||||
Story: Backlog → Ready for Dev → In Progress → Review → Done
|
||||
(Transition IDs from status_transitions.story)
|
||||
```
|
||||
|
||||
All transitions go through the `transition-jira-issue` reusable task, which calls `Get Transitions` first to verify availability.
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
name: sprint-planning-jira
|
||||
description: 'Generate sprint planning using Jira Sprints. Use when tracking_system is "jira".'
|
||||
author: "BMad"
|
||||
|
||||
# Critical variables from config
|
||||
config_source: "{project-root}/_bmad/atlassian/config.yaml"
|
||||
bmm_config: "{project-root}/_bmad/bmm/config.yaml"
|
||||
user_name: "{bmm_config}:user_name"
|
||||
communication_language: "{bmm_config}:communication_language"
|
||||
date: system-generated
|
||||
|
||||
# Atlassian-specific config
|
||||
jira_project_key: "{config_source}:jira_project_key"
|
||||
jira_board_id: "{config_source}:jira_board_id"
|
||||
key_map_file: "{config_source}:key_map_file"
|
||||
status_transitions: "{config_source}:status_transitions"
|
||||
output_mode: "{config_source}:output_mode"
|
||||
|
||||
# BMM config for dual-write fallback
|
||||
implementation_artifacts: "{bmm_config}:implementation_artifacts"
|
||||
planning_artifacts: "{bmm_config}:planning_artifacts"
|
||||
|
||||
# Workflow components
|
||||
installed_path: "{project-root}/_bmad/atlassian/workflow-overrides/4-implementation/sprint-planning"
|
||||
instructions: "{installed_path}/instructions-jira.md"
|
||||
|
||||
# Tracking system
|
||||
tracking_system: "jira"
|
||||
project_key: "{jira_project_key}"
|
||||
story_location: "jira://{jira_project_key}"
|
||||
|
||||
# Reusable tasks
|
||||
transition_task: "{project-root}/_bmad/atlassian/tasks/transition-jira-issue.md"
|
||||
lock_task: "{project-root}/_bmad/atlassian/tasks/lock-issue.md"
|
||||
context_task: "{project-root}/_bmad/atlassian/tasks/read-jira-context.md"
|
||||
|
||||
# Dual-write fallback output
|
||||
default_output_file: "{implementation_artifacts}/sprint-status.yaml"
|
||||
Loading…
Reference in New Issue