feat: add push-all workflow as standalone command

- New /push-all workflow for commit and push with safety
- Can be used anywhere (not just in super-dev-story)
- Comprehensive safety checks (secrets, API keys, large files)
- Smart commit message generation (conventional commits)
- Handles push failures (rebase, upstream, auth)
- Registered in Dev and SM agent menus
- Also integrated into super-dev-story Step 11

Applies to both BMM and BMGD modules
This commit is contained in:
Jonah Schulte 2025-12-26 18:32:00 -05:00
parent 57968001a6
commit 356dd48f49
7 changed files with 1111 additions and 0 deletions

35
PR-DESCRIPTION.md Normal file
View File

@ -0,0 +1,35 @@
# Gap Analysis & Enhanced Quality Workflows
## What
Three new capabilities for ensuring story tasks match codebase reality:
1. **Gap Analysis in dev-story** - Validates tasks before implementation starts
2. **Standalone gap-analysis** - Audit completed stories or validate before development
3. **super-dev-story** - Enhanced workflow with post-dev validation + auto code review
## Why
**Batch planning creates stale stories.** By the time Story 1.3 executes, Stories 1.1-1.2 have created reusable code, but the story still says "create X" → duplicate implementations, wasted time, confusion.
Gap analysis detects existing code and proposes task refinements (extend vs create, remove completed work, add missing dependencies) ensuring stories reflect **current codebase reality**.
## How
**create-story**: Simplified to requirements analysis, generates DRAFT tasks
**dev-story**: Added Step 1.5 - scans codebase, proposes task refinements, 6 user options (Y/A/n/e/s/r)
**gap-analysis**: Standalone audit tool - validates stories without starting development
**super-dev-story**: All dev-story steps + post-dev gap analysis + auto code review
## Testing
✅ All validation checks pass (schemas, lint, format)
✅ Tested via symlink in platform project
✅ Ready for real-world batch planning scenarios
---
**Changes:** 3 workflows, 4 new docs, 16 files total
**Lines:** ~2,740 additions
**Modules:** BMM and BMGD
**Breaking:** None - fully backwards compatible

View File

@ -44,6 +44,10 @@ agent:
workflow: "{project-root}/_bmad/bmgd/workflows/4-production/autonomous-epic/workflow.yaml"
description: "[AEP] Autonomous Epic Processing - create and develop all stories in an epic automatically"
- trigger: PA or fuzzy match on push-all
workflow: "{project-root}/_bmad/bmgd/workflows/4-production/push-all/workflow.yaml"
description: "[PA] Push-All - stage, commit, and push all changes with safety validation"
- trigger: CR or fuzzy match on code-review
workflow: "{project-root}/_bmad/bmgd/workflows/4-production/code-review/workflow.yaml"
description: "[CR] Perform a thorough clean context QA code review on a story flagged Ready for Review"

View File

@ -0,0 +1,518 @@
<workflow>
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
<critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical>
<critical>Communicate all responses in {communication_language}</critical>
<critical>📝 PUSH-ALL - Stage, commit, and push all changes with comprehensive safety validation</critical>
<critical>⚠️ Use with caution - commits ALL repository changes</critical>
<step n="1" goal="Analyze repository changes">
<output>🔄 **Analyzing Repository Changes**
Scanning for changes to commit and push...
</output>
<!-- ANALYZE CHANGES PHASE -->
<action>Run git commands in parallel:</action>
<action>- git status - Show modified/added/deleted/untracked files</action>
<action>- git diff --stat - Show change statistics</action>
<action>- git log -1 --oneline - Show recent commit for message style</action>
<action>- git branch --show-current - Confirm current branch</action>
<action>Parse git status output to identify:
- Modified files
- Added files
- Deleted files
- Untracked files
- Total insertion/deletion counts
</action>
<check if="no changes detected">
<output> **No Changes to Commit**
Working directory is clean.
Nothing to push.
</output>
<action>HALT - No work to do</action>
</check>
</step>
<step n="2" goal="Safety validation">
<critical>🔒 SAFETY CHECKS - Validate changes before committing</critical>
<action>Scan all changed files for dangerous patterns:</action>
**Secret Detection:**
<action>Check for files matching secret patterns:
- .env*, *.key, *.pem, credentials.json, secrets.yaml
- id_rsa, *.p12, *.pfx, *.cer
- Any file containing: _API_KEY=, _SECRET=, _TOKEN= with real values (not placeholders)
</action>
<action>Validate API keys are placeholders only:</action>
<action>✅ Acceptable placeholders:
- API_KEY=your-api-key-here
- SECRET=placeholder
- TOKEN=xxx
- API_KEY=${{YOUR_KEY}}
- SECRET_KEY=&lt;your-key&gt;
</action>
<action>❌ BLOCK real keys:
- OPENAI_API_KEY=sk-proj-xxxxx (real OpenAI key)
- AWS_SECRET_KEY=AKIA... (real AWS key)
- STRIPE_API_KEY=sk_live_... (real Stripe key)
- Any key with recognizable provider prefix + actual value
</action>
**File Size Check:**
<action>Check for files >10MB without Git LFS configuration</action>
**Build Artifacts:**
<action>Check for unwanted directories/files that should be gitignored:
- node_modules/, dist/, build/, .next/, __pycache__/, *.pyc, .venv/
- .DS_Store, Thumbs.db, *.swp, *.tmp, *.log (in root)
- *.class, target/, bin/ (Java)
- vendor/ (unless dependency managed)
</action>
**Git State:**
<action>Verify:
- .gitignore exists and properly configured
- No unresolved merge conflicts
- Git repository initialized
</action>
<!-- SAFETY DECISION -->
<check if="secrets detected OR real API keys found">
<output>🚨 **DANGER: Secrets Detected!**
The following sensitive data was found:
{{list_detected_secrets_with_files}}
❌ **BLOCKED:** Cannot commit secrets to version control.
**Actions Required:**
1. Move secrets to .env file (add to .gitignore)
2. Use environment variables: process.env.API_KEY
3. Remove secrets from tracked files: git rm --cached [file]
4. Update code to load from environment
**Example:**
```
// Before (UNSAFE):
const apiKey = 'sk-proj-xxxxx';
// After (SAFE):
const apiKey = process.env.OPENAI_API_KEY;
```
Halting workflow for safety.
</output>
<action>HALT - Cannot proceed with secrets</action>
</check>
<check if="large files detected without Git LFS">
<output>⚠️ **Warning: Large Files Detected**
Files >10MB found:
{{list_large_files_with_sizes}}
**Recommendation:** Set up Git LFS
```
git lfs install
git lfs track "*.{file_extension}"
git add .gitattributes
```
</output>
<ask>Proceed with large files anyway? [y/n]:</ask>
<check if="user says n">
<output>Halting. Please configure Git LFS first.</output>
<action>HALT</action>
</check>
</check>
<check if="build artifacts detected">
<output>⚠️ **Warning: Build Artifacts Detected**
These files should be in .gitignore:
{{list_build_artifacts}}
**Update .gitignore:**
```
node_modules/
dist/
build/
.DS_Store
```
</output>
<ask>Commit build artifacts anyway? [y/n]:</ask>
<check if="user says n">
<output>Halting. Update .gitignore and git rm --cached [files]</output>
<action>HALT</action>
</check>
</check>
<check if="current branch is main or master">
<output>⚠️ **Warning: Pushing to {{branch_name}}**
You're committing directly to {{branch_name}}.
**Recommendation:** Use feature branch workflow:
1. git checkout -b feature/my-changes
2. Make and commit changes
3. git push -u origin feature/my-changes
4. Create PR for review
</output>
<ask>Push directly to {{branch_name}}? [y/n]:</ask>
<check if="user says n">
<output>Halting. Create a feature branch instead.</output>
<action>HALT</action>
</check>
</check>
<output>✅ **Safety Checks Passed**
All validations completed successfully.
</output>
</step>
<step n="3" goal="Present summary and get confirmation">
<output>
📊 **Changes Summary**
**Files:**
- Modified: {{modified_count}}
- Added: {{added_count}}
- Deleted: {{deleted_count}}
- Untracked: {{untracked_count}}
**Total:** {{total_file_count}} files
**Changes:**
- Insertions: +{{insertion_count}} lines
- Deletions: -{{deletion_count}} lines
**Safety:**
{{if_all_safe}}
✅ No secrets detected
✅ No large files (or approved)
✅ No build artifacts (or approved)
✅ .gitignore configured
{{endif}}
{{if_warnings_approved}}
⚠️ Warnings acknowledged and approved
{{endif}}
**Git:**
- Branch: {{current_branch}}
- Remote: origin/{{current_branch}}
- Last commit: {{last_commit_message}}
---
**I will execute:**
1. `git add .` - Stage all changes
2. `git commit -m "[generated message]"` - Create commit
3. `git push` - Push to remote
</output>
<ask>**Proceed with commit and push?**
Options:
[yes] - Proceed with commit and push
[no] - Cancel (leave changes unstaged)
[review] - Show detailed diff first
</ask>
<check if="user says review">
<action>Execute: git diff --stat</action>
<action>Execute: git diff | head -100 (show first 100 lines of changes)</action>
<output>
{{diff_output}}
(Use 'git diff' to see full changes)
</output>
<ask>After reviewing, proceed with commit and push? [yes/no]:</ask>
</check>
<check if="user says no">
<output>❌ **Push-All Cancelled**
Changes remain unstaged. No git operations performed.
You can:
- Review changes: git status, git diff
- Commit manually: git add [files] && git commit
- Discard changes: git checkout -- [files]
</output>
<action>HALT - User cancelled</action>
</check>
</step>
<step n="4" goal="Stage changes">
<action>Execute: git add .</action>
<action>Execute: git status</action>
<output>✅ **All Changes Staged**
Ready for commit:
{{list_staged_files}}
</output>
</step>
<step n="5" goal="Generate commit message">
<critical>📝 COMMIT MESSAGE - Generate conventional commit format</critical>
<action>Analyze changes to determine commit type:</action>
<action>- feat: New features (new files with functionality)</action>
<action>- fix: Bug fixes (fixing broken functionality)</action>
<action>- docs: Documentation only (*.md, comments)</action>
<action>- style: Formatting, missing semicolons (no code change)</action>
<action>- refactor: Code restructuring (no feature/fix)</action>
<action>- test: Adding/updating tests</action>
<action>- chore: Tooling, configs, dependencies</action>
<action>- perf: Performance improvements</action>
<action>Determine scope (optional):
- Component/feature name if changes focused on one area
- Omit if changes span multiple areas
</action>
<action>Generate message summary (max 72 chars):
- Use imperative mood: "add feature" not "added feature"
- Lowercase except proper nouns
- No period at end
</action>
<action>Generate message body (if changes >5 files):
- List key changes as bullet points
- Max 3-5 bullets
- Keep concise
</action>
<action>Reference recent commits for style consistency</action>
<output>📝 **Generated Commit Message:**
```
{{generated_commit_message}}
```
Based on:
- {{commit_type}} commit type
- {{file_count}} files changed
- {{change_summary}}
</output>
<ask>**Use this commit message?**
Options:
[yes] - Use generated message
[edit] - Let me write custom message
[cancel] - Cancel push-all (leave staged)
</ask>
<check if="user says edit">
<ask>Enter your commit message (use conventional commit format if possible):</ask>
<action>Store user input as {{commit_message}}</action>
<output>✅ Using custom commit message</output>
</check>
<check if="user says cancel">
<output>❌ Push-all cancelled
Changes remain staged.
Run: git reset to unstage
</output>
<action>HALT</action>
</check>
<check if="user says yes">
<action>Use {{generated_commit_message}} as {{commit_message}}</action>
</check>
</step>
<step n="6" goal="Commit changes">
<action>Execute git commit with heredoc for multi-line message safety:
git commit -m "$(cat &lt;&lt;'EOF'
{{commit_message}}
EOF
)"
</action>
<check if="commit fails">
<output>❌ **Commit Failed**
Error: {{commit_error}}
**Common Causes:**
- Pre-commit hooks failing (linting, tests)
- Missing git config (user.name, user.email)
- Locked files or permissions
- Empty commit (no actual changes)
**Fix and try again:**
- Check pre-commit output
- Set git config: git config user.name "Your Name"
- Verify file permissions
</output>
<action>HALT - Fix errors before proceeding</action>
</check>
<action>Parse commit output for hash</action>
<output>✅ **Commit Created**
Commit: {{commit_hash}}
Message: {{commit_subject}}
</output>
</step>
<step n="7" goal="Push to remote">
<output>🚀 **Pushing to Remote**
Pushing {{current_branch}} to origin...
</output>
<action>Execute: git push</action>
<!-- HANDLE COMMON PUSH FAILURES -->
<check if="push fails with rejected (non-fast-forward)">
<output>⚠️ **Push Rejected - Remote Has New Commits**
Remote branch has commits you don't have locally.
Attempting to rebase and retry...
</output>
<action>Execute: git pull --rebase</action>
<check if="rebase has conflicts">
<output>❌ **Merge Conflicts During Rebase**
Conflicts found:
{{list_conflicted_files}}
**Manual resolution required:**
1. Resolve conflicts in listed files
2. git add [resolved files]
3. git rebase --continue
4. git push
Halting for manual conflict resolution.
</output>
<action>HALT - Resolve conflicts manually</action>
</check>
<action>Execute: git push</action>
</check>
<check if="push fails with no upstream branch">
<output> **No Upstream Branch Set**
First push to origin for this branch.
Setting upstream...
</output>
<action>Execute: git push -u origin {{current_branch}}</action>
</check>
<check if="push fails with protected branch">
<output>❌ **Push to Protected Branch Blocked**
Branch {{current_branch}} is protected on remote.
**Use PR workflow instead:**
1. Ensure you're on a feature branch
2. Push feature branch: git push -u origin feature-branch
3. Create PR for review
Changes are committed locally but not pushed.
</output>
<action>HALT - Use PR workflow for protected branches</action>
</check>
<check if="push fails with authentication">
<output>❌ **Authentication Failed**
Git push requires authentication.
**Fix authentication:**
- GitHub: Set up SSH key or Personal Access Token
- Check: git remote -v (verify remote URL)
- Docs: https://docs.github.com/authentication
Changes are committed locally but not pushed.
</output>
<action>HALT - Fix authentication</action>
</check>
<check if="push fails with other error">
<output>❌ **Push Failed**
Error: {{push_error}}
Your changes are committed locally but not pushed to remote.
**Troubleshoot:**
- Check network connection
- Verify remote exists: git remote -v
- Check permissions on remote repository
- Try manual push: git push
Halting for manual resolution.
</output>
<action>HALT - Manual push required</action>
</check>
<!-- SUCCESS -->
<check if="push succeeds">
<output>✅ **Successfully Pushed to Remote!**
**Commit:** {{commit_hash}} - {{commit_subject}}
**Branch:** {{current_branch}} → origin/{{current_branch}}
**Files changed:** {{file_count}} (+{{insertions}}, -{{deletions}})
---
Your changes are now on the remote repository.
</output>
<action>Execute: git log -1 --oneline --decorate</action>
<output>
**Latest commit:** {{git_log_output}}
</output>
</check>
</step>
<step n="8" goal="Completion summary">
<output>🎉 **Push-All Complete, {user_name}!**
**Summary:**
- ✅ {{file_count}} files committed
- ✅ Pushed to origin/{{current_branch}}
- ✅ All safety checks passed
**Commit Details:**
- Hash: {{commit_hash}}
- Message: {{commit_subject}}
- Changes: +{{insertions}}, -{{deletions}}
**Next Steps:**
- Verify on remote (GitHub/GitLab/etc)
- Create PR if working on feature branch
- Notify team if appropriate
**Git State:**
- Working directory: clean
- Branch: {{current_branch}}
- In sync with remote
</output>
</step>
</workflow>

View File

@ -0,0 +1,16 @@
name: push-all
description: "Stage all changes, create commit with safety checks, and push to remote - use with caution"
author: "BMad"
# Critical variables from config
config_source: "{project-root}/_bmad/bmgd/config.yaml"
user_name: "{config_source}:user_name"
communication_language: "{config_source}:communication_language"
# Workflow components
installed_path: "{project-root}/_bmad/bmgd/workflows/4-production/push-all"
instructions: "{installed_path}/instructions.xml"
standalone: true
web_bundle: false

View File

@ -51,6 +51,10 @@ agent:
workflow: "{project-root}/_bmad/bmm/workflows/4-implementation/autonomous-epic/workflow.yaml"
description: "[AE] Autonomous Epic Processing - create and develop all stories in an epic automatically"
- trigger: PA or fuzzy match on push-all
workflow: "{project-root}/_bmad/bmm/workflows/4-implementation/push-all/workflow.yaml"
description: "[PA] Push-All - stage, commit, and push all changes with safety validation"
- trigger: CR or fuzzy match on code-review
workflow: "{project-root}/_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml"
description: "[CR] Perform a thorough clean context code review (Highly Recommended, use fresh context and different LLM)"

View File

@ -0,0 +1,518 @@
<workflow>
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
<critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical>
<critical>Communicate all responses in {communication_language}</critical>
<critical>📝 PUSH-ALL - Stage, commit, and push all changes with comprehensive safety validation</critical>
<critical>⚠️ Use with caution - commits ALL repository changes</critical>
<step n="1" goal="Analyze repository changes">
<output>🔄 **Analyzing Repository Changes**
Scanning for changes to commit and push...
</output>
<!-- ANALYZE CHANGES PHASE -->
<action>Run git commands in parallel:</action>
<action>- git status - Show modified/added/deleted/untracked files</action>
<action>- git diff --stat - Show change statistics</action>
<action>- git log -1 --oneline - Show recent commit for message style</action>
<action>- git branch --show-current - Confirm current branch</action>
<action>Parse git status output to identify:
- Modified files
- Added files
- Deleted files
- Untracked files
- Total insertion/deletion counts
</action>
<check if="no changes detected">
<output> **No Changes to Commit**
Working directory is clean.
Nothing to push.
</output>
<action>HALT - No work to do</action>
</check>
</step>
<step n="2" goal="Safety validation">
<critical>🔒 SAFETY CHECKS - Validate changes before committing</critical>
<action>Scan all changed files for dangerous patterns:</action>
**Secret Detection:**
<action>Check for files matching secret patterns:
- .env*, *.key, *.pem, credentials.json, secrets.yaml
- id_rsa, *.p12, *.pfx, *.cer
- Any file containing: _API_KEY=, _SECRET=, _TOKEN= with real values (not placeholders)
</action>
<action>Validate API keys are placeholders only:</action>
<action>✅ Acceptable placeholders:
- API_KEY=your-api-key-here
- SECRET=placeholder
- TOKEN=xxx
- API_KEY=${{YOUR_KEY}}
- SECRET_KEY=&lt;your-key&gt;
</action>
<action>❌ BLOCK real keys:
- OPENAI_API_KEY=sk-proj-xxxxx (real OpenAI key)
- AWS_SECRET_KEY=AKIA... (real AWS key)
- STRIPE_API_KEY=sk_live_... (real Stripe key)
- Any key with recognizable provider prefix + actual value
</action>
**File Size Check:**
<action>Check for files >10MB without Git LFS configuration</action>
**Build Artifacts:**
<action>Check for unwanted directories/files that should be gitignored:
- node_modules/, dist/, build/, .next/, __pycache__/, *.pyc, .venv/
- .DS_Store, Thumbs.db, *.swp, *.tmp, *.log (in root)
- *.class, target/, bin/ (Java)
- vendor/ (unless dependency managed)
</action>
**Git State:**
<action>Verify:
- .gitignore exists and properly configured
- No unresolved merge conflicts
- Git repository initialized
</action>
<!-- SAFETY DECISION -->
<check if="secrets detected OR real API keys found">
<output>🚨 **DANGER: Secrets Detected!**
The following sensitive data was found:
{{list_detected_secrets_with_files}}
❌ **BLOCKED:** Cannot commit secrets to version control.
**Actions Required:**
1. Move secrets to .env file (add to .gitignore)
2. Use environment variables: process.env.API_KEY
3. Remove secrets from tracked files: git rm --cached [file]
4. Update code to load from environment
**Example:**
```
// Before (UNSAFE):
const apiKey = 'sk-proj-xxxxx';
// After (SAFE):
const apiKey = process.env.OPENAI_API_KEY;
```
Halting workflow for safety.
</output>
<action>HALT - Cannot proceed with secrets</action>
</check>
<check if="large files detected without Git LFS">
<output>⚠️ **Warning: Large Files Detected**
Files >10MB found:
{{list_large_files_with_sizes}}
**Recommendation:** Set up Git LFS
```
git lfs install
git lfs track "*.{file_extension}"
git add .gitattributes
```
</output>
<ask>Proceed with large files anyway? [y/n]:</ask>
<check if="user says n">
<output>Halting. Please configure Git LFS first.</output>
<action>HALT</action>
</check>
</check>
<check if="build artifacts detected">
<output>⚠️ **Warning: Build Artifacts Detected**
These files should be in .gitignore:
{{list_build_artifacts}}
**Update .gitignore:**
```
node_modules/
dist/
build/
.DS_Store
```
</output>
<ask>Commit build artifacts anyway? [y/n]:</ask>
<check if="user says n">
<output>Halting. Update .gitignore and git rm --cached [files]</output>
<action>HALT</action>
</check>
</check>
<check if="current branch is main or master">
<output>⚠️ **Warning: Pushing to {{branch_name}}**
You're committing directly to {{branch_name}}.
**Recommendation:** Use feature branch workflow:
1. git checkout -b feature/my-changes
2. Make and commit changes
3. git push -u origin feature/my-changes
4. Create PR for review
</output>
<ask>Push directly to {{branch_name}}? [y/n]:</ask>
<check if="user says n">
<output>Halting. Create a feature branch instead.</output>
<action>HALT</action>
</check>
</check>
<output>✅ **Safety Checks Passed**
All validations completed successfully.
</output>
</step>
<step n="3" goal="Present summary and get confirmation">
<output>
📊 **Changes Summary**
**Files:**
- Modified: {{modified_count}}
- Added: {{added_count}}
- Deleted: {{deleted_count}}
- Untracked: {{untracked_count}}
**Total:** {{total_file_count}} files
**Changes:**
- Insertions: +{{insertion_count}} lines
- Deletions: -{{deletion_count}} lines
**Safety:**
{{if_all_safe}}
✅ No secrets detected
✅ No large files (or approved)
✅ No build artifacts (or approved)
✅ .gitignore configured
{{endif}}
{{if_warnings_approved}}
⚠️ Warnings acknowledged and approved
{{endif}}
**Git:**
- Branch: {{current_branch}}
- Remote: origin/{{current_branch}}
- Last commit: {{last_commit_message}}
---
**I will execute:**
1. `git add .` - Stage all changes
2. `git commit -m "[generated message]"` - Create commit
3. `git push` - Push to remote
</output>
<ask>**Proceed with commit and push?**
Options:
[yes] - Proceed with commit and push
[no] - Cancel (leave changes unstaged)
[review] - Show detailed diff first
</ask>
<check if="user says review">
<action>Execute: git diff --stat</action>
<action>Execute: git diff | head -100 (show first 100 lines of changes)</action>
<output>
{{diff_output}}
(Use 'git diff' to see full changes)
</output>
<ask>After reviewing, proceed with commit and push? [yes/no]:</ask>
</check>
<check if="user says no">
<output>❌ **Push-All Cancelled**
Changes remain unstaged. No git operations performed.
You can:
- Review changes: git status, git diff
- Commit manually: git add [files] && git commit
- Discard changes: git checkout -- [files]
</output>
<action>HALT - User cancelled</action>
</check>
</step>
<step n="4" goal="Stage changes">
<action>Execute: git add .</action>
<action>Execute: git status</action>
<output>✅ **All Changes Staged**
Ready for commit:
{{list_staged_files}}
</output>
</step>
<step n="5" goal="Generate commit message">
<critical>📝 COMMIT MESSAGE - Generate conventional commit format</critical>
<action>Analyze changes to determine commit type:</action>
<action>- feat: New features (new files with functionality)</action>
<action>- fix: Bug fixes (fixing broken functionality)</action>
<action>- docs: Documentation only (*.md, comments)</action>
<action>- style: Formatting, missing semicolons (no code change)</action>
<action>- refactor: Code restructuring (no feature/fix)</action>
<action>- test: Adding/updating tests</action>
<action>- chore: Tooling, configs, dependencies</action>
<action>- perf: Performance improvements</action>
<action>Determine scope (optional):
- Component/feature name if changes focused on one area
- Omit if changes span multiple areas
</action>
<action>Generate message summary (max 72 chars):
- Use imperative mood: "add feature" not "added feature"
- Lowercase except proper nouns
- No period at end
</action>
<action>Generate message body (if changes >5 files):
- List key changes as bullet points
- Max 3-5 bullets
- Keep concise
</action>
<action>Reference recent commits for style consistency</action>
<output>📝 **Generated Commit Message:**
```
{{generated_commit_message}}
```
Based on:
- {{commit_type}} commit type
- {{file_count}} files changed
- {{change_summary}}
</output>
<ask>**Use this commit message?**
Options:
[yes] - Use generated message
[edit] - Let me write custom message
[cancel] - Cancel push-all (leave staged)
</ask>
<check if="user says edit">
<ask>Enter your commit message (use conventional commit format if possible):</ask>
<action>Store user input as {{commit_message}}</action>
<output>✅ Using custom commit message</output>
</check>
<check if="user says cancel">
<output>❌ Push-all cancelled
Changes remain staged.
Run: git reset to unstage
</output>
<action>HALT</action>
</check>
<check if="user says yes">
<action>Use {{generated_commit_message}} as {{commit_message}}</action>
</check>
</step>
<step n="6" goal="Commit changes">
<action>Execute git commit with heredoc for multi-line message safety:
git commit -m "$(cat &lt;&lt;'EOF'
{{commit_message}}
EOF
)"
</action>
<check if="commit fails">
<output>❌ **Commit Failed**
Error: {{commit_error}}
**Common Causes:**
- Pre-commit hooks failing (linting, tests)
- Missing git config (user.name, user.email)
- Locked files or permissions
- Empty commit (no actual changes)
**Fix and try again:**
- Check pre-commit output
- Set git config: git config user.name "Your Name"
- Verify file permissions
</output>
<action>HALT - Fix errors before proceeding</action>
</check>
<action>Parse commit output for hash</action>
<output>✅ **Commit Created**
Commit: {{commit_hash}}
Message: {{commit_subject}}
</output>
</step>
<step n="7" goal="Push to remote">
<output>🚀 **Pushing to Remote**
Pushing {{current_branch}} to origin...
</output>
<action>Execute: git push</action>
<!-- HANDLE COMMON PUSH FAILURES -->
<check if="push fails with rejected (non-fast-forward)">
<output>⚠️ **Push Rejected - Remote Has New Commits**
Remote branch has commits you don't have locally.
Attempting to rebase and retry...
</output>
<action>Execute: git pull --rebase</action>
<check if="rebase has conflicts">
<output>❌ **Merge Conflicts During Rebase**
Conflicts found:
{{list_conflicted_files}}
**Manual resolution required:**
1. Resolve conflicts in listed files
2. git add [resolved files]
3. git rebase --continue
4. git push
Halting for manual conflict resolution.
</output>
<action>HALT - Resolve conflicts manually</action>
</check>
<action>Execute: git push</action>
</check>
<check if="push fails with no upstream branch">
<output> **No Upstream Branch Set**
First push to origin for this branch.
Setting upstream...
</output>
<action>Execute: git push -u origin {{current_branch}}</action>
</check>
<check if="push fails with protected branch">
<output>❌ **Push to Protected Branch Blocked**
Branch {{current_branch}} is protected on remote.
**Use PR workflow instead:**
1. Ensure you're on a feature branch
2. Push feature branch: git push -u origin feature-branch
3. Create PR for review
Changes are committed locally but not pushed.
</output>
<action>HALT - Use PR workflow for protected branches</action>
</check>
<check if="push fails with authentication">
<output>❌ **Authentication Failed**
Git push requires authentication.
**Fix authentication:**
- GitHub: Set up SSH key or Personal Access Token
- Check: git remote -v (verify remote URL)
- Docs: https://docs.github.com/authentication
Changes are committed locally but not pushed.
</output>
<action>HALT - Fix authentication</action>
</check>
<check if="push fails with other error">
<output>❌ **Push Failed**
Error: {{push_error}}
Your changes are committed locally but not pushed to remote.
**Troubleshoot:**
- Check network connection
- Verify remote exists: git remote -v
- Check permissions on remote repository
- Try manual push: git push
Halting for manual resolution.
</output>
<action>HALT - Manual push required</action>
</check>
<!-- SUCCESS -->
<check if="push succeeds">
<output>✅ **Successfully Pushed to Remote!**
**Commit:** {{commit_hash}} - {{commit_subject}}
**Branch:** {{current_branch}} → origin/{{current_branch}}
**Files changed:** {{file_count}} (+{{insertions}}, -{{deletions}})
---
Your changes are now on the remote repository.
</output>
<action>Execute: git log -1 --oneline --decorate</action>
<output>
**Latest commit:** {{git_log_output}}
</output>
</check>
</step>
<step n="8" goal="Completion summary">
<output>🎉 **Push-All Complete, {user_name}!**
**Summary:**
- ✅ {{file_count}} files committed
- ✅ Pushed to origin/{{current_branch}}
- ✅ All safety checks passed
**Commit Details:**
- Hash: {{commit_hash}}
- Message: {{commit_subject}}
- Changes: +{{insertions}}, -{{deletions}}
**Next Steps:**
- Verify on remote (GitHub/GitLab/etc)
- Create PR if working on feature branch
- Notify team if appropriate
**Git State:**
- Working directory: clean
- Branch: {{current_branch}}
- In sync with remote
</output>
</step>
</workflow>

View File

@ -0,0 +1,16 @@
name: push-all
description: "Stage all changes, create commit with safety checks, and push to remote - use with caution"
author: "BMad"
# Critical variables from config
config_source: "{project-root}/_bmad/bmm/config.yaml"
user_name: "{config_source}:user_name"
communication_language: "{config_source}:communication_language"
# Workflow components
installed_path: "{project-root}/_bmad/bmm/workflows/4-implementation/push-all"
instructions: "{installed_path}/instructions.xml"
standalone: true
web_bundle: false