Create GitHub task issues with hybrid auto-generation and user review
This skill reads project-specific values from skills.config.json at the repository root.
Required keys: github.repo, github.owner, github.project_number, milestones.*, team.*
If not found, prompt the user for repository and project details.
Role: GitHub Issue Automation Scope: Project-wide issue creation with intelligent context extraction Platform: Windows + gh CLI Repository: {github.repo} Project: {project.fullname}
Create well-formed GitHub task issues by extracting context from git history, auto-generating draft content, and guiding user review before submission. Integrates with project boards and validates labels.
Before using this skill:
gh CLI is authenticated: gh auth statusgh auth refresh -s project (if needed)CRITICAL: Always read templates from .github/ISSUE_TEMPLATE/ before creating issues.
| Template File | Type | Use Case |
|---|---|---|
task.md | Task | New features, improvements, planned work |
bug.md | Bug | Defects, crashes, unexpected behavior |
vfx_task.md | VFX Task | VFX team work items |
ene_proto.md | Enemy Prototype | GD enemy/elite/boss prototypes |
2d_3d_task.md | Art Task | 2D/3D art work items |
epic.md | Epic | Large feature epics |
feature_request.md | Feature Request | New feature proposals |
1. Read user input or detect from context:
- Keywords "bug", "fix", "crash", "broken" → bug.md
- Keywords "vfx", "particle", "effect" → vfx_task.md
- Keywords "enemy", "boss", "elite", "prototype" → ene_proto.md
- Keywords "art", "texture", "model", "asset" → 2d_3d_task.md
- Keywords "epic", "milestone", "phase" → epic.md
- Default → task.md
2. Read selected template:
Read .github/ISSUE_TEMPLATE/{selected_template}
3. Parse template structure to extract:
- Required sections
- Default labels from frontmatter
- Title format from frontmatter
Per create-gitissue-guidelines.md:
| Rule | Description |
|---|---|
| Line breaks | Use <br /> instead of newlines in body |
| Headers | Use **Header**<br /> instead of ## Header |
| Bold | Section headers only |
| Dates | Always YYYY-MM-DD format, calculated manually |
Format: task_S02_[TechnicalType]_[SubType]_[UniqueName]
Examples:
- task_S02_ENG_Framework_convert-resting-point-to-smartio
- task_S02_ENG_Combat_add-parry-timing-window
- task_S02_VFX_Boss_tiger-flame-attack
- task_S02_GD_Ene_spear-wielder-prototype
Technical Types:
- ENG = Engineering
- VFX = Visual Effects
- GD = Game Design
- ART = Art/Animation
- UI = User Interface
- AI = Artificial Intelligence
- LVL = Level Design
Sub Types (by domain):
- ENG: Framework, Combat, AI, UI, Tools, System
- VFX: Boss, Enemy, Player, Environment
- GD: Ene, Boss, Elite, Player
- ART: Char, Env, Prop, Anim
{CWD} = Current Working Directory
{Branch} = Current git branch name
{BaseCommit} = Merge base with main branch
{ProjectName} = "{project.fullname}"
{ProjectNumber} = {github.project_number}
{ProjectID} = "{github.project_node_id}"
{RepoOwner} = "{github.owner}"
{RepoName} = "s2"
{Today} = Current date in YYYY-MM-DD format
Query available milestones at runtime:
gh api repos/{github.repo}/milestones --jq '.[] | "\(.number): \(.title)"'
Domain-to-Milestone Mapping:
| Domain Labels | Suggested Milestone |
|---|---|
combat, gameplay | {milestones.combat.name} ({milestones.combat.number}) |
ai, system | {milestones.game_ai.name} ({milestones.game_ai.number}) |
vfx, ArtAnim, main-char | PRE-PROD: META (10) |
level-design | PRE-PROD: ENV (1) |
UXUI | PRE-PROD: META (10) |
Engineering (framework) | {milestones.game_ai.name} ({milestones.game_ai.number}) or {milestones.combat.name} ({milestones.combat.number}) based on content |
| Default | alpha (9) |
Read appropriate template from .github/ISSUE_TEMPLATE/:
# Determine template based on user input or context
# Default: task.md
# Read template file
cat .github/ISSUE_TEMPLATE/task.md
Template Parsing:
Extract frontmatter (between --- markers):
name: Template nametitle: Title format patternlabels: Default labels (comma-separated)assignees: Default assigneesExtract body sections:
## Section Name headersExample Parsed Template (task.md):
Frontmatter:
name: Task
title: [TASK-ID] Task title
labels: task
Sections:
- Task Description
- Task ID
- Epic
- Acceptance Criteria
- Dependencies
- Size & Effort
- Due Date
- Additional Context
Check prerequisites before proceeding:
# Verify gh CLI authentication
gh auth status
# Get current branch
git rev-parse --abbrev-ref HEAD
# Fetch available labels
gh label list --json name --jq '.[].name'
Validation Rules:
gh auth status fails → Error: "GitHub CLI not authenticated. Run: gh auth login"Gather information from current branch state:
# Get current branch name
git rev-parse --abbrev-ref HEAD
# Get commit messages since diverged from main
git log main...HEAD --oneline --no-decorate
# Get file changes with statistics
git diff main...HEAD --stat --no-color
# Get uncommitted changes
git status --short
Store:
Handle Edge Cases:
Map file paths to domain labels based on project structure:
Label Detection Rules:
| File Path Pattern | Domain Labels |
|---|---|
Plugins/Frameworks/Sipher* | Engineering, system |
Plugins/EditorTools/* | Engineering, tools |
Source/S2/Private/Combat/* | combat, Engineering |
Source/S2/Private/AI/* | ai, Engineering |
Source/S2/UI/* | UXUI, Engineering |
Content/S2/Core_VFX/* | vfx |
Content/S2/Core_Char/S2_char_MC/* | main-char, ArtAnim |
Content/S2/Core_Boss/* | combat, gameplay |
Content/S2/Maps/* | level-design |
*.cpp, *.h | Engineering |
*.uasset (in Anim folders) | ArtAnim |
Docs/*, *.md | documentation |
Logic:
Example:
Changed files:
- Plugins/Frameworks/SipherInteractionObjectFramework/Source/SipherIOTypes.h (+200)
- Content/S2/Core_Boss/s2_boss_tiger/BP_Tiger.uasset (+50)
Detected labels: task, Engineering, system, combat, gameplay
Calculate T-shirt size based on total lines changed:
Total Lines Changed → T-Shirt Size → Estimated Hours
< 100 → XS → 2-4h
100-300 → S → 4-8h
300-600 → M → 8-16h
600-1200 → L → 16-32h
> 1200 → XL → 32h+
Logic:
git diff --statSpecial Case:
Build complete draft issue from extracted context:
Primary Format (from guidelines):
task_S02_[TechnicalType]_[SubType]_[unique-name]
Logic:
1. Determine TechnicalType from domain labels:
- Engineering/system/framework → ENG
- combat → ENG (sub: Combat)
- ai → ENG (sub: AI) or AI
- vfx → VFX
- ArtAnim → ART
- UXUI → UI
- level-design → LVL
- gameplay/game-design → GD
2. Determine SubType based on file paths or context:
- Plugins/Frameworks/* → Framework
- Combat systems → Combat
- AI systems → AI
- UI systems → UI
- Editor tools → Tools
- Content/S2/Core_VFX/Boss/* → Boss
- Content/S2/Core_Ene/* → Ene
3. Generate unique-name:
- Extract from branch name or user input
- Convert to kebab-case (lowercase, hyphens)
- Remove common prefixes (feature/, fix/, etc.)
Examples:
- Branch: feature/convert-resting-point-smartio
Labels: Engineering, system
→ task_S02_ENG_Framework_convert-resting-point-to-smartio
- Branch: fix/parry-timing-window
Labels: combat, Engineering
→ task_S02_ENG_Combat_fix-parry-timing-window
- Branch: feature/tiger-boss-vfx
Labels: vfx
→ task_S02_VFX_Boss_tiger-flame-attack
Fallback Format (if naming convention unclear):
[TASK-ID] Human Readable Title
Example: [ENG-FRAMEWORK-001] Convert Resting Point to SmartIO
Logic:
1. Summarize commit messages:
- Extract all commit subjects
- Group related commits
- Create cohesive 2-4 sentence summary
2. Add technical details:
- List key files modified (top 5 by lines changed)
- Note any new systems/plugins added
- Mention refactorings or deletions
Example:
"Implement Smart IO creator tool with behavior definitions. This adds
editor tooling for creating Smart Objects with modular behavior patterns.
Refactored SipherIOTypes to use class-based definitions instead of
struct-based approach.
Key changes:
- SSipherSmartObjectCreatorWindow.cpp (848 lines)
- SipherIOTypes.h/cpp (refactored)
- New state tree tasks for montage playback"
Format: ENG-{DOMAIN}-{NUMBER}
Logic:
1. Extract primary domain from labels:
- If "system" in labels → ENG-FRAMEWORK-{NUMBER}
- If "combat" in labels → ENG-COMBAT-{NUMBER}
- If "ui" in labels → ENG-UI-{NUMBER}
- Default → ENG-GENERAL-{NUMBER}
2. Suggest next available number:
- Query existing issues: gh issue list --label {domain} --json number
- Find max number, increment by 1
- If no existing issues → Start at 001
Example: ENG-FRAMEWORK-001
Logic:
1. Extract from commit messages:
- Each significant commit → One checkbox
- Focus on "what" not "how"
- Use action verbs (Implement, Add, Fix, Refactor)
2. Add standard criteria:
- "Code compiles successfully" (always)
- "Tests pass" (if test files in changes)
- "Documentation updated" (if public API changes)
Example:
- [ ] Smart Object creator window implemented
- [ ] Behavior definition system working
- [ ] State tree tasks updated
- [ ] Code compiles successfully
- [ ] Tests pass
Default: "None"
User will be prompted to specify if applicable
Logic:
1. Start with today's date
2. Add days based on size:
- XS → +2 days
- S → +3 days
- M → +5 days
- L → +7 days
- XL → +14 days
3. Format as YYYY-MM-DD
Logic:
1. Query available milestones:
gh api repos/{github.repo}/milestones --jq '.[] | "\(.number): \(.title)"'
2. Auto-select based on domain labels:
- If "combat" or "gameplay" in labels → {milestones.combat.name} ({milestones.combat.number})
- If "ai" in labels → {milestones.game_ai.name} ({milestones.game_ai.number})
- If "system" in labels → {milestones.game_ai.name} ({milestones.game_ai.number})
- If "vfx" or "ArtAnim" in labels → PRE-PROD: META (10)
- If "level-design" in labels → PRE-PROD: ENV (1)
- If "UXUI" in labels → PRE-PROD: META (10)
- Default → alpha (9)
3. Store milestone number (not title) for gh CLI
Example:
Labels: task, Engineering, system
Auto-detected Milestone: {milestones.game_ai.name} ({milestones.game_ai.number})
Logic:
1. Default project: "{project.fullname}" (number {github.project_number})
2. Project ID: {github.project_node_id}
3. After issue creation, add to project board:
gh project item-add {github.project_number} --owner {github.owner} --url {issue_url}
Display complete draft for review:
═══════════════════════════════════════
DRAFT ISSUE
═══════════════════════════════════════
Title: [ENG-FRAMEWORK-001] Smart IO Creator Tool
Description:
Implement Smart IO creator tool with behavior definitions. This adds
editor tooling for creating Smart Objects with modular behavior patterns.
Refactored SipherIOTypes to use class-based definitions instead of
struct-based approach.
Key changes:
- SSipherSmartObjectCreatorWindow.cpp (848 lines)
- SipherIOTypes.h/cpp (refactored)
- New state tree tasks for montage playback
Task ID: ENG-FRAMEWORK-001
Epic: N/A
Acceptance Criteria:
- [ ] Smart Object creator window implemented
- [ ] Behavior definition system working
- [ ] State tree tasks updated
- [ ] Code compiles successfully
Dependencies: None
Size: L (16-32 hours)
Estimated Hours: 24
Due Date: 2025-12-31
Labels: task, Engineering, system
Milestone: {milestones.game_ai.name} ({milestones.game_ai.number})
Project: {project.fullname}
═══════════════════════════════════════
Options:
1. Create issue with this draft
2. Edit specific fields
3. Cancel
Your choice (1/2/3): _
User Interaction:
If user chooses "2. Edit specific fields":
Which field to edit?
a. Title
b. Description
c. Task ID
d. Epic
e. Acceptance Criteria
f. Dependencies
g. Size/Hours
h. Due Date
i. Labels
j. Milestone
k. Project
l. Done editing, create issue
Your choice: _
For each field:
Validation Rules:
Before creating issue, ensure all labels exist:
# Get available labels
gh label list --json name --jq '.[].name'
Validation Logic:
Required Labels:
If no domain label:
No domain label detected. Please select:
a. Engineering
b. combat
c. vfx
d. UXUI
e. ArtAnim
f. gameplay
g. ai
h. level-design
i. documentation
Your choice: _
IMPORTANT: Use <br /> for line breaks and ** for headers per project guidelines.
Construct body using template-compliant formatting:
**Task Description**<br />
{Description from draft}
**Task ID**<br />
{Task ID}
**Epic**<br />
{Epic or "N/A"}
**Acceptance Criteria**<br />
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Code compiles successfully
**Dependencies**<br />
{Dependencies or "None"}
**Size & Effort**<br />
**T-Shirt Size:** {Size} ({Hours range})<br />
**Estimated Hours:** {Hours}
**Due Date**<br />
{YYYY-MM-DD}
**Additional Context**<br />
{Technical details, key files}
Example (Properly Formatted):
**Task Description**<br />
Convert the existing Resting Point implementation to use the SmartIO (Smart Interaction Object) framework.
**Task ID**<br />
ENG-FRAMEWORK-001
**Epic**<br />
SmartIO Framework Migration
**Acceptance Criteria**<br />
- [ ] Resting Point converted to SmartIO-based implementation
- [ ] Behavior definitions properly configured
- [ ] State Tree tasks updated for SmartIO consumption
- [ ] Existing functionality preserved
- [ ] Code compiles successfully
**Dependencies**<br />
None
**Size & Effort**<br />
**T-Shirt Size:** M (8-16 hours)<br />
**Estimated Hours:** 12
**Due Date**<br />
2026-01-12
**Additional Context**<br />
Part of the ongoing effort to migrate interaction objects to the SmartIO framework using the SipherInteractionObjectFramework plugin.
Formatting Rules:
**Section**<br /> for all section headers<br /> to separate sections- [ ] format (GitHub auto-renders)## headers in body (reserve for template parsing)Submit issue via gh CLI:
gh issue create \
--title "[ENG-FRAMEWORK-001] Smart IO Creator Tool" \
--body "$(cat <<'EOF'
## Task Description
Implement Smart IO creator tool with behavior definitions...
## Task ID
ENG-FRAMEWORK-001
...
EOF
)" \
--label "task,Engineering,system" \
--milestone 13 \
--repo {github.repo}
Important:
--milestone: Use milestone NUMBER (not title)Parse Output:
Example output: