| name | Branch Orchestration |
| description | Use this skill when the user wants to "create branch", "rename branch", "smart branch name", "link branch to issue", or manage branch lifecycle. Provides intelligent branch naming with automatic issue linking following the pattern {issueNum}-{workType}/{kebab-name}. |
| version | 0.1.0 |
Branch Orchestration
Intelligent Git branch management with automated naming, issue linking, and lifecycle operations.
Purpose
Branch Orchestration provides systematic branch naming and management following the convention {issueNum}-{workType}/{kebab-name}. Automatically links branches to GitHub issues, detects work types, and manages branch lifecycle including creation, renaming, remote sync, and cleanup.
When to Use
- Creating branches with smart naming from issue context
- Renaming branches to follow project conventions
- Linking branches to GitHub issues
- Cleaning up merged or stale branches
- When hooks don't provide enough control over naming
Core Capabilities
Branch Naming Convention
Format: {issueNumber}-{workType}/{kebab-case-title}
Examples:
42-feature/add-dark-mode
123-fix/safari-auth-bug
7-docs/update-readme
99-refactor/simplify-api
Branch Creation
Create branches with intelligent naming:
ISSUE_NUM=42
WORK_TYPE="feature"
TITLE="Add dark mode support"
BRANCH_NAME=$(generateBranchName $ISSUE_NUM "$WORK_TYPE" "$TITLE")
git checkout -b "$BRANCH_NAME"
git push -u origin "$BRANCH_NAME"
Utilities:
generateBranchName(issueNumber, workType, title) - Generate formatted name
toKebabCase(title) - Convert title to kebab-case (max 40 chars)
validateBranchName(branchName) - Check naming conventions
Branch Renaming
Rename branches with remote sync:
OLD_BRANCH=$(git rev-parse --abbrev-ref HEAD)
NEW_BRANCH="42-feature/add-dark-mode"
git branch -m "$OLD_BRANCH" "$NEW_BRANCH"
if git ls-remote --heads origin "$OLD_BRANCH" | grep -q "$OLD_BRANCH"; then
git push -u origin "$NEW_BRANCH"
git push origin --delete "$OLD_BRANCH"
else
git push -u origin "$NEW_BRANCH"
fi
Utilities:
parseBranchName(branchName) - Extract components (issue#, work type, title)
extractIssueNumber(branchName) - Get issue number from branch name
Branch Linking
Link branches to GitHub issues:
ISSUE_NUM=42
BRANCH_NAME="42-feature/add-dark-mode"
CURRENT_BODY=$(gh issue view $ISSUE_NUM --json body -q .body)
UPDATED_BODY="$CURRENT_BODY
---
**Branch:** \`$BRANCH_NAME\`"
echo "$UPDATED_BODY" | gh issue edit $ISSUE_NUM --body-file -
STATE_FILE=".claude/logs/branch-issues.json"
jq --arg branch "$BRANCH_NAME" --arg issue "$ISSUE_NUM" \
'.[$branch] = {issueNumber: ($issue | tonumber)}' \
"$STATE_FILE" > tmp.json && mv tmp.json "$STATE_FILE"
State File:
.claude/logs/branch-issues.json - Maps branch names to issue numbers
Branch Cleanup
Clean up merged or stale branches:
git branch --merged main | grep -v "^\*\|main\|master" | xargs -n 1 git branch -d
gh pr list --state merged --json headRefName -q '.[].headRefName' | \
xargs -I {} git push origin --delete {}
git for-each-ref --sort=-committerdate refs/heads/ \
--format='%(refname:short) %(committerdate:relative)' | \
awk '$2 ~ /months/ && $3 >= 1 {print $1}' | \
xargs -n 1 git branch -D
Work Type Detection
Automatically detect work type from context:
import { detectWorkType } from '../shared/hooks/utils/work-type-detector.js';
const workType = detectWorkType('fix the authentication bug');
const workType = detectWorkType(
'Update authentication system',
['bug', 'priority:high']
);
Work Types:
feature - New functionality
fix - Bug fixes
chore - Maintenance tasks
docs - Documentation
refactor - Code improvements
Integration with Hooks
This skill complements the automatic hooks:
| Hook | Automatic Behavior | When to Use Skill |
|---|
| create-issue-on-prompt | Renames branch after issue creation | Rename before issue creation, custom naming |
| add-github-context | Discovers issue from branch name | Manual branch-issue linking |
State Files:
.claude/logs/branch-issues.json - Branch → Issue mapping
Naming Utilities
generateBranchName
generateBranchName(issueNumber: number, workType: WorkType, title: string): string
Generates formatted branch name.
Example:
generateBranchName(42, 'feature', 'Add Dark Mode')
parseBranchName
parseBranchName(branchName: string): ParsedBranchName
Parses branch name into components.
Example:
parseBranchName('42-feature/add-dark-mode')
parseBranchName('123-fix-auth-bug')
validateBranchName
validateBranchName(branchName: string): BranchValidation
Validates branch name against conventions.
Example:
validateBranchName('42-feature/add-dark-mode')
validateBranchName('invalid name with spaces')
extractIssueNumber
extractIssueNumber(branchName: string): number | null
Extracts issue number from branch name.
Example:
extractIssueNumber('42-feature/add-dark-mode')
extractIssueNumber('main')
Examples
Example 1: Create Branch for Issue
ISSUE_NUM=42
ISSUE_DATA=$(gh issue view $ISSUE_NUM --json title,labels)
TITLE=$(echo "$ISSUE_DATA" | jq -r '.title')
LABELS=$(echo "$ISSUE_DATA" | jq -r '.labels[].name' | tr '\n' ',')
WORK_TYPE=$(detectWorkType "$TITLE" "$LABELS")
BRANCH_NAME=$(generateBranchName $ISSUE_NUM "$WORK_TYPE" "$TITLE")
git checkout -b "$BRANCH_NAME"
git push -u origin "$BRANCH_NAME"
echo "Branch \`$BRANCH_NAME\` created" | gh issue comment $ISSUE_NUM --body-file -
Example 2: Rename Branch to Convention
CURRENT=$(git rev-parse --abbrev-ref HEAD)
ISSUE_NUM=$(parseIssueFromBranch "$CURRENT")
if [ -z "$ISSUE_NUM" ]; then
echo "No issue linked to this branch"
exit 1
fi
ISSUE_DATA=$(gh issue view $ISSUE_NUM --json title,labels)
TITLE=$(echo "$ISSUE_DATA" | jq -r '.title')
LABELS=$(echo "$ISSUE_DATA" | jq -r '.labels[].name' | tr '\n' ',')
WORK_TYPE=$(detectWorkType "$TITLE" "$LABELS")
NEW_BRANCH=$(generateBranchName $ISSUE_NUM "$WORK_TYPE" "$TITLE")
git branch -m "$CURRENT" "$NEW_BRANCH"
git push -u origin "$NEW_BRANCH"
git push origin --delete "$CURRENT" 2>/dev/null || true
Example 3: Validate Branch Names in CI
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" =~ ^(main|master|develop)$ ]]; then
exit 0
fi
if ! validateBranchName "$BRANCH"; then
echo "❌ Branch name '$BRANCH' doesn't follow convention: {issueNum}-{workType}/{kebab-name}"
echo "Examples: 42-feature/add-dark-mode, 123-fix/safari-bug"
exit 1
fi
ISSUE_NUM=$(extractIssueNumber "$BRANCH")
if [ -n "$ISSUE_NUM" ]; then
if ! gh issue view $ISSUE_NUM &>/dev/null; then
echo "⚠️ Issue #$ISSUE_NUM referenced in branch name doesn't exist"
fi
fi
Example 4: Bulk Branch Cleanup
MERGED=$(git branch --merged main | grep -v "^\*\|main\|master")
for branch in $MERGED; do
PARSED=$(parseBranchName "$branch")
ISSUE_NUM=$(echo "$PARSED" | jq -r '.issueNumber // empty')
if [ -n "$ISSUE_NUM" ]; then
STATE=$(gh issue view $ISSUE_NUM --json state -q .state 2>/dev/null || echo "")
if [ "$STATE" = "CLOSED" ]; then
echo "Deleting merged branch: $branch (issue #$ISSUE_NUM closed)"
git branch -d "$branch"
git push origin --delete "$branch" 2>/dev/null || true
fi
else
echo "Deleting merged branch: $branch (no linked issue)"
git branch -d "$branch"
fi
done
Best Practices
- Follow naming convention - Always use
{issueNum}-{workType}/{kebab-name}
- Link to issues - Create branches from issue numbers when possible
- Validate before push - Use
validateBranchName() to check format
- Clean up regularly - Delete merged and stale branches
- Update state files - Keep
.claude/logs/branch-issues.json synced
- Use work type detection - Automatically categorize with
detectWorkType()
- Sync with remote - Always use
-u flag when pushing new branches
Common Patterns
Pattern: Create Branch from Current Issue
ISSUE_NUM=$(cat .claude/logs/branch-issues.json | jq -r '.[] | .issueNumber' | head -1)
if [ -n "$ISSUE_NUM" ]; then
ISSUE_DATA=$(gh issue view $ISSUE_NUM --json title,labels)
TITLE=$(echo "$ISSUE_DATA" | jq -r '.title')
WORK_TYPE=$(detectWorkType "$TITLE")
BRANCH_NAME=$(generateBranchName $ISSUE_NUM "$WORK_TYPE" "$TITLE")
git checkout -b "$BRANCH_NAME"
git push -u origin "$BRANCH_NAME"
fi
Pattern: Switch Branch by Issue Number
ISSUE_NUM=42
BRANCH=$(git branch -a | grep -E "^[ *]*$ISSUE_NUM-" | sed 's/^[ *]*//' | head -1)
if [ -n "$BRANCH" ]; then
git checkout "$BRANCH"
else
echo "No branch found for issue #$ISSUE_NUM"
fi
Pattern: List Branches by Work Type
git branch | grep -E "feature/" | sed 's/^[ *]*//'
git branch | grep -E "fix/" | sed 's/^[ *]*//'