Claude-skill-registry agent-ops-branch-workflow

Standardized branch creation with type detection, issue ID extraction, and worktree setup. Creates working branches (-WB) and integrates with selective-copy for clean PRs.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/agent-ops-branch-workflow" ~/.claude/skills/majiayu000-claude-skill-registry-agent-ops-branch-workflow && rm -rf "$T"
manifest: skills/data/agent-ops-branch-workflow/SKILL.md
source content

Branch Workflow — Standardized Branch Creation

Create working branches with consistent naming from task descriptions. Platform agnostic.

Works with or without

aoc
CLI. Uses standard git commands.


Purpose

Standardize branch creation with:

  1. Type detection — Auto-detect bug/feature/refactor from description
  2. Issue ID extraction — JIRA, GitHub, or internal issue references
  3. Slug generation — Short, URL-safe names from descriptions
  4. Worktree setup — Parallel development without branch switching
  5. Clean branch integration — Seamless handoff to selective-copy

CRITICAL: No Assumptions

NEVER assume. NEVER guess. ALWAYS ask.

Before creating ANY branch, confirm with user:

If unclear about...ASK
Task description"What is the task? Please include issue ID if available."
Source branch"Which branch should I base this on? (e.g., develop, main)"
Branch type"I detected this as a [type]. Is that correct?"
Issue ID"I found [ID]. Is this the correct issue reference?"
Generated name"I'll create branch
{name}
. Does this look right?"

If ANY of these are ambiguous:

  1. Stop
  2. Ask ONE question at a time
  3. Wait for explicit confirmation
  4. Only proceed when ALL inputs are confirmed

NEVER:

  • Guess the source branch
  • Assume
    main
    or
    develop
    without asking
  • Create a branch without showing the user the exact name first
  • Proceed if the task description is vague

Branch Naming Convention

Working branch: {type}/{ID}-{slug}-WB
Clean branch:   {type}/{ID}-{slug}

Examples:

TaskWorking BranchClean Branch
"GATS-0666: Add auth support"
feature/GATS-0666-add-auth-WB
feature/GATS-0666-add-auth
"Fix #123 login timeout"
bugfix/123-login-timeout-WB
bugfix/123-login-timeout
"Refactor database layer"
refactor/db-layer-WB
refactor/db-layer

Invocation

User says something like:

  • "Create a branch for GATS-0666: Add authentication"
  • "Start working on fix for login timeout bug"
  • "New feature branch based on develop"

Arguments

ArgumentDescriptionRequiredDefault
task_description
Description of work (for type/ID/slug detection)Yes-
source_branch
Branch to base new branch onYes-
branch_name
Override auto-generated nameNoAuto-generated

Phase 1: Create Working Branch

Step 1: Gather Requirements

If not provided, ask:

To create your working branch, I need:

1. What's the task? (include issue ID if you have one)
   Example: "GATS-0666: Add OAuth2 authentication support"

2. Which branch should I base this on?
   Example: develop, main, release/v2.0

Step 2: Detect Branch Type

Analyze the task description to determine type:

KeywordsType
hotfix, critical, urgent, emergency
hotfix/
fix, bug, error, crash, broken, issue
bugfix/
refactor, cleanup, restructure, reorganize
refactor/
doc, readme, changelog, documentation
docs/
chore, deps, dependency, maintenance, update
chore/
(default) feature, add, implement, create
feature/
# PowerShell - Type Detection
function Get-BranchType {
    param([string]$Description)
    
    $desc = $Description.ToLower()
    
    if ($desc -match 'hotfix|critical|urgent|emergency') { return 'hotfix' }
    if ($desc -match 'fix|bug|error|crash|broken|issue') { return 'bugfix' }
    if ($desc -match 'refactor|cleanup|restructure|reorganize') { return 'refactor' }
    if ($desc -match 'doc|readme|changelog') { return 'docs' }
    if ($desc -match 'chore|deps|dependency|maintenance|update') { return 'chore' }
    
    return 'feature'
}
# Bash - Type Detection
get_branch_type() {
    local desc="${1,,}"  # lowercase
    
    if [[ "$desc" =~ hotfix|critical|urgent|emergency ]]; then echo "hotfix"; return; fi
    if [[ "$desc" =~ fix|bug|error|crash|broken|issue ]]; then echo "bugfix"; return; fi
    if [[ "$desc" =~ refactor|cleanup|restructure|reorganize ]]; then echo "refactor"; return; fi
    if [[ "$desc" =~ doc|readme|changelog ]]; then echo "docs"; return; fi
    if [[ "$desc" =~ chore|deps|dependency|maintenance|update ]]; then echo "chore"; return; fi
    
    echo "feature"
}

Step 3: Extract Issue ID

Look for issue identifiers in the description:

PatternExampleType
[A-Z]{2,10}-\d+
GATS-0666, PROJ-123JIRA
#\d+
#456GitHub
[A-Z]+-\d+@\w+
FEAT-0305@p8q9r0Internal
# PowerShell - Issue ID Extraction
function Get-IssueId {
    param([string]$Description)
    
    # JIRA pattern: PROJECT-123
    if ($Description -match '([A-Z]{2,10}-\d+)') {
        return @{ Id = $Matches[1]; Type = 'jira' }
    }
    
    # GitHub pattern: #123
    if ($Description -match '#(\d+)') {
        return @{ Id = $Matches[1]; Type = 'github' }
    }
    
    # Internal AgentOps pattern
    if ($Description -match '([A-Z]+-\d+)@\w+') {
        return @{ Id = $Matches[1]; Type = 'internal' }
    }
    
    return @{ Id = $null; Type = 'none' }
}
# Bash - Issue ID Extraction
get_issue_id() {
    local desc="$1"
    
    # JIRA pattern
    if [[ "$desc" =~ ([A-Z]{2,10}-[0-9]+) ]]; then
        echo "${BASH_REMATCH[1]}"
        return
    fi
    
    # GitHub pattern
    if [[ "$desc" =~ \#([0-9]+) ]]; then
        echo "${BASH_REMATCH[1]}"
        return
    fi
    
    # Internal pattern
    if [[ "$desc" =~ ([A-Z]+-[0-9]+)@ ]]; then
        echo "${BASH_REMATCH[1]}"
        return
    fi
    
    echo ""
}

Step 4: Generate Slug

Create a short, URL-safe name from the description:

# PowerShell - Slug Generation
function Get-BranchSlug {
    param(
        [string]$Description,
        [string]$IssueId,
        [int]$MaxLength = 30
    )
    
    $text = $Description
    
    # Remove issue ID
    if ($IssueId) {
        $text = $text -replace [regex]::Escape($IssueId), ''
    }
    
    # Remove common prefixes
    $text = $text -replace '^(fix|bug|feature|add|implement|create|update|refactor)[:.\s]+', ''
    
    # Convert to lowercase, replace non-alphanumeric with dashes
    $slug = ($text.ToLower() -replace '[^a-z0-9]+', '-').Trim('-')
    
    # Truncate at word boundary
    if ($slug.Length -gt $MaxLength) {
        $slug = $slug.Substring(0, $MaxLength)
        if ($slug.Contains('-')) {
            $slug = $slug.Substring(0, $slug.LastIndexOf('-'))
        }
    }
    
    if ([string]::IsNullOrEmpty($slug)) { $slug = 'work' }
    
    return $slug
}
# Bash - Slug Generation
get_branch_slug() {
    local desc="$1"
    local issue_id="$2"
    local max_length="${3:-30}"
    
    local text="$desc"
    
    # Remove issue ID
    if [ -n "$issue_id" ]; then
        text="${text//$issue_id/}"
    fi
    
    # Remove common prefixes
    text=$(echo "$text" | sed -E 's/^(fix|bug|feature|add|implement|create|update|refactor)[:. ]+//i')
    
    # Convert to lowercase, replace non-alphanumeric with dashes
    local slug=$(echo "$text" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//;s/-$//')
    
    # Truncate
    if [ ${#slug} -gt $max_length ]; then
        slug="${slug:0:$max_length}"
        slug="${slug%-*}"  # Remove partial word
    fi
    
    [ -z "$slug" ] && slug="work"
    
    echo "$slug"
}

Step 5: Build Branch Name

# PowerShell
$type = Get-BranchType -Description $TaskDescription
$issueInfo = Get-IssueId -Description $TaskDescription
$slug = Get-BranchSlug -Description $TaskDescription -IssueId $issueInfo.Id

if ($BranchName) {
    $workingBranch = $BranchName
} elseif ($issueInfo.Id) {
    $workingBranch = "$type/$($issueInfo.Id)-$slug-WB"
} else {
    $workingBranch = "$type/$slug-WB"
}

Write-Host "Branch type: $type"
Write-Host "Issue ID: $($issueInfo.Id ?? 'none')"
Write-Host "Slug: $slug"
Write-Host "Working branch: $workingBranch"
# Bash
type=$(get_branch_type "$task_description")
issue_id=$(get_issue_id "$task_description")
slug=$(get_branch_slug "$task_description" "$issue_id")

if [ -n "$branch_name" ]; then
    working_branch="$branch_name"
elif [ -n "$issue_id" ]; then
    working_branch="${type}/${issue_id}-${slug}-WB"
else
    working_branch="${type}/${slug}-WB"
fi

echo "Branch type: $type"
echo "Issue ID: ${issue_id:-none}"
echo "Slug: $slug"
echo "Working branch: $working_branch"

Step 6: Create Worktree

# PowerShell
# Calculate worktree path (replace / with - for filesystem)
$worktreePath = "../$($workingBranch -replace '/', '-')"

# Ensure source branch exists and is up to date
git fetch origin $SourceBranch 2>$null

# Create worktree with new branch
git worktree add -b $workingBranch $worktreePath "origin/$SourceBranch"

if ($LASTEXITCODE -eq 0) {
    Write-Host "`n✓ Working branch created successfully" -ForegroundColor Green
    Write-Host "  Branch: $workingBranch"
    Write-Host "  Path: $worktreePath"
    Write-Host "  Based on: $SourceBranch"
    Write-Host "`nTo start working:"
    Write-Host "  cd $worktreePath"
} else {
    Write-Error "Failed to create worktree"
}
# Bash
# Calculate worktree path
worktree_path="../${working_branch//\//-}"

# Ensure source branch exists and is up to date
git fetch origin "$source_branch" 2>/dev/null

# Create worktree with new branch
if git worktree add -b "$working_branch" "$worktree_path" "origin/$source_branch"; then
    echo ""
    echo "✓ Working branch created successfully"
    echo "  Branch: $working_branch"
    echo "  Path: $worktree_path"
    echo "  Based on: $source_branch"
    echo ""
    echo "To start working:"
    echo "  cd $worktree_path"
else
    echo "Error: Failed to create worktree" >&2
    exit 1
fi

Step 7: Update Focus State

After creating the branch, update

.agent/focus.md
:

# PowerShell
$cleanBranch = $workingBranch -replace '-WB$', ''

$focusUpdate = @"

## Branch Info

- working_branch: $workingBranch
- clean_branch: $cleanBranch (pending - use selective-copy)
- source_branch: $SourceBranch
- issue_id: $($issueInfo.Id ?? 'none')
- task: $TaskDescription
- worktree_path: $worktreePath
"@

# Append to focus.md or create section
Add-Content -Path ".agent/focus.md" -Value $focusUpdate

Phase 2: Create Clean Branch (for PR)

When ready for code review, use

selective-copy
to create the clean branch:

# PowerShell
# The clean branch is the working branch without -WB suffix
$cleanBranch = $workingBranch -replace '-WB$', ''

# Invoke selective-copy (manually or via skill)
# This will:
# 1. Create $cleanBranch from $workingBranch
# 2. Exclude .agent/, .github/, and logged files
# 3. Create exclusion log for selective-merge

User command:

Create a clean branch for PR

The

selective-copy
skill will:

  • Detect the working branch (ends with
    -WB
    )
  • Auto-generate clean branch name (remove
    -WB
    )
  • Exclude agent-ops files
  • Create exclusion log

Complete Workflow Example

# === PHASE 1: Start Work ===

# User: "Create a branch for GATS-0666: Add OAuth2 authentication"
# Source: develop

# Agent detects:
# - Type: feature
# - Issue ID: GATS-0666
# - Slug: oauth2-auth

# Agent creates:
git worktree add -b feature/GATS-0666-oauth2-auth-WB ../feature-GATS-0666-oauth2-auth-WB origin/develop

# === WORK HAPPENS HERE ===
# Agent assists with implementation in the worktree
# Files logged to .agent/log/created-files.log

# === PHASE 2: Ready for PR ===

# User: "Create a clean branch for PR"
# Agent invokes selective-copy:
# - source: feature/GATS-0666-oauth2-auth-WB
# - target: feature/GATS-0666-oauth2-auth

# Push for review:
cd ../feature-GATS-0666-oauth2-auth
git push origin feature/GATS-0666-oauth2-auth

# === REVIEW CYCLE ===
# After feedback, use selective-merge to sync changes

Verification

After branch creation:

# PowerShell
Write-Host "`n=== Branch Verification ===" -ForegroundColor Cyan

# List worktrees
Write-Host "`nWorktrees:"
git worktree list

# Show branch info
Write-Host "`nNew branch:"
git -C $worktreePath branch -vv

# Show files
Write-Host "`nFiles in worktree:"
Get-ChildItem $worktreePath -Name | Select-Object -First 10
# Bash
echo ""
echo "=== Branch Verification ==="

# List worktrees
echo ""
echo "Worktrees:"
git worktree list

# Show branch info
echo ""
echo "New branch:"
git -C "$worktree_path" branch -vv

# Show files
echo ""
echo "Files in worktree:"
ls "$worktree_path" | head -10

Error Handling

ErrorCauseSolution
"Branch already exists"Name collisionAppend timestamp:
{branch}-{yyyyMMdd}
"Source branch not found"Invalid sourceRun
git fetch origin
, verify name
"Worktree path exists"Directory collisionRemove old worktree or use different path
"fatal: not a git repository"Wrong directoryNavigate to git repo root

Branch Name Collision

# PowerShell - Handle existing branch
$baseBranch = $workingBranch
$counter = 1

while (git show-ref --verify --quiet "refs/heads/$workingBranch") {
    $workingBranch = "$baseBranch-$counter"
    $counter++
}

Cleanup

After PR is merged:

# PowerShell
# Remove worktree
git worktree remove $worktreePath

# Delete working branch locally
git branch -d $workingBranch

# Delete clean branch locally  
git branch -d $cleanBranch

# Delete remote branches (if desired)
git push origin --delete $workingBranch
git push origin --delete $cleanBranch
# Bash
# Remove worktree
git worktree remove "$worktree_path"

# Delete branches locally
git branch -d "$working_branch"
git branch -d "$clean_branch"

# Delete remote branches (if desired)
git push origin --delete "$working_branch"
git push origin --delete "$clean_branch"

Related Skills

SkillRelationship
agent-ops-selective-copy
Creates clean branch from working branch
agent-ops-selective-merge
Syncs working → clean after review feedback
agent-ops-git
Underlying git operations
agent-ops-implementation
Logs created files in working branch