# show-sprint-board ## Purpose Display the current sprint's Kanban board showing all stories and their states in a clear, visual format with enhanced performance and reliability. ## Task Execution ### Step 0: Initialize Environment Source the shared library for compatibility and utilities: ```bash # Source shared library if [ -f ".bmad-core/utils/bmad-lib.sh" ]; then source .bmad-core/utils/bmad-lib.sh elif [ -f "BMAD-METHOD/bmad-core/utils/bmad-lib.sh" ]; then source BMAD-METHOD/bmad-core/utils/bmad-lib.sh else echo "Warning: bmad-lib.sh not found, using fallback mode" fi # Validate project if ! validate_bmad_project 2>/dev/null; then echo "πŸ“‹ SPRINT BOARD - No Active Project" echo "═══════════════════════════════════════" echo "" echo "⚠️ NO BMAD PROJECT INITIALIZED" echo "" echo "To get started:" echo "1. Initialize a BMAD project in your workspace" echo "2. Create planning documents" echo "3. Use *draft to create stories" exit 0 fi ``` ### Step 1: Gather Project Context Identify project name and structure: ```bash # Get project name from brief or directory project_name="Project" if [ -f ".bmad/documents/project-brief.md" ]; then project_name=$(grep "^#" .bmad/documents/project-brief.md | head -1 | sed 's/^#\+ *//' | cut -d'-' -f1 | xargs) fi # Validate story files exist story_count=$(find .bmad/stories -name "*.yaml" 2>/dev/null | wc -l) if [ "$story_count" -eq 0 ]; then echo "πŸ“‹ SPRINT BOARD - $project_name" echo "═══════════════════════════════════════" echo "" echo "No stories created yet. Use *draft to create first story" exit 0 fi ``` ### Step 2: Analyze Document Status Check planning documents with proper validation: ```bash # Check document status with enhanced detection check_document_status() { local doc_name="$1" local doc_file="" # Check multiple possible locations and formats for ext in md yaml yml; do if [ -f ".bmad/documents/${doc_name}.${ext}" ]; then doc_file=".bmad/documents/${doc_name}.${ext}" break fi done if [ -n "$doc_file" ]; then # Extract status if present in YAML header or content local doc_status=$(grep -i "^status:" "$doc_file" 2>/dev/null | head -1 | cut -d: -f2- | xargs) if [ -n "$doc_status" ]; then echo "βœ“ $(echo $doc_name | tr '-' ' ' | sed 's/\b\(.\)/\u\1/g') ($doc_status)" else echo "βœ“ $(echo $doc_name | tr '-' ' ' | sed 's/\b\(.\)/\u\1/g')" fi else echo "β—‹ $(echo $doc_name | tr '-' ' ' | sed 's/\b\(.\)/\u\1/g')" fi } ``` ### Step 3: Count Stories by Status (Optimized) Use single-pass counting for performance: ```bash # Optimized single-pass story counting eval $(awk ' /^status: draft/ {draft++} /^status: ready/ {ready++} /^status: in_progress/ {in_progress++} /^status: code_review/ {code_review++} /^status: qa_testing/ {qa_testing++} /^status: completed|^status: done/ {completed++} /^blocked: true/ {blocked++} END { print "draft=" draft+0 print "ready=" ready+0 print "in_progress=" in_progress+0 print "code_review=" code_review+0 print "qa_testing=" qa_testing+0 print "completed=" completed+0 print "blocked_count=" blocked+0 } ' .bmad/stories/*.yaml 2>/dev/null) # Calculate totals total_wip=$((in_progress + code_review + qa_testing)) total_stories=$((draft + ready + in_progress + code_review + qa_testing + completed)) ``` ### Step 4: Gather Active Work Details Collect detailed information with proper escaping: ```bash # Get in-progress stories with safe parsing in_progress_details="" while IFS= read -r file; do [ -z "$file" ] && continue story_id=$(get_yaml_field "$file" "id" "Unknown") story_title=$(get_yaml_field "$file" "title" "No title") assignee=$(get_yaml_field "$file" "assignee" "Unassigned") days=$(get_yaml_field "$file" "days_in_progress" "0") is_blocked=$(get_yaml_field "$file" "blocked" "false") if [ "$is_blocked" = "true" ]; then emoji="🚫" else emoji="β€’" fi in_progress_details="${in_progress_details} ${emoji} ${story_id}: ${story_title} - ${assignee} (${days} days)\n" done < <(find .bmad/stories -name "*.yaml" -exec grep -l "status: in_progress" {} \; 2>/dev/null) # Get code review stories review_details="" while IFS= read -r file; do [ -z "$file" ] && continue story_id=$(get_yaml_field "$file" "id" "Unknown") story_title=$(get_yaml_field "$file" "title" "No title") pr_number=$(get_yaml_field "$file" "pr_number" "N/A") approvals=$(get_yaml_field "$file" "approvals" "0") review_details="${review_details} β€’ ${story_id}: ${story_title} - PR #${pr_number} (${approvals} approval)\n" done < <(find .bmad/stories -name "*.yaml" -exec grep -l "status: code_review" {} \; 2>/dev/null) # Get QA testing stories qa_details="" while IFS= read -r file; do [ -z "$file" ] && continue story_id=$(get_yaml_field "$file" "id" "Unknown") story_title=$(get_yaml_field "$file" "title" "No title") qa_assignee=$(get_yaml_field "$file" "qa_assignee" "Unassigned") progress=$(get_yaml_field "$file" "testing_progress" "0") qa_details="${qa_details} β€’ ${story_id}: ${story_title} - QA: ${qa_assignee} (${progress}% complete)\n" done < <(find .bmad/stories -name "*.yaml" -exec grep -l "status: qa_testing" {} \; 2>/dev/null) # Get blocked stories blocked_details="" while IFS= read -r file; do [ -z "$file" ] && continue story_id=$(get_yaml_field "$file" "id" "Unknown") blocker=$(get_yaml_field "$file" "blocker" "Unknown blocker") blocked_days=$(get_yaml_field "$file" "blocked_days" "0") blocked_details="${blocked_details} β€’ ${story_id}: ${blocker} (${blocked_days} days)\n" done < <(find .bmad/stories -name "*.yaml" -exec grep -l "blocked: true" {} \; 2>/dev/null) ``` ### Step 5: Calculate Sprint Health Metrics ```bash # Calculate health indicators aging_count=$(find .bmad/stories -name "*.yaml" -exec grep -l "days_in_progress: [3-9]" {} \; 2>/dev/null | wc -l) # WIP limit check wip_status="βœ…" wip_message="Within limits" if [ "$total_wip" -gt 8 ]; then wip_status="⚠️" wip_message="Over limit!" elif [ "$total_wip" -gt 6 ]; then wip_status="🟑" wip_message="Near limit" fi # Sprint velocity indicator velocity_status="🎯" if [ "$blocked_count" -gt 2 ]; then velocity_status="πŸ”΄" elif [ "$blocked_count" -gt 0 ] || [ "$aging_count" -gt 1 ]; then velocity_status="🟑" fi ``` ### Step 6: Display the Board Format and display with color support if available: ```bash # Display header echo "" echo "πŸ“‹ SPRINT BOARD - ${project_name}" echo "═══════════════════════════════════════" echo "" # Display document status echo "PLANNING DOCUMENTS:" echo -n " " check_document_status "project-brief" echo -n " " check_document_status "prd" echo -n " " check_document_status "architecture" echo -n " " check_document_status "ux-spec" echo "" # Display story pipeline echo "" echo "STORY PIPELINE:" echo "β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”" echo "β”‚ Backlog β”‚ Ready β”‚ In Progressβ”‚ Review β”‚ Testing β”‚ Done β”‚" echo "β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€" printf "β”‚ %-6sβ”‚ %-5sβ”‚ %-7sβ”‚ %-6sβ”‚ %-5sβ”‚ %-4sβ”‚\n" \ "$draft" "$ready" "$in_progress" "$code_review" "$qa_testing" "$completed" echo "β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”˜" # Display current sprint focus if [ "$total_wip" -gt 0 ]; then echo "" echo "CURRENT SPRINT FOCUS:" echo "━━━━━━━━━━━━━━━━━━━━" if [ "$in_progress" -gt 0 ] && [ -n "$in_progress_details" ]; then echo "πŸ”„ IN PROGRESS ($in_progress):" echo -e "$in_progress_details" fi if [ "$code_review" -gt 0 ] && [ -n "$review_details" ]; then echo "πŸ‘€ IN REVIEW ($code_review):" echo -e "$review_details" fi if [ "$qa_testing" -gt 0 ] && [ -n "$qa_details" ]; then echo "πŸ§ͺ IN TESTING ($qa_testing):" echo -e "$qa_details" fi if [ "$blocked_count" -gt 0 ] && [ -n "$blocked_details" ]; then echo "🚫 BLOCKED ($blocked_count):" echo -e "$blocked_details" fi fi # Display sprint health echo "" echo "SPRINT HEALTH:" echo "━━━━━━━━━━━━━" echo "β€’ Total WIP: ${total_wip} items (Max: 8) ${wip_status} ${wip_message}" if [ "$blocked_count" -gt 0 ]; then echo "β€’ Blocked: ${blocked_count} item(s) ⚠️" fi if [ "$aging_count" -gt 0 ]; then echo "β€’ Aging items: ${aging_count} (>3 days) ⚠️" fi echo "β€’ Sprint velocity: ${velocity_status} $([ "$velocity_status" = "🎯" ] && echo "On track" || echo "At risk")" # Display key observations echo "" echo "KEY OBSERVATIONS:" if [ "$in_progress" -gt 4 ]; then echo "β€’ Development has high WIP ($in_progress items) - monitor for context switching" fi if [ "$blocked_count" -gt 0 ]; then echo "β€’ ${blocked_count} blocker(s) need escalation" fi if [ "$aging_count" -gt 0 ]; then echo "β€’ ${aging_count} story(ies) aging - may need assistance" fi if [ "$ready" -gt 3 ]; then echo "β€’ ${ready} stories ready to start - consider assigning" fi ``` ## Success Criteria - Board displays within 1 second (with caching) - All stories accurately counted - Shell compatibility across bash/zsh/sh - Graceful error handling - Clear, readable output ## Error Handling - Project validation with helpful messages - Safe YAML parsing with defaults - Continue with partial data on errors - No shell-specific failures ## Performance Optimizations - Single-pass AWK for counting - Process substitution instead of subshells - Optional caching for large projects - Efficient file operations ## Notes - Uses bmad-lib.sh for shared utilities - Compatible with all major shells - Supports color output when available - Maintains read-only operation