Branch Workflow — Standardized Branch Creation
SkillAI & modelsStandardized branch creation with type detection, issue ID extraction, and worktree setup. Creates working branches (-WB) and integrates with selective-copy for clean PRs.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Branch Workflow — Standardized Branch Creation skill
What this skill tells your AI
The instructions your AI receives, as published by diegosouzapw/awesome-omni-skill in skills/data-ai/agent-ops-branch-workflow/SKILL.md and read by ahel’s review.
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:
- Type detection — Auto-detect bug/feature/refactor from description
- Issue ID extraction — JIRA, GitHub, or internal issue references
- Slug generation — Short, URL-safe names from descriptions
- Worktree setup — Parallel development without branch switching
- 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:
- Stop
- Ask ONE question at a time
- Wait for explicit confirmation
- Only proceed when ALL inputs are confirmed
NEVER:
- Guess the source branch
- Assume
mainordevelopwithout 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:
| Task | Working Branch | Clean 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
| Argument | Description | Required | Default |
|---|---|---|---|
task_description | Description of work (for type/ID/slug detection) | Yes | - |
source_branch | Branch to base new branch on | Yes | - |
branch_name | Override auto-generated name | No | Auto-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:
| Keywords | Type |
|---|---|
| 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:
| Pattern | Example | Type |
|---|---|---|
[A-Z]{2,10}-\d+ | GATS-0666, PROJ-123 | JIRA |
#\d+ | #456 | GitHub |
[A-Z]+-\d+@\w+ | FEAT-0305@p8q9r0 | Internal |
# 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
| Error | Cause | Solution |
|---|---|---|
| "Branch already exists" | Name collision | Append timestamp: {branch}-{yyyyMMdd} |
| "Source branch not found" | Invalid source | Run git fetch origin, verify name |
| "Worktree path exists" | Directory collision | Remove old worktree or use different path |
| "fatal: not a git repository" | Wrong directory | Navigate 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
| Skill | Relationship |
|---|---|
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 |
Signals
- GitHub stars
- 57
- Forks
- 19
- Last commit
- Mar 2026
Advanced
- Catalog kind
- skill
- Gateway key
agent-ops-branch-workflow- Source
- github.com/diegosouzapw/awesome-omni-skill