Claude Code for OSS Issue Triage Workflow Tutorial
Open source maintainers often struggle with incoming issue floods. A well-designed Claude Code skill can automate the tedious triage process—classifying bugs, detecting duplicates, assigning priorities, and routing issues to the right maintainers. This tutorial shows you how to build a complete issue triage workflow that integrates with GitHub’s API.
Why Automate Issue Triage?
Every OSS project eventually faces this problem: issues pile up faster than maintainers can review them. Without triage, critical bugs get lost in the noise, duplicate reports multiply, and contributors feel ignored. Manual triage consumes hours each week that could go toward actual development.
Claude Code can help by:
- Classifying issue types (bug, feature request, documentation, question)
- Detecting potential duplicates via semantic similarity
- Assigning priority labels based on severity keywords and context
- Routing issues to appropriate maintainers or teams
- Filtering spam and invalid submissions
The key is building a skill that understands your project’s conventions and applies consistent triage logic.
Setting Up Your Triage Skill
Create a new skill file for issue triage. This skill will process GitHub issues and apply your project’s triage rules:
---
name: issue-triage
description: "Automatically triage GitHub issues with classification, priority assignment, and duplicate detection"
tools:
- read_file
- bash
- github
- write_file
category: workflow
version: 1.0.0
---
# Issue Triage Skill
This skill processes incoming GitHub issues and applies automated triage logic based on your project's conventions.
Building the Triage Logic
The core of your triage workflow is a set of classification rules. Here’s how to implement each major triage function:
Issue Classification
Parse the issue body and title to determine the type:
## Classification Rules
When processing an issue:
1. **Bug Reports** - Look for:
- Keywords: "crash", "error", "broken", "fail", "bug"
- Error messages or stack traces
- Steps to reproduce patterns
2. **Feature Requests** - Look for:
- Keywords: "add", "support", "feature", "would be nice", "request"
- "Should be able to..." statements
- Enhancement prefixes like "[FEATURE]"
3. **Documentation** - Look for:
- Keywords: "docs", "documentation", "typo", "spelling"
- File path references to docs folder
4. **Questions** - Look for:
- Question marks in title
- Keywords: "how to", "can i", "is it possible"
5. **Duplicates** - Compare against existing issues using:
- Title similarity (cosine similarity > 0.7)
- Same error messages or keywords
Priority Assignment
Assign priority based on issue characteristics:
## Priority Assignment
Assign priority labels using these rules:
- **P0 - Critical**: System crashes, data loss, security vulnerabilities
- **P1 - High**: Major features broken, significant workarounds needed
- **P2 - Medium**: Regular bugs, minor feature gaps
- **P3 - Low**: Cosmetic issues, minor inconveniences, documentation
Use keyword matching and context analysis to determine priority.
Complete Triage Workflow Implementation
Here’s a practical implementation that combines all triage functions:
#!/usr/bin/env python3
"""GitHub Issue Triage Bot using Claude Code"""
import os
import re
from datetime import datetime
# Configuration
REPO_OWNER = os.getenv("GITHUB_REPO_OWNER")
REPO_NAME = os.getenv("GITHUB_REPO_NAME")
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
# Classification patterns
BUG_PATTERNS = [
r'\b(crash|error|bug|broken|fail|not working)\b',
r'Steps to reproduce',
r'Traceback|stack trace',
]
FEATURE_PATTERNS = [
r'\b(feature|add|support|implement|enhancement)\b',
r'would be nice',
r'should be able to',
]
DOC_PATTERNS = [
r'\b(docs?|documentation|typo|spelling)\b',
r'\.md$',
]
QUESTION_PATTERNS = [
r'\?$',
r'\b(how (to|can)|is it possible|can i)\b',
]
PRIORITY_PATTERNS = {
'P0': [r'\b(crash|data loss|security|vulnerability|critical)\b'],
'P1': [r'\b(major|broken|significant workaround)\b'],
'P2': [r'\b(bug|issue|problem)\b'],
'P3': [r'\b(cosmetic|minor|inconvenience)\b'],
}
def classify_issue(title, body):
"""Classify issue type based on content"""
text = f"{title} {body}".lower()
if any(re.search(p, text) for p in BUG_PATTERNS):
return "bug"
elif any(re.search(p, text) for p in FEATURE_PATTERNS):
return "enhancement"
elif any(re.search(p, text) for p in DOC_PATTERNS):
return "documentation"
elif any(re.search(p, text) for p in QUESTION_PATTERNS):
return "question"
else:
return "other"
def assign_priority(title, body):
"""Assign priority based on severity indicators"""
text = f"{title} {body}".lower()
for priority, patterns in PRIORITY_PATTERNS.items():
if any(re.search(p, text) for p in patterns):
return priority
return "P2" # Default priority
def extract_labels(issue_type, priority):
"""Generate labels based on classification"""
labels = []
# Type labels
type_labels = {
"bug": ["type: bug"],
"enhancement": ["type: feature"],
"documentation": ["type: docs"],
"question": ["type: question"],
"other": ["type: other"],
}
labels.extend(type_labels.get(issue_type, []))
# Priority labels
labels.append(f"priority: {priority}")
return labels
# Main triage function
def triage_issue(issue_number):
"""Process a single issue through the triage workflow"""
# Fetch issue details (via GitHub CLI or API)
# This is where Claude Code integrates
title = get_issue_title(issue_number)
body = get_issue_body(issue_number)
# Run classification
issue_type = classify_issue(title, body)
priority = assign_priority(title, body)
labels = extract_labels(issue_type, priority)
# Add triage comment
triage_comment = f"""**Triage Complete**
- **Type:** {issue_type}
- **Priority:** {priority}
- **Labels:** {', '.join(labels)}
_This issue was automatically triaged by Claude Code._"""
# Apply labels and comment
add_labels(issue_number, labels)
add_comment(issue_number, triage_comment)
return {"type": issue_type, "priority": priority}
Integrating with GitHub
The easiest integration uses the GitHub CLI (gh) which Claude Code can invoke directly:
# Fetch issue details
gh issue view $ISSUE_NUMBER --repo $REPO --json title,body,labels
# Add labels
gh issue edit $ISSUE_NUMBER --add-label "triage: done,priority: P1"
# Add comment
gh issue comment $ISSUE_NUMBER --body "Triage complete: classified as bug (P1)"
Create a wrapper script that your skill calls:
#!/bin/bash
# triage-issue.sh
ISSUE_NUM=$1
REPO=$2
# Get issue details
ISSUE_DATA=$(gh issue view $ISSUE_NUM --repo $REPO --json title,body)
TITLE=$(echo $ISSUE_DATA | jq -r '.title')
BODY=$(echo $ISSUE_DATA | jq -r '.body')
# Process with Claude Code
# Claude analyzes and determines labels
# Apply results
gh issue edit $ISSUE_NUM --repo $REPO --add-label "triage: automated"
Actionable Advice for Effective Triage
Start Simple, Iterate
Begin with basic keyword matching before adding ML-based duplicate detection. Claude Code excels at rule-based triage that’s easy to audit and modify.
Maintain Human Oversight
Always add a “needs: triage” label for issues requiring human review. Your skill should flag edge cases rather than guess wrong:
## Edge Cases to Flag for Human Review
- Security vulnerabilities → flag immediately to security team
- Issues with no reproduction steps → request more info
- Very old issues → mark as "stale" for cleanup
- Issues from first-time contributors → welcome and prioritize response
Track Triage Accuracy
Log triage decisions and their outcomes. Periodically review misclassifications to refine your rules. Claude Code can generate weekly triage reports:
## Weekly Triage Summary
- **Total Issues:** 47
- **Auto-triaged:** 41 (87%)
- **Classification Accuracy:** 92%
- **Average Triage Time:** 3.2 seconds
### Issues Requiring Review
[List of flagged issues for human review]
Document Your Conventions
Create a CONTRIBUTING.md section explaining your triage labels. Contributors who understand the process are more likely to provide complete issue reports.
Conclusion
Automating issue triage with Claude Code transforms an overwhelming backlog into a manageable workflow. Start with classification and priority assignment, then expand to duplicate detection and maintainer routing as your rules mature. The key is maintaining human oversight for edge cases while letting Claude handle the predictable 80% of incoming issues.
Your maintainers will thank you—and so will contributors who see their issues addressed promptly.