feat(bmvcs): add VCS adaptation examples
Add practical examples demonstrating VCS-agnostic adaptation: - vcs-adaptation-examples.md: 6 real-world scenarios (GitHub Flow, GitFlow, No VCS, SVN, Trunk-Based, Multi-VCS) - vcs-detection-implementation.py: Reference implementation of Git workflow auto-detection with confidence scoring - examples/README.md: Guide to using examples and integration Examples demonstrate "Detection as a HINT, not a DECISION" principle with evidence-based suggestions and user confirmation. Part 4/5 of BMVCS migration (#661) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bccfe9d651
commit
29d4dc030c
|
|
@ -0,0 +1,79 @@
|
|||
# BMVCS Examples
|
||||
|
||||
Practical examples demonstrating VCS-agnostic adaptation in BMAD.
|
||||
|
||||
## Files in This Directory
|
||||
|
||||
### [vcs-adaptation-examples.md](./vcs-adaptation-examples.md)
|
||||
|
||||
**Real-world scenarios** showing how BMAD adapts to different VCS workflows:
|
||||
|
||||
- **Startup with GitHub Flow**: Fast-paced web development
|
||||
- **Enterprise with GitFlow**: Structured releases with versions
|
||||
- **No Version Control**: One-time scripts and prototypes
|
||||
- **Custom SVN Workflow**: Legacy system adaptation
|
||||
- **Trunk-Based with Feature Flags**: Continuous deployment
|
||||
- **Complex Multi-VCS Setup**: Mixed systems in one organization
|
||||
|
||||
Each example shows discovery dialogue, BMAD adaptations, and generated artifacts.
|
||||
|
||||
### [vcs-detection-implementation.py](./vcs-detection-implementation.py)
|
||||
|
||||
**Reference implementation** of Git workflow auto-detection:
|
||||
|
||||
- Analyzes repository history to detect workflow patterns
|
||||
- Calculates confidence scores for GitFlow, GitHub Flow, and Trunk-Based
|
||||
- Follows "Detection as a HINT, not a DECISION" principle
|
||||
- Interactive confirmation with evidence presentation
|
||||
- Handles edge cases (migration, unclear patterns, fresh repos)
|
||||
|
||||
**Note**: This is an example implementation in Python. The actual BMAD implementation may use JavaScript/TypeScript. This demonstrates the detection logic that can be adapted to any language.
|
||||
|
||||
## Usage
|
||||
|
||||
### Running the Detector Example
|
||||
|
||||
```bash
|
||||
cd /path/to/your/git/repo
|
||||
python /path/to/vcs-detection-implementation.py
|
||||
```
|
||||
|
||||
The script will:
|
||||
|
||||
1. Analyze your Git history
|
||||
2. Score workflow indicators
|
||||
3. Present detection results with evidence
|
||||
4. Ask for confirmation (never auto-decides)
|
||||
5. Save configuration to `.bmad/vcs_config.json`
|
||||
|
||||
### Understanding the Examples
|
||||
|
||||
The adaptation examples show specific output for each workflow type. Use them as:
|
||||
|
||||
- **Reference**: See how BMAD should adapt terminology and structure
|
||||
- **Templates**: Copy patterns for custom integrations
|
||||
- **Documentation**: Explain VCS-agnostic behavior to users
|
||||
|
||||
## Key Principles Demonstrated
|
||||
|
||||
1. **Discovery First**: Always ask, never assume
|
||||
2. **Evidence-Based**: Show detection reasoning transparently
|
||||
3. **User Confirmation**: Detection is advisory, not prescriptive
|
||||
4. **Graceful Fallback**: Handle unclear cases with questions
|
||||
5. **Respect Existing**: Adapt to their workflow, don't change it
|
||||
|
||||
## Integration with BMAD Agents
|
||||
|
||||
These examples inform how all BMAD agents should adapt:
|
||||
|
||||
- **Architect**: Generate VCS-appropriate architecture docs
|
||||
- **PM**: Create requirements matching workflow style
|
||||
- **SM**: Size stories for the team's release cadence
|
||||
- **Dev**: Suggest VCS-appropriate code delivery
|
||||
- **QA**: Align test plans with workflow gates
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [VCS Agnostic Principles](../docs/VCS_AGNOSTIC_PRINCIPLES.md)
|
||||
- [Detection Confidence Scoring](../docs/VCS_DETECTION_CONFIDENCE.md)
|
||||
- [Discovery Task Implementation](../tasks/discover-vcs.md)
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
# VCS Adaptation Examples
|
||||
|
||||
## Real-World Scenarios: How BMAD Adapts
|
||||
|
||||
### Example 1: Startup with GitHub Flow
|
||||
|
||||
**Context:** 5-person team, web SaaS, deploys daily
|
||||
|
||||
**Discovery:**
|
||||
|
||||
```
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "Git with GitHub"
|
||||
BMAD: "Which Git workflow best describes your approach?"
|
||||
User: "GitHub Flow - simple feature branches"
|
||||
```
|
||||
|
||||
**BMAD Adapts:**
|
||||
|
||||
- Architect generates lightweight, PR-sized architecture updates
|
||||
- SM creates 1-3 day stories that map to single PRs
|
||||
- Dev suggests branch names like `feature/add-user-auth`
|
||||
- All docs optimized for quick review in PR comments
|
||||
|
||||
**Generated Architecture Snippet:**
|
||||
|
||||
```markdown
|
||||
## Payment Service Update
|
||||
|
||||
_PR: #234 - feature/add-stripe-integration_
|
||||
|
||||
### Changes in This PR
|
||||
|
||||
- New Stripe webhook handler
|
||||
- Updated payment models
|
||||
- Added retry logic
|
||||
|
||||
### Testing
|
||||
|
||||
- [ ] Unit tests for webhook handler
|
||||
- [ ] Integration test with Stripe test mode
|
||||
- [ ] Manual testing checklist in PR
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Enterprise with GitFlow
|
||||
|
||||
**Context:** 50-person team, banking software, quarterly releases
|
||||
|
||||
**Discovery:**
|
||||
|
||||
```
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "Git with corporate server"
|
||||
BMAD: "Which Git workflow?"
|
||||
User: "GitFlow - we have develop, release, and hotfix branches"
|
||||
```
|
||||
|
||||
**BMAD Adapts:**
|
||||
|
||||
- Architect creates version-oriented architecture docs
|
||||
- PM generates release-scoped PRDs
|
||||
- SM groups stories by release version
|
||||
- Dev follows strict branch naming
|
||||
|
||||
**Generated Architecture Snippet:**
|
||||
|
||||
```markdown
|
||||
## Release 2.4.0 Architecture
|
||||
|
||||
### Version Highlights
|
||||
|
||||
- New authentication system (breaking change)
|
||||
- Performance improvements
|
||||
- Database migration required
|
||||
|
||||
### Branch Status
|
||||
|
||||
- develop: v2.5.0 features in progress
|
||||
- release/2.4.0: Final testing
|
||||
- hotfix/2.3.1: Critical fix for production
|
||||
|
||||
### Migration Guide
|
||||
|
||||
From 2.3.x to 2.4.0:
|
||||
|
||||
1. Run migration script
|
||||
2. Update config files
|
||||
3. Restart services in order
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 3: No Version Control
|
||||
|
||||
**Context:** Data scientist, one-time analysis script
|
||||
|
||||
**Discovery:**
|
||||
|
||||
```
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "No version control needed - this is a one-time script"
|
||||
```
|
||||
|
||||
**BMAD Adapts:**
|
||||
|
||||
- All code in single, runnable package
|
||||
- Extensive inline documentation
|
||||
- No commit messages or branch references
|
||||
- Date-stamped delivery
|
||||
|
||||
**Generated Package:**
|
||||
|
||||
```
|
||||
customer_analysis_20240315/
|
||||
├── README.md # Complete instructions
|
||||
├── requirements.txt # All Python dependencies
|
||||
├── analysis.py # Full script with comments
|
||||
├── data/
|
||||
│ └── sample.csv # Sample data format
|
||||
└── output/
|
||||
└── results_template.xlsx
|
||||
```
|
||||
|
||||
**README Content:**
|
||||
|
||||
```markdown
|
||||
# Customer Analysis Script
|
||||
|
||||
Generated: 2024-03-15
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Install dependencies: pip install -r requirements.txt
|
||||
2. Place your data in data/input.csv
|
||||
3. Run: python analysis.py
|
||||
4. Results appear in output/
|
||||
|
||||
## No Version Control Required
|
||||
|
||||
This is a complete, self-contained package.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 4: Custom SVN Workflow
|
||||
|
||||
**Context:** Game studio using Subversion
|
||||
|
||||
**Discovery:**
|
||||
|
||||
```
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "Other version control system"
|
||||
BMAD: "Which system?"
|
||||
User: "Subversion (SVN)"
|
||||
```
|
||||
|
||||
**BMAD Adapts:**
|
||||
|
||||
- Uses "revision" instead of "commit"
|
||||
- References trunk/branches/tags structure
|
||||
- Revision numbers, not hashes
|
||||
- SVN-specific commands
|
||||
|
||||
**Generated Instructions:**
|
||||
|
||||
```markdown
|
||||
## Integration Steps
|
||||
|
||||
1. Update your working copy:
|
||||
svn update
|
||||
|
||||
2. Create feature branch:
|
||||
svn copy ^/trunk ^/branches/feature-player-inventory
|
||||
|
||||
3. After implementation:
|
||||
svn merge ^/branches/feature-player-inventory
|
||||
|
||||
4. Commit with revision message:
|
||||
svn commit -m "Add player inventory system (refs ticket #456)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 5: Trunk-Based with Feature Flags
|
||||
|
||||
**Context:** Netflix-style continuous deployment
|
||||
|
||||
**Discovery:**
|
||||
|
||||
```
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "Git with GitHub"
|
||||
BMAD: "Which Git workflow?"
|
||||
User: "Trunk-Based - we deploy continuously"
|
||||
```
|
||||
|
||||
**BMAD Adapts:**
|
||||
|
||||
- Everything behind feature flags
|
||||
- Tiny, hours-long tasks
|
||||
- Direct commits or same-day PRs
|
||||
- Progressive rollout plans
|
||||
|
||||
**Generated Story:**
|
||||
|
||||
````markdown
|
||||
## Story: Add Recommendation Engine
|
||||
|
||||
Size: 4 hours
|
||||
Flag: `recommendation-engine-v2`
|
||||
|
||||
### Implementation
|
||||
|
||||
```python
|
||||
if feature_flag.is_enabled("recommendation-engine-v2", user_id):
|
||||
return new_recommendation_engine(user_id)
|
||||
else:
|
||||
return legacy_recommendations(user_id)
|
||||
```
|
||||
````
|
||||
|
||||
### Rollout Plan
|
||||
|
||||
- Hour 1-2: Implement behind flag (0% users)
|
||||
- Hour 3: Deploy and enable for employees
|
||||
- Hour 4: Enable for 1% external users
|
||||
- Day 2: 10% if metrics good
|
||||
- Day 3: 50%
|
||||
- Day 5: 100% and schedule flag removal
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 6: Complex Multi-VCS Setup
|
||||
|
||||
**Context:** Enterprise with mixed systems
|
||||
|
||||
**Discovery:**
|
||||
```
|
||||
|
||||
BMAD: "How does your team manage code versions?"
|
||||
User: "Custom/Complex setup"
|
||||
BMAD: "Please describe:"
|
||||
User: "Frontend in Git, backend in Perforce, configs in SVN"
|
||||
|
||||
````
|
||||
|
||||
**BMAD Adapts:**
|
||||
- Asks for component-specific preferences
|
||||
- Generates VCS-appropriate artifacts per component
|
||||
- Uses neutral terminology in cross-component docs
|
||||
|
||||
**Generated Guidance:**
|
||||
```markdown
|
||||
## Multi-VCS Development Guide
|
||||
|
||||
### Frontend (Git/GitHub Flow)
|
||||
- Feature branches from main
|
||||
- PR review process
|
||||
- Deploy on merge
|
||||
|
||||
### Backend (Perforce)
|
||||
- Create changelist for features
|
||||
- Submit after review
|
||||
- Changelist numbers in deployment notes
|
||||
|
||||
### Configuration (SVN)
|
||||
- Update from trunk before changes
|
||||
- Commit with revision references
|
||||
- Tag for production releases
|
||||
|
||||
### Cross-Component Changes
|
||||
When updating across systems:
|
||||
1. Frontend PR: #123
|
||||
2. Backend Changelist: 456789
|
||||
3. Config Revision: r1234
|
||||
|
||||
Reference all three in deployment ticket.
|
||||
````
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
1. **BMAD never assumes** - always discovers first
|
||||
2. **Adapts terminology** - commit/changelist/revision as appropriate
|
||||
3. **Respects workflows** - doesn't try to "improve" existing processes
|
||||
4. **Practical focus** - generates what works with their tools
|
||||
5. **Clear communication** - uses the team's language
|
||||
|
||||
This flexibility makes BMAD valuable to ANY team, regardless of their VCS choice.
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example implementation of VCS workflow auto-detection for BMAD agents.
|
||||
This can be adapted for different languages and Git libraries.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Dict, List, Tuple, Optional
|
||||
|
||||
|
||||
class GitWorkflowDetector:
|
||||
"""
|
||||
Auto-detect Git workflow from repository history.
|
||||
Follows the principle: "Detection as a HINT, not a DECISION"
|
||||
"""
|
||||
|
||||
def __init__(self, repo_path: str = '.'):
|
||||
self.repo_path = repo_path
|
||||
self.confidence_threshold = 0.7
|
||||
|
||||
def run_git_command(self, cmd: str) -> Optional[str]:
|
||||
"""Execute git command and return output"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd.split(),
|
||||
cwd=self.repo_path,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
def detect_workflow(self) -> Dict:
|
||||
"""
|
||||
Main detection method that returns workflow suggestion with confidence.
|
||||
"""
|
||||
if not self.is_git_repo():
|
||||
return {
|
||||
'detected': False,
|
||||
'reason': 'Not a Git repository'
|
||||
}
|
||||
|
||||
# Calculate scores for each workflow
|
||||
gitflow_score = self._score_gitflow()
|
||||
github_flow_score = self._score_github_flow()
|
||||
trunk_based_score = self._score_trunk_based()
|
||||
|
||||
# Check for migration
|
||||
migration_info = self._detect_migration()
|
||||
|
||||
# Determine best match
|
||||
scores = {
|
||||
'gitflow': gitflow_score,
|
||||
'github_flow': github_flow_score,
|
||||
'trunk_based': trunk_based_score
|
||||
}
|
||||
|
||||
best_workflow = max(scores.items(), key=lambda x: x[1]['score'])
|
||||
workflow_name = best_workflow[0]
|
||||
confidence = best_workflow[1]['score']
|
||||
evidence = best_workflow[1]['evidence']
|
||||
|
||||
# Check if confidence meets threshold
|
||||
if confidence < self.confidence_threshold:
|
||||
return {
|
||||
'detected': True,
|
||||
'workflow': 'unclear',
|
||||
'confidence': confidence,
|
||||
'evidence': evidence,
|
||||
'needs_clarification': True,
|
||||
'migration_detected': migration_info['detected']
|
||||
}
|
||||
|
||||
return {
|
||||
'detected': True,
|
||||
'workflow': workflow_name,
|
||||
'confidence': confidence,
|
||||
'evidence': evidence,
|
||||
'migration_detected': migration_info['detected'],
|
||||
'migration_info': migration_info if migration_info['detected'] else None
|
||||
}
|
||||
|
||||
def is_git_repo(self) -> bool:
|
||||
"""Check if current directory is a Git repository"""
|
||||
return self.run_git_command('git rev-parse --git-dir') is not None
|
||||
|
||||
def _score_gitflow(self) -> Dict:
|
||||
"""Score GitFlow indicators"""
|
||||
score = 0.0
|
||||
evidence = []
|
||||
|
||||
# Check for develop branch
|
||||
branches = self.run_git_command('git branch -a')
|
||||
if branches and ('develop' in branches or 'development' in branches):
|
||||
score += 0.3
|
||||
evidence.append("Found develop branch")
|
||||
|
||||
# Check for release branches
|
||||
if branches and 'release/' in branches:
|
||||
release_count = branches.count('release/')
|
||||
score += 0.3
|
||||
evidence.append(f"Found {release_count} release branches")
|
||||
|
||||
# Check for hotfix branches
|
||||
if branches and 'hotfix/' in branches:
|
||||
score += 0.2
|
||||
evidence.append("Found hotfix branches")
|
||||
|
||||
# Check for version tags
|
||||
tags = self.run_git_command('git tag -l v*')
|
||||
if tags:
|
||||
tag_count = len(tags.split('\n'))
|
||||
score += 0.2
|
||||
evidence.append(f"Found {tag_count} version tags")
|
||||
|
||||
return {'score': score, 'evidence': evidence}
|
||||
|
||||
def _score_github_flow(self) -> Dict:
|
||||
"""Score GitHub Flow indicators"""
|
||||
score = 0.0
|
||||
evidence = []
|
||||
|
||||
# Check for PR merge patterns in recent commits
|
||||
recent_commits = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago" --grep="Merge pull request"'
|
||||
)
|
||||
if recent_commits:
|
||||
pr_count = len(recent_commits.split('\n'))
|
||||
score += 0.3
|
||||
evidence.append(f"Found {pr_count} PR merges in last 90 days")
|
||||
|
||||
# Check for squash merge patterns
|
||||
squash_commits = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago" --grep="(#"'
|
||||
)
|
||||
if squash_commits:
|
||||
score += 0.2
|
||||
evidence.append("Found squash-merge patterns")
|
||||
|
||||
# Check average branch lifespan (simplified)
|
||||
branches = self.run_git_command('git branch -a')
|
||||
if branches and 'feature/' in branches:
|
||||
score += 0.3
|
||||
evidence.append("Using feature branch naming")
|
||||
|
||||
# No develop branch is positive for GitHub Flow
|
||||
if branches and 'develop' not in branches:
|
||||
score += 0.2
|
||||
evidence.append("No develop branch (GitHub Flow indicator)")
|
||||
|
||||
return {'score': score, 'evidence': evidence}
|
||||
|
||||
def _score_trunk_based(self) -> Dict:
|
||||
"""Score Trunk-Based Development indicators"""
|
||||
score = 0.0
|
||||
evidence = []
|
||||
|
||||
# Check ratio of direct commits to main
|
||||
main_commits = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago" --first-parent main'
|
||||
)
|
||||
all_commits = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago"'
|
||||
)
|
||||
|
||||
if main_commits and all_commits:
|
||||
main_count = len(main_commits.split('\n'))
|
||||
total_count = len(all_commits.split('\n'))
|
||||
ratio = main_count / total_count
|
||||
|
||||
if ratio > 0.5:
|
||||
score += 0.4
|
||||
evidence.append(f"{int(ratio * 100)}% commits directly to main")
|
||||
|
||||
# Check for feature flags in commit messages
|
||||
feature_flag_commits = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago" --grep="feature flag" -i'
|
||||
)
|
||||
if feature_flag_commits:
|
||||
score += 0.3
|
||||
evidence.append("Found feature flag usage in commits")
|
||||
|
||||
# Check for very short-lived branches (would need more complex analysis)
|
||||
# Simplified: check if most branches are deleted quickly
|
||||
deleted_branches = self.run_git_command('git reflog show --all | grep "branch:"')
|
||||
if deleted_branches:
|
||||
score += 0.3
|
||||
evidence.append("Pattern suggests short-lived branches")
|
||||
|
||||
return {'score': score, 'evidence': evidence}
|
||||
|
||||
def _detect_migration(self) -> Dict:
|
||||
"""Detect if workflow has changed recently"""
|
||||
# Compare recent vs historical commit patterns
|
||||
recent = self.run_git_command(
|
||||
'git log --oneline --since="30 days ago" --pretty=format:"%d"'
|
||||
)
|
||||
historical = self.run_git_command(
|
||||
'git log --oneline --since="90 days ago" --until="30 days ago" --pretty=format:"%d"'
|
||||
)
|
||||
|
||||
if not recent or not historical:
|
||||
return {'detected': False}
|
||||
|
||||
# Simple heuristic: check if branch naming patterns changed
|
||||
recent_has_develop = 'develop' in recent
|
||||
historical_has_develop = 'develop' in historical
|
||||
|
||||
if recent_has_develop != historical_has_develop:
|
||||
return {
|
||||
'detected': True,
|
||||
'recent_pattern': 'GitFlow-like' if recent_has_develop else 'GitHub Flow-like',
|
||||
'historical_pattern': 'GitFlow-like' if historical_has_develop else 'GitHub Flow-like'
|
||||
}
|
||||
|
||||
return {'detected': False}
|
||||
|
||||
def interactive_confirmation(self, detection_result: Dict) -> str:
|
||||
"""
|
||||
Present detection results to user and get confirmation.
|
||||
This demonstrates the "hint not decision" principle.
|
||||
"""
|
||||
if not detection_result['detected']:
|
||||
print(f"❌ {detection_result['reason']}")
|
||||
return self.manual_selection()
|
||||
|
||||
if detection_result['workflow'] == 'unclear':
|
||||
print("🤔 Could not confidently detect your workflow.")
|
||||
print(f" Confidence: {detection_result['confidence']:.1%}")
|
||||
return self.clarifying_questions()
|
||||
|
||||
# Present detection with evidence
|
||||
print(f"🔍 Analyzed your Git history...")
|
||||
print(f"\nDetected workflow: **{detection_result['workflow']}**")
|
||||
print(f"Confidence: {detection_result['confidence']:.1%}\n")
|
||||
print("Evidence:")
|
||||
for item in detection_result['evidence']:
|
||||
print(f" ✓ {item}")
|
||||
|
||||
if detection_result['migration_detected']:
|
||||
print("\n📊 Note: Detected a possible workflow change recently")
|
||||
print(f" Recent: {detection_result['migration_info']['recent_pattern']}")
|
||||
print(f" Historical: {detection_result['migration_info']['historical_pattern']}")
|
||||
|
||||
# Get confirmation
|
||||
print("\nIs this correct?")
|
||||
print("1. Yes, that's right")
|
||||
print("2. No, we actually use something else")
|
||||
print("3. We recently changed our approach")
|
||||
print("4. It's more complex than that")
|
||||
|
||||
choice = input("\nSelect (1-4): ")
|
||||
|
||||
if choice == '1':
|
||||
return detection_result['workflow']
|
||||
elif choice == '3':
|
||||
return self.handle_migration()
|
||||
else:
|
||||
return self.manual_selection()
|
||||
|
||||
def clarifying_questions(self) -> str:
|
||||
"""Ask progressive questions when detection is unclear"""
|
||||
print("\nLet me ask a few questions to understand your workflow better:\n")
|
||||
|
||||
# Progressive questions to increase confidence
|
||||
score_adjustments = {
|
||||
'gitflow': 0,
|
||||
'github_flow': 0,
|
||||
'trunk_based': 0
|
||||
}
|
||||
|
||||
# Question 1: Team size
|
||||
print("1. How many developers actively commit code?")
|
||||
print(" a) Just me")
|
||||
print(" b) 2-5 developers")
|
||||
print(" c) 6+ developers")
|
||||
team_size = input("Select (a-c): ")
|
||||
|
||||
if team_size == 'a':
|
||||
score_adjustments['trunk_based'] += 0.3
|
||||
elif team_size == 'b':
|
||||
score_adjustments['github_flow'] += 0.2
|
||||
elif team_size == 'c':
|
||||
score_adjustments['gitflow'] += 0.2
|
||||
|
||||
# Question 2: Release frequency
|
||||
print("\n2. How often do you release to production?")
|
||||
print(" a) Multiple times daily")
|
||||
print(" b) Weekly")
|
||||
print(" c) Monthly or less frequently")
|
||||
release_freq = input("Select (a-c): ")
|
||||
|
||||
if release_freq == 'a':
|
||||
score_adjustments['trunk_based'] += 0.3
|
||||
elif release_freq == 'b':
|
||||
score_adjustments['github_flow'] += 0.3
|
||||
elif release_freq == 'c':
|
||||
score_adjustments['gitflow'] += 0.3
|
||||
|
||||
# Determine recommendation
|
||||
best_workflow = max(score_adjustments.items(), key=lambda x: x[1])
|
||||
return best_workflow[0]
|
||||
|
||||
def manual_selection(self) -> str:
|
||||
"""Fallback to manual workflow selection"""
|
||||
print("\nWhich Git workflow best describes your team's approach?\n")
|
||||
print("1. GitHub Flow - Simple feature branches with pull requests")
|
||||
print(" → Best for: Web apps, continuous deployment\n")
|
||||
print("2. GitFlow - Structured branches (develop, release, hotfix)")
|
||||
print(" → Best for: Versioned software, scheduled releases\n")
|
||||
print("3. Trunk-Based - Direct commits or very short branches")
|
||||
print(" → Best for: Mature CI/CD, experienced teams\n")
|
||||
print("4. Custom Git workflow")
|
||||
|
||||
choice = input("Select (1-4): ")
|
||||
|
||||
workflow_map = {
|
||||
'1': 'github_flow',
|
||||
'2': 'gitflow',
|
||||
'3': 'trunk_based',
|
||||
'4': 'custom'
|
||||
}
|
||||
|
||||
return workflow_map.get(choice, 'github_flow')
|
||||
|
||||
def handle_migration(self) -> str:
|
||||
"""Handle workflow migration scenario"""
|
||||
print("\nWhich workflow should BMAD optimize for?")
|
||||
print("1. The new approach (we've completed migration)")
|
||||
print("2. The old approach (recent activity was exceptional)")
|
||||
print("3. Both (we're still transitioning)")
|
||||
|
||||
choice = input("Select (1-3): ")
|
||||
|
||||
if choice == '3':
|
||||
print("\nWhich workflow is your target state?")
|
||||
|
||||
return self.manual_selection()
|
||||
|
||||
|
||||
def main():
|
||||
"""Example usage of the detector"""
|
||||
detector = GitWorkflowDetector()
|
||||
|
||||
# Run detection
|
||||
result = detector.detect_workflow()
|
||||
|
||||
# Get user confirmation (following "hint not decision" principle)
|
||||
confirmed_workflow = detector.interactive_confirmation(result)
|
||||
|
||||
# Save configuration
|
||||
config = {
|
||||
'vcs_config': {
|
||||
'type': 'git',
|
||||
'workflow': confirmed_workflow,
|
||||
'detection_method': 'auto-detected' if result['detected'] else 'user-selected',
|
||||
'confidence_score': result.get('confidence', 0),
|
||||
'detection_evidence': result.get('evidence', []),
|
||||
'cache': {
|
||||
'detected_at': datetime.now().isoformat(),
|
||||
'valid_until': (datetime.now() + timedelta(days=7)).isoformat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print(f"\n✅ Configuration saved!")
|
||||
print(f" Workflow: {confirmed_workflow}")
|
||||
print(f" All BMAD agents will adapt to your {confirmed_workflow} workflow.")
|
||||
|
||||
# Save to file (in real implementation)
|
||||
with open('.bmad/vcs_config.json', 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue