/fixpr Command - Intelligent PR Fix Analysis
Analyzes GitHub PR blockers and fixes CI failures, conflicts, and bot feedback to achieve mergeable status.
/plugin marketplace add jleechanorg/claude-commands/plugin install claude-commands@claude-commands-marketplaceWhen this command is invoked, YOU (Claude) must execute these steps immediately: This is NOT documentation - these are COMMANDS to execute right now. Use TodoWrite to track progress through multi-phase workflows.
Action Steps:
Enhanced Universal Composition: /fixpr now uses /e (execute) for intelligent optimization while preserving its core universal composition architecture.
Action Steps:
Default Mode: Uses /e to determine optimal approach
Parallel Mode (Enhanced): 4. Trigger: Complex PRs with >10 distinct issues, multiple conflict types, or extensive CI failures 5. Behavior: Spawn specialized analysis agents while Claude orchestrates integration 6. Benefits: Faster processing of complex scenarios, parallel issue resolution
Action Steps:
Action Steps:
MANDATORY PRE-FLIGHT CHECK: /fixpr MUST verify GitHub CLI authentication before making any API requests.
if ! gh auth status; then
echo "ā GitHub CLI not authenticated - run 'gh auth login' first"
exit 1
fi
POSIX-shell friendly; works in bash, zsh, and dash.
Only proceed once authentication succeeds.
Action Steps: šØ CRITICAL PRINCIPLE: GitHub PR status is the ONLY authoritative source of truth. NEVER assume local conditions match GitHub reality.
MANDATORY GITHUB FIRST APPROACH:
status=$(gh pr view "$PR" --json mergeStateStatus,statusCheckRollup)
merge_state=$(echo "$status" | jq -r '.mergeStateStatus // "UNKNOWN"')
### Phase 6: Step 3: Analyze Issues with Intelligence & Pattern Detection
**Action Steps:**
šØ **CRITICAL BUG PREVENTION**: Before analyzing any GitHub API data, ALWAYS verify data structure to prevent "'list' object has no attribute 'get'" errors.
**MANDATORY DATA STRUCTURE VERIFICATION**:
1. ā
**Check if data is list or dict** before using .get() methods
2. ā
**Use isinstance(data, dict)** before accessing dict methods
3. ā
**Iterate through lists** rather than treating them as single objects
4. ā **NEVER assume API response structure**
š **NEW: PATTERN DETECTION ENGINE** - Automatically scan for similar issues across the codebase
**FIRESTORE MOCKING PATTERN DETECTION** (High Priority):
```bash
### Phase 7: Step 4: Detect CI Environment Discrepancies
**Action Steps:**
šØ **CRITICAL DETECTION**: Before applying fixes, detect if GitHub CI failures are environment-specific.
**GitHub CI vs Local Test Discrepancy Detection**:
1. **MANDATORY CHECK**: Run local tests first: `./run_tests.sh`
2. **DISCREPANCY INDICATOR**: Local tests pass (ā
) but GitHub CI shows failures (ā)
3. **COMMON CAUSES**:
4. Different Python versions between local and CI
5. Missing environment variables in CI
6. Different package versions or dependencies
7. Race conditions that only manifest in CI environment
8. Time zone or locale differences
9. File system case sensitivity (CI often Linux, local might be macOS/Windows)
**When Discrepancy Detected, Trigger `/redgreen` Workflow**:
```bash
### Phase 8: Step 5: Apply Fixes Intelligently
**Action Steps:**
šÆ **FOCUSED APPROACH**: Apply fixes to the immediate issues identified in the current PR
Based on the analysis, apply appropriate fixes:
1. **MANDATORY PRECONDITION**: Do not modify code until the `/redgreen` command above has produced the matching local failure and marked the RED phase complete.
**For CI Failures**:
2. **Environment issues**: Update dependencies, fix missing environment variables, adjust timeouts
3. **Code issues**: Correct import statements, fix failing assertions, add type annotations
4. **Test issues**: Update test expectations, fix race conditions, handle edge cases
5. **šØ GitHub CI vs Local Discrepancy**: When GitHub CI fails but local tests pass, use `/redgreen` methodology:
6. **RED PHASE**: Create failing tests that reproduce the GitHub CI failure locally
7. **GREEN PHASE**: Fix the code to make both local and GitHub tests pass
8. **REFACTOR PHASE**: Clean up the solution while maintaining test coverage
9. **Trigger**: GitHub shows failing tests but `./run_tests.sh` passes locally
10. **Process**: Extract GitHub CI error ā Write failing test ā Implement fix ā Verify both environments
### Phase 9: šØ Integrated `/redgreen` Workflow for CI Discrepancies
**Action Steps:**
**AUTOMATIC ACTIVATION**: When GitHub CI fails but local tests pass, `/fixpr` automatically implements this workflow:
**MANDATORY COMMAND INVOCATION**: `/fixpr` must explicitly call the real `/redgreen` slash command (no aliases) to recreate the GitHub failure locally **before** touching any source files. The run must complete and show the failing local test that mirrors GitHub prior to entering the fix phase.
### RED PHASE: Reproduce GitHub Failure Locally
**Action Steps:**
```bash
### GREEN PHASE: Fix Code to Pass Both Environments
**Action Steps:**
```bash
### REFACTOR PHASE: Clean Up and Optimize
**Action Steps:**
```bash
### Phase 13: Step 5: Verify Mergeability Status - **MANDATORY GITHUB RE-VERIFICATION**
**Action Steps:**
šØ **CRITICAL**: After applying fixes, ALWAYS re-fetch fresh GitHub status. NEVER assume fixes worked without GitHub confirmation.
**MANDATORY GITHUB RE-VERIFICATION PROTOCOL**:
šØ **CRITICAL**: Never trust `mergeable: "MERGEABLE"` alone - it can show mergeable even with failing tests!
1. **Comprehensive Test State Verification** (Wait for CI to complete):
- **WAIT**: Allow 30-60 seconds for GitHub CI to register changes after push
- **FETCH ALL STATUS**: `gh pr view <PR> --json statusCheckRollup,mergeable,mergeStateStatus`
- **šØ MANDATORY FAILURE CHECK**: Explicitly validate NO tests are failing:
```bash
# CRITICAL: Check for any failing required checks
failing_checks=$(gh pr view "$PR" --json statusCheckRollup --jq '
[
(.statusCheckRollup.contexts.nodes // [])[]
| select((.isRequired // false) == true)
| ((.conclusion // .state) // "") as $outcome
| select($outcome == "FAILURE"
or $outcome == "ERROR"
or $outcome == "TIMED_OUT"
or $outcome == "CANCELLED"
or $outcome == "ACTION_REQUIRED")
] | length
')
if [ "$failing_checks" -gt 0 ]; then
echo "ā BLOCKING: $failing_checks required checks failing"
gh pr view "$PR" --json statusCheckRollup --jq '
(.statusCheckRollup.contexts.nodes // [])[]
| select((.isRequired // false) == true)
| ((.conclusion // .state) // "") as $outcome
| select($outcome == "FAILURE"
or $outcome == "ERROR"
or $outcome == "TIMED_OUT"
or $outcome == "CANCELLED"
or $outcome == "ACTION_REQUIRED")
| "ā \((.context // .name) // \"unknown\"): \($outcome) - \((.description // \"No description\"))"
'
echo "šØ /fixpr MUST NOT declare success with failing tests"
exit 1
fi
```
- **šØ WARNING SIGNS**:
- `mergeStateStatus: "UNSTABLE"` = Failing required checks
- `conclusion: "FAILURE"` in ANY statusCheckRollup entry = Hard failure
- `state: "FAILURE"` = Failed CI run
- **DISPLAY**: Print updated GitHub status with explicit test validation:
```text
š GITHUB STATUS VERIFICATION (After Fixes):
BEFORE:
ā test-unit: FAILING - TypeError in auth.py
ā mergeable: false, mergeStateStatus: CONFLICTING
AFTER (Fresh from GitHub):
ā
ALL CHECKS VERIFIED: No failing tests found
ā
test-unit: PASSING - All tests pass
ā
mergeable: "MERGEABLE", mergeStateStatus: CLEAN
š RESULT: PR is genuinely mergeable on GitHub
```
- **SUCCESS CRITERIA**:
- `mergeable: "MERGEABLE"` AND
- `mergeStateStatus: "CLEAN"` (not "UNSTABLE") AND
- Zero entries with `conclusion: "FAILURE"` AND
- All required checks passing
2. **Local CI Replica Verification**:
- **MANDATORY**: Run `./run_ci_replica.sh` to verify fixes in CI-equivalent environment
- **PURPOSE**: Ensures fixes work in the same environment as GitHub Actions CI
- **ENVIRONMENT**: Sets CI=true, GITHUB_ACTIONS=true, TESTING=true, TEST_MODE=mock
- **VALIDATION**: Must pass completely before considering fixes successful
- Check git status for uncommitted changes
- Verify no conflicts remain with the base branch
3. **Push and Monitor**:
- Push fixes to the PR branch
- Wait for GitHub to re-run CI checks
- Monitor the PR page to see blockers clearing
4. **Success Criteria** (šØ ALL MUST BE TRUE):
- **COMPREHENSIVE TEST VALIDATION**: Zero failing checks in statusCheckRollup
- **STATUS VERIFICATION**: `mergeable: "MERGEABLE"` AND `mergeStateStatus: "CLEAN"`
- **CONFLICT RESOLUTION**: GitHub shows "This branch has no conflicts"
- **REVIEW APPROVAL**: No "Changes requested" reviews blocking merge
- **FINAL VALIDATION**: The merge button would be green (but we don't click it!)
- **šØ MANDATORY**: If ANY check shows `conclusion: "FAILURE"`, /fixpr has NOT succeeded
If blockers remain, iterate through the analysis and fix process again until the PR is fully mergeable.
### Phase 14: Integrated CI Verification Workflow
**Action Steps:**
**Complete Fix and Verification Cycle**:
```bash
## š REFERENCE DOCUMENTATION
# /fixpr Command - Intelligent PR Fix Analysis
**Usage**: `/fixpr <PR_NUMBER> [--auto-apply]`
**Purpose**: Make GitHub PRs mergeable by analyzing and fixing CI failures, merge conflicts, and bot feedback - without merging. **NEW**: Automatically uses `/redgreen` methodology when GitHub CI fails but local tests pass.
## šØ FUNDAMENTAL PRINCIPLE: GITHUB IS THE AUTHORITATIVE SOURCE
**CRITICAL RULE**: GitHub PR status is the ONLY source of truth. Local conditions (tests, conflicts, etc.) may differ from GitHub's reality.
**šØ CRITICAL LEARNING (2025-09-09)**: GitHub `mergeable: "MERGEABLE"` can be MISLEADING - it indicates no merge conflicts but does NOT guarantee tests are passing. Always explicitly inspect `statusCheckRollup.contexts.nodes[]` for failing checks before declaring success.
## āŗ š§ Learning & Thinking: How to Improve /fixpr
### šØ Critical Improvements Needed
1. **Mandatory Authentication Verification**
```bash
if ! gh auth status; then
echo "ā GitHub CLI not authenticated - run 'gh auth login' first"
exit 1
fi
POSIX-shell friendly; works in bash, zsh, and dash. 2. Correct GitHub Status Interpretation
status=$(gh pr view "$PR" --json mergeStateStatus,statusCheckRollup)
merge_state=$(echo "$status" | jq -r '.mergeStateStatus // "UNKNOWN"')
# Extract the individual CI checks from the nested statusCheckRollup payload
checks=$(echo "$status" | jq '.statusCheckRollup.contexts.nodes // []')
# Filter to outcomes that indicate hard failures
failed_checks=$(echo "$checks" | jq '[.[]
| select((.conclusion // .state // "")
| test("^(FAILURE|ERROR|TIMED_OUT|ACTION_REQUIRED|CANCELLED)$"))
]')
# Count how many failing checks remain
failed_count=$(echo "$failed_checks" | jq 'length')
if [[ "$merge_state" == "CLEAN" ]] && [[ "$failed_count" -eq 0 ]]; then
echo "ā
Actually ready to merge"
else
echo "ā Tests failing or unstable: $merge_state, $failed_count failures"
fi
statusCheckRollup.contexts.nodesmergeable: "MERGEABLE" alonestatus_data is the parsed JSON payload from
gh pr view --json statusCheckRollup. GitHub returns a dictionary whose
failing checks live under statusCheckRollup.contexts.nodes, but defensive
code should tolerate unexpected shapes.)
nodes = []
if isinstance(status_data, dict):
nodes = (
((status_data.get('statusCheckRollup') or {}).get('contexts') or {})
.get('nodes')
) or []
for check in nodes:
if isinstance(check, dict):
outcome = (check.get('conclusion') or check.get('state') or '')
if outcome in ('FAILURE', 'ERROR', 'TIMED_OUT', 'CANCELLED', 'ACTION_REQUIRED'):
name = check.get('name') or check.get('context') or 'unknown'
print(f"ā Failed: {name}")
mergeablemergeable: "MERGEABLE" only means there are no merge conflicts.mergeStateStatus and the individual statusCheckRollup conclusions for truth./fixpr to enforce authentication and authoritative status validation.MANDATORY APPROACH:
WHY THIS MATTERS: GitHub uses different CI environments, merge algorithms, and caching than local development. A PR may be mergeable locally but blocked on GitHub, or vice versa.
The /fixpr command leverages Claude's natural language understanding to analyze PR blockers and fix them. The goal is to get the PR into a mergeable state (all checks passing, no conflicts) but never actually merge it. It orchestrates GitHub tools and git commands through intent-based descriptions rather than explicit syntax.
š Enhanced with /redgreen Integration: When GitHub CI shows test failures that don't reproduce locally, /fixpr automatically triggers the Red-Green-Refactor methodology to create failing tests locally, fix the environment-specific issues, and verify the solution works in both environments.
Coordination Protocol: Claude maintains overall workflow control, orchestrating agent results through natural language understanding integration.
Dynamically detect repository information from the git environment:
š” Implementation hints:
https://github.com/owner/repo.git or git@github.com:owner/repo.gitchecks=$(echo "$status" | jq '.statusCheckRollup.contexts.nodes // []')
failed_checks=$(echo "$checks" | jq '[.[] | select((.conclusion // .state // "") | test("^(FAILURE|ERROR|TIMED_OUT|ACTION_REQUIRED|CANCELLED)$")) ]') failed_count=$(echo "$failed_checks" | jq 'length')
echo "š GitHub merge state: $merge_state" echo "š Failing checks: $failed_count"
if [[ "$merge_state" != "CLEAN" ]] || [[ "$failed_count" -ne 0 ]]; then echo "ā Tests failing or merge state not clean - investigate before claiming success" fi
šØ **DEFENSIVE PROGRAMMING FOR GITHUB API RESPONSES**:
- ā
**ALWAYS handle both list and dict responses** from GitHub API
- ā
**NEVER use .get() on variables that might be lists**
- ā
**Use isinstance() checks** before accessing dict methods
- ā **NEVER assume GitHub API response structure**
**SAFE DATA ACCESS PATTERN**:
```python
# When processing GitHub API responses like statusCheckRollup, reviews, or comments
if isinstance(data, dict):
value = data.get('key', default)
elif isinstance(data, list) and len(data) > 0:
# Handle list responses (checks, comments, reviews)
value = data[0].get('key', default) if isinstance(data[0], dict) else default # Default if data[0] is not a dict
else:
value = default # Default if data is neither a dict nor a non-empty list
EXPLICIT GITHUB STATUS FETCHING - Fetch these specific items from GitHub to understand what's blocking mergeability:
CI State & Test Failures (GitHub Authoritative):
gh pr view <PR> --json statusCheckRollup - Get ALL CI check resultsstatusCheckRollup is a GraphQL object whose contexts.nodes field is the LIST of checkscontexts.nodes[]; never call .get() on the rollup wrapper itselfā FAILING: test-unit (exit code 1)gh pr view "$PR_NUMBER" --json statusCheckRollup --jq \
'(.statusCheckRollup.contexts.nodes // [])
| map(select((.conclusion // .state // "")
| test("^(FAILURE|ERROR|TIMED_OUT|ACTION_REQUIRED|CANCELLED)$")))
| map("\((.name // .context) // "unknown"): \((.description // "no description provided"))")
| .[]'
# When processing statusCheckRollup.contexts.nodes (list of individual checks):
for check in (statusCheckRollup.get('contexts', {}).get('nodes', [])):
status = check.get('state', 'unknown')
name = check.get('context') or check.get('name', 'unknown')
š GITHUB CI STATUS (Authoritative):
ā test-unit: FAILING (required) - TypeError: Cannot read property 'id' of undefined
ā
test-lint: PASSING (required)
ā³ test-integration: PENDING (required)
Merge Conflicts (GitHub Authoritative):
gh pr view <PR> --json mergeable,mergeStateStatus - Get GitHub merge statusā CONFLICTING: 3 files have conflictsgh pr diff <PR> - Get actual conflict content from GitHubš GITHUB MERGE STATUS (Authoritative):
ā mergeable: false
ā mergeableState: CONFLICTING
š Conflicting files: src/main.py, tests/test_main.py, README.md
Bot Feedback & Review Comments (GitHub Authoritative):
gh pr view <PR> --json reviews,comments - Get ALL review data from GitHubā CHANGES_REQUESTED by @reviewer# When processing reviews (which is a list):
for review in reviews: # DON'T use .get() on reviews itself
state = review.get('state', 'unknown') # OK - review is a dict
user = review.get('user', {}).get('login', 'unknown')
# When processing comments (which is a list):
for comment in comments: # DON'T use .get() on comments itself
body = comment.get('body', '') # OK - comment is a dict
author = comment.get('user', {}).get('login', 'unknown')
š GITHUB REVIEW STATUS (Authoritative):
ā @coderabbit: CHANGES_REQUESTED - Fix security vulnerability in auth.py
ā
@teammate: APPROVED
ā³ @senior-dev: REVIEW_REQUESTED
PR Metadata & Protection Rules (GitHub Authoritative):
gh pr view <PR> --json state,mergeable,requiredStatusChecks - Get current GitHub PR stateš GITHUB PR METADATA (Authoritative):
š State: OPEN | Mergeable: false
š”ļø Required checks: [test-unit, test-lint, security-scan]
š« Blocking factors: 1 failing check, 1 requested change
šÆ THE GOAL: Gather everything that GitHub shows as preventing the green "Merge" button from being available - NEVER assume, ALWAYS verify with fresh GitHub data.
grep -r "@patch.firebase_admin.firestore.client" . --include=".py" >/dev/null 2>&1
grep -r "firestore_service.get_db" . --include="*.py" >/dev/null 2>&1
**MAGICMOCK SERIALIZATION PATTERN DETECTION**:
```bash
# Detect other patterns that cause "Object of type MagicMock is not JSON serializable" errors
# 1. Scan for MagicMock usage in tests that interact with JSON APIs
grep -r "MagicMock" . --include="test_*.py" -A 5 -B 5 | grep -E "(json\.|\.json|JSON)" >/dev/null 2>&1
# 2. Look for patch decorators that don't return proper fake objects
grep -r "@patch" . --include="test_*.py" -A 10 | grep -E "(return_value.*MagicMock|side_effect.*MagicMock)" >/dev/null 2>&1
SCOPE FLAGS FOR PATTERN DETECTION:
--scope=pattern: Fix detected issues + apply same fix to similar patterns across codebase--scope=comprehensive: Fix all related test infrastructure issuesExamine the collected data to understand what needs fixing:
CI Status Analysis:
statusCheckRollup.contexts.nodes is the list of checks - iterate through those nodesset -o pipefail
# Extract specific failing tests and error messages (pytest + Python errors)
gh api "repos/$OWNER/$REPO/actions/jobs/$job_id/logs" | \
grep -Ei \
-e '^FAILURES?' \
-e '^=+ FAILURES =+' \
-e 'collected [0-9]+ items' \
-e '===+ [0-9]+ (failed|errors?|x?failed|x?passed)' \
-e 'E\s+AssertionError' \
-e 'Traceback \(most recent call last\):' \
-e 'ModuleNotFoundError:' \
-e 'ImportError:' \
-e 'NameError:' \
-e 'TypeError:' \
-e '\.py[:,]?\d+(:\d+)?' \
-A 3 -B 3
# Common patterns to identify:
# - ModuleNotFoundError: Missing imports or dependencies
# - AssertionError: Test logic failures with specific expectations
# - NameError: Undefined variables or missing imports
# - ImportError: Module loading issues
# - TypeError: Type mismatches in function calls
# - Orchestration failures: Redis/tmux dependency issues
# - File permission or path issues in CI environment
Merge Conflict Analysis:
Bot Feedback Processing:
./run_tests.sh
gh pr view <PR> --json statusCheckRollup
PR_NUMBER=<PR> # Replace with the numeric PR identifier failing_check="test-unit" # Replace with actual failing check name from GitHub ci_failure_log=$(gh pr view "$PR_NUMBER" --json statusCheckRollup --jq ' (.statusCheckRollup.contexts.nodes // []) | map(select(((.conclusion // .state) // "") | test("^(FAILURE|ERROR|TIMED_OUT|ACTION_REQUIRED|CANCELLED)$"))) | map("((.context // .name) // "unknown"): ((.description // "no description"))") | join("\n") ') /redgreen --pr "$PR_NUMBER" --check "$failing_check" --gh-log "$ci_failure_log" --local "./run_tests.sh"
# 1. Extract specific GitHub CI failure details
gh pr view <PR> --json statusCheckRollup --jq '(.statusCheckRollup.contexts.nodes // [])[] | select(((.conclusion // .state) // "") | test("^(FAILURE|ERROR|TIMED_OUT|ACTION_REQUIRED|CANCELLED)$"))'
# Example: "AssertionError: Expected 'foo' but got 'FOO' in test_case_sensitivity"
# 2. Create a failing test that reproduces the CI environment condition
# Example: Create test that fails due to case sensitivity like CI environment
PROJECT_ROOT=$(git rev-parse --show-toplevel)
TESTS_DIR="$PROJECT_ROOT/tests"
cat > "$TESTS_DIR/test_ci_discrepancy_redgreen.py" << 'EOF'
"""RED-GREEN test to reproduce GitHub CI failure locally."""
import os
import unittest
class TestCIDiscrepancy(unittest.TestCase):
def test_case_sensitivity_like_ci(self):
"""RED: Reproduce the case sensitivity issue from GitHub CI."""
# Simulate CI environment behavior (Linux case-sensitive)
os.environ['FORCE_CASE_SENSITIVE'] = 'true'
# This should fail locally to match GitHub CI failure
result = some_function_that_failed_in_ci()
self.assertEqual(result, 'foo') # This will fail like CI if function returns 'FOO'
def some_function_that_failed_in_ci():
"""Simulate the CI failure condition - replace with actual failing function."""
# Example: Simulate a case sensitivity issue by returning 'FOO' instead of 'foo'
return 'FOO'
EOF
# 3. Verify test fails locally (RED confirmed)
# Use project-specific test runner (examples: python -m pytest, TESTING=true python, etc.)
<RUN_TEST_COMMAND> "$TESTS_DIR/test_ci_discrepancy_redgreen.py"
# ā FAIL: AssertionError: Expected 'foo' but got 'FOO'
<RUN_TEST_COMMAND> "$TESTS_DIR/test_ci_discrepancy_redgreen.py"
./run_tests.sh
# 7. Clean up the fix while maintaining test coverage
# - Remove any temporary debugging code
# - Optimize the solution
# - Add proper error handling
# - Update documentation if needed
# 8. Final verification
./run_tests.sh && ./run_ci_replica.sh
# ā
All tests pass in both local and CI-equivalent environments
INTEGRATION WITH FIXPR WORKFLOW:
/redgreen workflow is triggered automatically within /fixpr when CI discrepancies are detected./run_ci_replica.sh to confirm fix works in CI environmentFor Merge Conflicts:
For Bot Suggestions:
When --auto-apply is specified, the command operates more autonomously:
Safe Fixes Only:
Always Preserve:
Incremental Approach:
Flaky Test Indicators:
Real Issues Requiring Fixes:
Preservation Priority:
Risk-Based Approach:
For every fix applied:
# Analyze and show what would be fixed (default: critical scope)
/fixpr 1234
# Analyze and automatically apply safe fixes
/fixpr 1234 --auto-apply
# š NEW: Pattern detection mode - Fix similar issues across codebase
/fixpr 1234 --scope=pattern
# ā Fixes immediate blockers
# ā Scans for similar patterns (e.g., firestore mocking mismatches)
# ā Applies same fix to all instances
# ā Prevents future similar failures
# Comprehensive mode - Fix all related test infrastructure
/fixpr 1234 --scope=comprehensive --auto-apply
# Example with GitHub CI vs Local discrepancy (auto-triggers /redgreen workflow):
# Local: ./run_tests.sh ā ā
All tests pass
# GitHub: CI shows ā test-unit FAILING - Environment-specific test failure
/fixpr 1234
# ā Automatically detects discrepancy
# ā Triggers RED-GREEN workflow
# ā Immediately issues the real /redgreen slash command to reproduce the CI failure locally
/redgreen --pr 1234 --check "test-unit" --gh-log "AssertionError: Expected 'foo' but got 'FOO'" --local "./run_tests.sh"
# ā Waits for /redgreen to finish establishing a failing local test that matches GitHub
# ā Creates failing test locally
# ā Fixes code to work in both environments
# ā Verifies GitHub CI passes
# Example with MagicMock JSON serialization pattern:
# GitHub: ā "Object of type MagicMock is not JSON serializable"
/fixpr 1234 --scope=pattern
# ā Identifies @patch("firebase_admin.firestore.client") mismatch
# ā Fixes immediate test to @patch("firestore_service.get_db")
# ā Scans codebase for similar patterns
# ā Fixes 4+ additional test files with same issue
# ā Prevents regression of MagicMock serialization errors
./run_ci_replica.sh
git add -A && git commit -m "fix: Address CI failures and merge conflicts"
$(git rev-parse --show-toplevel)/scripts/sync_check.sh
sleep 60
gh pr view <PR> --json statusCheckRollup,mergeable,mergeStateStatus
**Key Benefits of run_ci_replica.sh Integration**:
- **Environment Parity**: Exact match with GitHub Actions CI environment variables
- **Early Detection**: Catch CI failures locally before pushing to GitHub
- **Time Efficiency**: Avoid multiple push/wait/fail cycles
- **Confidence**: Know fixes will work in CI before pushing
## Integration Points
This command works naturally with:
- `/copilot` - For comprehensive PR workflow orchestration
- `/commentreply` - To respond to review feedback
- `/pushl` - To push fixes to remote
- `/redgreen` (alias `/tdd`) - **NEW**: Automatically triggered for GitHub CI vs local test discrepancies
- Testing commands - To verify fixes work correctly
- `./run_ci_replica.sh` - To verify fixes work in CI-equivalent environment
## Error Recovery
When issues arise:
- Gracefully handle missing tools by trying alternatives
- Provide clear explanations of what failed and why
- Suggest manual steps when automation isn't possible
- Maintain partial progress rather than failing completely
## Natural Language Advantage
This approach leverages Claude's understanding to:
- Adapt to different repository structures
- Handle edge cases without explicit programming
- Provide context-aware solutions
- Explain decisions in human terms
The focus is on describing intent and letting Claude determine the best implementation, making the command more flexible and maintainable than rigid scripted approaches.
## Important Notes
**šØ NEVER MERGE**: This command's job is to make PRs mergeable, not to merge them. The user retains control over when/if to actually merge.
**š Success Metric**: A successful run means GitHub would show a green merge button with no blockers - all CI passing, no conflicts, no blocking reviews.
## Regression Testing Notes
- `./run_tests.sh` *(2025-09-27)* ā Completed with 177/178 tests passing. The remaining failure (`$PROJECT_ROOT/tests/test_main_state_helper.py`) surfaces an existing `ResourceWarning` about an unclosed log file handle in `$PROJECT_ROOT/main.py`. Investigate the logging lifecycle before treating `/fixpr` updates as production-ready.