BMAD-METHOD/src/modules/bmm/workflows/4-implementation/story-pipeline/batch-runner.sh

251 lines
11 KiB
Bash
Executable File

#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════════
# BMAD Story Pipeline - Batch Runner
# Single-session execution using step-file architecture
#
# Token Efficiency: ~60-70% savings compared to separate Claude calls
# ═══════════════════════════════════════════════════════════════════════════════
set -e
# ─────────────────────────────────────────────────────────────────────────────
# CONFIGURATION
# ─────────────────────────────────────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# Defaults
STORY_ID=""
EPIC_NUM=""
DRY_RUN=false
RESUME=false
VERBOSE=false
# Directories
LOG_DIR="$PROJECT_ROOT/logs/pipeline-batch"
WORKFLOW_PATH="_bmad/bmm/workflows/4-implementation/story-pipeline"
# ─────────────────────────────────────────────────────────────────────────────
# USAGE
# ─────────────────────────────────────────────────────────────────────────────
usage() {
cat << EOF
BMAD Story Pipeline - Batch Runner
Single-session execution with step-file architecture
Usage: $(basename "$0") --story-id <id> --epic-num <num> [OPTIONS]
Required:
--story-id <id> Story ID (e.g., '1-4')
--epic-num <num> Epic number (e.g., 1)
Options:
--resume Resume from last checkpoint
--dry-run Show what would be executed
--verbose Show detailed output
--help Show this help
Examples:
# Run pipeline for story 1-4
$(basename "$0") --story-id 1-4 --epic-num 1
# Resume failed pipeline
$(basename "$0") --story-id 1-4 --epic-num 1 --resume
Token Savings:
Traditional (6 calls): ~71K tokens
Step-file (1 session): ~25-35K tokens
Savings: 50-65%
EOF
exit 1
}
# ─────────────────────────────────────────────────────────────────────────────
# ARGUMENT PARSING
# ─────────────────────────────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
case $1 in
--story-id)
STORY_ID="$2"
shift 2
;;
--epic-num)
EPIC_NUM="$2"
shift 2
;;
--resume)
RESUME=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--verbose)
VERBOSE=true
shift
;;
--help)
usage
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Validate required arguments
if [[ -z "$STORY_ID" || -z "$EPIC_NUM" ]]; then
echo -e "${RED}Error: --story-id and --epic-num are required${NC}"
usage
fi
# ─────────────────────────────────────────────────────────────────────────────
# SETUP
# ─────────────────────────────────────────────────────────────────────────────
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/batch-$STORY_ID-$TIMESTAMP.log"
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${CYAN} BMAD Story Pipeline - Batch Mode${NC}"
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}Story:${NC} $STORY_ID"
echo -e "${BLUE}Epic:${NC} $EPIC_NUM"
echo -e "${BLUE}Mode:${NC} $([ "$RESUME" = true ] && echo 'Resume' || echo 'Fresh')"
echo -e "${BLUE}Log:${NC} $LOG_FILE"
echo ""
# ─────────────────────────────────────────────────────────────────────────────
# BUILD PROMPT
# ─────────────────────────────────────────────────────────────────────────────
if [[ "$RESUME" = true ]]; then
PROMPT=$(cat << EOF
Execute BMAD Story Pipeline in BATCH mode - RESUME from checkpoint.
WORKFLOW: $WORKFLOW_PATH/workflow.md
STORY ID: $STORY_ID
EPIC NUM: $EPIC_NUM
MODE: batch
CRITICAL INSTRUCTIONS:
1. Load and read fully: $WORKFLOW_PATH/workflow.md
2. This is RESUME mode - load state file first
3. Follow step-file architecture EXACTLY
4. Execute steps ONE AT A TIME
5. AUTO-PROCEED through all steps (no menus in batch mode)
6. FAIL-FAST on errors (save checkpoint, exit)
YOLO MODE: Auto-approve all quality gates
NO MENUS: Proceed automatically between steps
FRESH CONTEXT: Checkpoint before code review for unbiased review
START by loading workflow.md and then step-01b-resume.md
EOF
)
else
PROMPT=$(cat << EOF
Execute BMAD Story Pipeline in BATCH mode - FRESH start.
WORKFLOW: $WORKFLOW_PATH/workflow.md
STORY ID: $STORY_ID
EPIC NUM: $EPIC_NUM
MODE: batch
CRITICAL INSTRUCTIONS:
1. Load and read fully: $WORKFLOW_PATH/workflow.md
2. This is a FRESH run - initialize new state
3. Follow step-file architecture EXACTLY
4. Execute steps ONE AT A TIME (never load multiple)
5. AUTO-PROCEED through all steps (no menus in batch mode)
6. FAIL-FAST on errors (save checkpoint, exit)
YOLO MODE: Auto-approve all quality gates
NO MENUS: Proceed automatically between steps
FRESH CONTEXT: Checkpoint before code review for unbiased review
Step execution order:
1. step-01-init.md - Initialize, cache documents
2. step-02-create-story.md - Create story (SM role)
3. step-03-validate-story.md - Validate story (SM role)
4. step-04-atdd.md - Generate tests (TEA role)
5. step-05-implement.md - Implement (DEV role)
6. step-06-code-review.md - Review (DEV role, adversarial)
7. step-07-complete.md - Complete (SM role)
8. step-08-summary.md - Generate audit
START by loading workflow.md and then step-01-init.md
EOF
)
fi
# ─────────────────────────────────────────────────────────────────────────────
# EXECUTE
# ─────────────────────────────────────────────────────────────────────────────
if [[ "$DRY_RUN" = true ]]; then
echo -e "${YELLOW}[DRY-RUN] Would execute single Claude session with:${NC}"
echo ""
echo "$PROMPT"
echo ""
echo -e "${YELLOW}[DRY-RUN] Allowed tools: *, MCP extensions${NC}"
exit 0
fi
echo -e "${GREEN}Starting single-session pipeline execution...${NC}"
echo -e "${YELLOW}This replaces 6 separate Claude calls with 1 session${NC}"
echo ""
cd "$PROJECT_ROOT/src"
# Single Claude session executing all steps
claude -p "$PROMPT" \
--dangerously-skip-permissions \
--allowedTools "*,mcp__exa__web_search_exa,mcp__exa__get_code_context_exa,mcp__exa__crawling_exa,mcp__supabase__list_tables,mcp__supabase__execute_sql,mcp__supabase__apply_migration,mcp__supabase__list_migrations,mcp__supabase__generate_typescript_types,mcp__supabase__get_logs,mcp__supabase__get_advisors" \
2>&1 | tee "$LOG_FILE"
# ─────────────────────────────────────────────────────────────────────────────
# COMPLETION CHECK
# ─────────────────────────────────────────────────────────────────────────────
echo ""
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
# Check for success indicators in log
if grep -qi "Pipeline complete\|Story.*is ready\|step-08-summary.*completed" "$LOG_FILE"; then
echo -e "${GREEN}✅ Pipeline completed successfully${NC}"
# Extract metrics if available
if grep -qi "Token Efficiency" "$LOG_FILE"; then
echo ""
echo -e "${CYAN}Token Efficiency:${NC}"
grep -A5 "Token Efficiency" "$LOG_FILE" | head -6
fi
else
echo -e "${YELLOW}⚠️ Pipeline may have completed with issues${NC}"
echo -e "${YELLOW} Check log: $LOG_FILE${NC}"
# Check for specific failure indicators
if grep -qi "permission\|can't write\|access denied" "$LOG_FILE"; then
echo -e "${RED} Found permission errors in log${NC}"
fi
if grep -qi "HALT\|FAIL\|ERROR" "$LOG_FILE"; then
echo -e "${RED} Found error indicators in log${NC}"
fi
fi
echo ""
echo -e "${BLUE}Log file:${NC} $LOG_FILE"
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"