一键导入
issue-work
Automate GitHub issue workflow - select issue, create branch, implement, build, test, and create PR.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Automate GitHub issue workflow - select issue, create branch, implement, build, test, and create PR.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Clean up merged and stale branches from local and remote repositories. Use when branch list is cluttered or after merging PRs.
Generate document index files (manifest, bundles, graph, router) for project documentation. Creates docs/.index/ with searchable registry, feature-grouped bundles, cross-reference dependency graph, and query routing. Supports flat mode (generic projects, script-driven) and grouped mode (projects with doc_id frontmatter, Claude-curated).
Comprehensive markdown document review - anchors, accuracy, SSOT, cross-references, and redundancy analysis.
Enforce complete implementation of all tiers/difficulty levels for tiered features. Prevents partial implementations.
Create well-structured GitHub issues using the 5W1H framework with proper labels and acceptance criteria.
Interactive review of stale, flagged, and duplicate memories from the latest audit report. Walks entries one at a time with verify / quarantine / edit / skip choices.
| name | issue-work |
| description | Automate GitHub issue workflow - select issue, create branch, implement, build, test, and create PR. |
| argument-hint | [project-name] [issue-number] [--solo|--team] [--limit N] [--dry-run] [--inline] [--wait-on-timeout] |
| user-invocable | true |
| disable-model-invocation | true |
| allowed-tools | Bash(gh *) |
| disallowed-tools | ["WebSearch","WebFetch","NotebookEdit"] |
| max_iterations | 10 |
| halt_conditions | [{"type":"success","expr":"CI all-green and PR merged"},{"type":"limit","expr":"3 identical build/CI failures in a row"}] |
| on_halt | Convert PR to draft, report failing checks, exit without merging |
| loop_safe | false |
| tiers | {"light":{"ref_docs":[],"deep_checks":false},"standard":{"ref_docs":["core"],"deep_checks":true},"deep":{"ref_docs":["core","advanced"],"deep_checks":true}} |
| default_tier | standard |
| iso_class | none |
Automate GitHub issue workflow with project name as argument.
/issue-work # Batch: all repos, all open issues
/issue-work vi_slam # Batch: all open issues in vi_slam
/issue-work vi_slam 21 # Single: work on issue #21
/issue-work vi_slam 21 --org mycompany # Explicit organization
/issue-work mycompany/vi_slam 21 # Full repo path format
/issue-work vi_slam 21 --solo # Force solo mode (sequential)
/issue-work vi_slam 21 --team # Force team mode (implementer + tester)
/issue-work --org mycompany # Batch: all repos in org
/issue-work vi_slam --limit 5 # Batch: top 5 priority issues
/issue-work vi_slam --dry-run # Preview batch plan only
/issue-work vi_slam --inline # Batch: process items in the parent context (legacy)
[project-name]: Project name or full repository path (optional)
<project-name> - auto-detect organization from git remote<project-name> --org <organization> - explicit organization<organization>/<project-name> - full repository path[issue-number]: GitHub issue number (optional)
[--solo|--team]: Execution mode override (optional)
--solo — Force solo mode for all items (single agent, sequential workflow)--team — Force team mode for all items (implementer + tester agents in parallel)[--limit N]: Maximum number of items to process in batch mode (default: 5, max: 10)
--force-large to acknowledge rule drift risk. Empirically, drift becomes visible around items 15-25 in long batches; the conservative default keeps batches inside the safe zone.[--force-large]: Allow --limit > 10. Required to bypass the safe-batch cap.
[--no-confirm]: Skip the chunked confirmation gate fired every 5 items in batch mode. Intended for CI-driven or fully unattended batches; interactive sessions should leave it off so the gate can serve as both a user-control checkpoint and an attention refresh for accumulated context.
[--auto-restart]: Force a session restart every CONFIRM_INTERVAL items instead of showing the interactive chunked gate. The batch writes .claude/resume.md using the Batch Workflow Resume Format and exits cleanly; a fresh claude session picks up the next item from the resume file. Use for long unattended batches where a full process-level attention reset per chunk matters more than human confirmation. Ignored in single-item mode.
[--no-restart]: Suppress the forced restart. When combined with --auto-restart, the batch falls back to the interactive chunked gate. Meaningful primarily as a defensive flag in scripts that want to guarantee no session exit even if --auto-restart is set elsewhere (aliases, wrappers, or a future default change).
[--dry-run]: Show batch plan only, do not execute
[--inline]: Process each batch item in the parent conversation context instead of delegating to a fresh subagent.
general-purpose Agent. The parent keeps only the queue state and a short per-item summary; gh outputs, build logs, and file reads live inside the subagent and are discarded on completion. This is the preferred mode for batches >3 items because rule compliance at item 30 looks like item 1.--inline: The parent executes Solo/Team workflow directly for every item. Lower token overhead (~10-15% savings) but accumulated tool results cause rule drift around items 15-25. Use for tiny batches (≤3 items) or when inter-item context is actually useful (e.g., fixing related regressions).[--priority <level>]: Filter batch to this priority level and above
critical, high, medium, low, all (default: all)[--wait-on-timeout]: On the CI-polling timeout (Step 9), ask the user whether to keep waiting instead of taking the default action. Default (omitted): when the 10-minute polling limit is reached with runs still pending, leave the PR open and print a resume command (pr-work <PR_NUM>) rather than blocking on a prompt. Pass this flag only when you want the interactive "wait longer?" question back.
Parse $ARGUMENTS and extract project, organization, issue number, and batch flags:
ARGS="$ARGUMENTS"
ISSUE_NUMBER="" PROJECT="" ORG="" EXEC_MODE=""
BATCH_MODE="single" BATCH_LIMIT=5 DRY_RUN=false PRIORITY_FILTER="all" FORCE_LARGE=false NO_CONFIRM=false INLINE_MODE=false AUTO_RESTART=false NO_RESTART=false WAIT_ON_TIMEOUT=false
MAX_LIMIT=10
CONFIRM_INTERVAL=5
# Extract flags
if [[ "$ARGS" == *"--solo"* ]]; then EXEC_MODE="solo"; ARGS=$(echo "$ARGS" | sed 's/--solo//g'); fi
if [[ "$ARGS" == *"--team"* ]]; then EXEC_MODE="team"; ARGS=$(echo "$ARGS" | sed 's/--team//g'); fi
if [[ "$ARGS" == *"--dry-run"* ]]; then DRY_RUN=true; ARGS=$(echo "$ARGS" | sed 's/--dry-run//g'); fi
if [[ "$ARGS" == *"--force-large"* ]]; then FORCE_LARGE=true; ARGS=$(echo "$ARGS" | sed 's/--force-large//g'); fi
if [[ "$ARGS" == *"--no-confirm"* ]]; then NO_CONFIRM=true; ARGS=$(echo "$ARGS" | sed 's/--no-confirm//g'); fi
if [[ "$ARGS" == *"--no-restart"* ]]; then NO_RESTART=true; ARGS=$(echo "$ARGS" | sed 's/--no-restart//g'); fi
if [[ "$ARGS" == *"--auto-restart"* ]]; then AUTO_RESTART=true; ARGS=$(echo "$ARGS" | sed 's/--auto-restart//g'); fi
if [[ "$ARGS" == *"--inline"* ]]; then INLINE_MODE=true; ARGS=$(echo "$ARGS" | sed 's/--inline//g'); fi
if [[ "$ARGS" == *"--wait-on-timeout"* ]]; then WAIT_ON_TIMEOUT=true; ARGS=$(echo "$ARGS" | sed 's/--wait-on-timeout//g'); fi
if [[ "$ARGS" =~ --limit[[:space:]]+([0-9]+) ]]; then BATCH_LIMIT="${BASH_REMATCH[1]}"; ARGS=$(echo "$ARGS" | sed -E 's/--limit[[:space:]]+[0-9]+//g'); fi
if [[ "$ARGS" =~ --priority[[:space:]]+(critical|high|medium|low|all) ]]; then PRIORITY_FILTER="${BASH_REMATCH[1]}"; ARGS=$(echo "$ARGS" | sed -E 's/--priority[[:space:]]+\w+//g'); fi
# Hard cap on batch size to mitigate rule drift in long batches.
# Drift becomes empirically visible around items 15-25; default 5 keeps the
# operator inside the safe zone, and bypassing requires explicit acknowledgment.
if (( BATCH_LIMIT > MAX_LIMIT )) && [[ "$FORCE_LARGE" != "true" ]]; then
echo "Error: --limit ${BATCH_LIMIT} exceeds safe cap of ${MAX_LIMIT}." >&2
echo "Long batches risk rule drift around items 15-25." >&2
echo "Either split the batch into smaller runs or pass --force-large to override." >&2
exit 1
fi
# Extract issue number if present (numeric argument)
if [[ "$ARGS" =~ [[:space:]]([0-9]+)([[:space:]]|$) ]]; then
ISSUE_NUMBER="${BASH_REMATCH[1]}"
ARGS=$(echo "$ARGS" | sed -E "s/[[:space:]]+${ISSUE_NUMBER}([[:space:]]|$)/ /g")
fi
ARGS=$(echo "$ARGS" | xargs)
# Helper: resolve ORG/PROJECT from remaining ARGS
resolve_org_project() {
if [[ "$ARGS" == *"--org"* ]]; then
PROJECT=$(echo "$ARGS" | awk '{print $1}')
ORG=$(echo "$ARGS" | sed -n 's/.*--org[[:space:]]*\([^[:space:]]*\).*/\1/p')
elif [[ "$ARGS" == *"/"* ]]; then
ORG=$(echo "$ARGS" | cut -d'/' -f1 | xargs)
PROJECT=$(echo "$ARGS" | cut -d'/' -f2 | xargs)
else
PROJECT="$ARGS"
cd "$PROJECT" 2>/dev/null || { echo "Error: Project directory not found: $PROJECT"; exit 1; }
ORG=$(git remote get-url origin 2>/dev/null | sed -E 's|.*[:/]([^/]+)/[^/]+\.git$|\1|' | sed -E 's|.*[:/]([^/]+)/[^/]+$|\1|')
fi
}
# Determine batch mode and resolve org/project
if [[ -z "$ARGS" && -z "$ISSUE_NUMBER" ]]; then
BATCH_MODE="cross-repo"
if [[ "$ARGS" == *"--org"* ]]; then
ORG=$(echo "$ARGS" | sed -n 's/.*--org[[:space:]]*\([^[:space:]]*\).*/\1/p')
fi
elif [[ -n "$ARGS" && -z "$ISSUE_NUMBER" ]]; then
BATCH_MODE="single-repo"
resolve_org_project
else
BATCH_MODE="single"
resolve_org_project
fi
https://github.com/$ORG/$PROJECT (single/single-repo modes)./$PROJECT$ISSUE_NUMBER (empty for batch modes)$BATCH_MODE (single, single-repo, or cross-repo)$BATCH_MODE == "single-repo" or $BATCH_MODE == "cross-repo" → Execute Batch Mode Instructions below$BATCH_MODE == "single" → Execute Phase 0: Execution Mode Selection (skip Batch Mode)See reference/batch-mode.md for the complete batch mode workflow including discovery, priority sorting, plan approval, and sequential execution.
Batch-only behaviors (do not apply in single-item mode):
general-purpose Agent so it starts with an unpolluted attention pool. The parent retains only {item_id, status, pr_url, ci_conclusion} per item. Pass --inline to fall back to the legacy single-context loop.--inline mode it is emitted directly in the parent context.@load: reference/... inside the per-item loop: keep the inline reminder as the most recent context anchor.--no-confirm. When --auto-restart is set (and --no-restart is not), the gate is replaced by a forced session restart that writes .claude/resume.md and exits; a fresh claude session resumes from the next item.Determine whether to run in Solo mode (single agent, sequential) or Team mode (implementer + tester agents in parallel).
--solo or --team flag was providedSkip mode selection — use $EXEC_MODE directly.
First, fetch issue information for size estimation (after Issue Selection in Step 1):
ISSUE_INFO=$(gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT \
--json title,body,labels -q '{title: .title, body: .body, labels: [.labels[].name]}')
Auto-recommend based on issue size:
| Signal | Solo (Recommended) | Team (Recommended) |
|---|---|---|
| Size label | size/XS, size/S | size/M, size/L, size/XL |
| Description length | < 500 chars | > 500 chars |
| Acceptance criteria | < 3 items | 4+ items |
| Subtask references | None | "Part of", checklist items |
Decisive signals → apply silently. When the signals are unambiguous (all point the same direction — e.g. size/XS/size/S → solo, size/L/size/XL → team), set $EXEC_MODE to the recommended mode WITHOUT asking and print a one-line notice, e.g. [Mode: solo — XS issue; pass --team to override] (or [Mode: team — L issue; pass --solo to override]). The user can still override with the --solo/--team flags handled in 0-1.
Conflicting signals → ask. Only when signals genuinely point in different directions (e.g. size/S label but 4+ acceptance criteria and "Part of" references) use AskUserQuestion to present the choice:
Store the result in $EXEC_MODE (solo | team).
$EXEC_MODE == "solo" → Execute Solo Mode Instructions (Steps 1-12 below)$EXEC_MODE == "team" → Execute Team Mode Instructions (after Solo Mode section)Execute the following workflow for the specified project:
If issue number is provided:
# Fetch specific issue
gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT --json number,title,state,labels
# Verify issue exists and is open
STATE=$(gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT --json state -q '.state')
if [[ "$STATE" != "OPEN" ]]; then
echo "Error: Issue #$ISSUE_NUMBER is not open (state: $STATE)"
exit 1
fi
If issue number is NOT provided:
# Auto-select by priority
gh issue list --repo $ORG/$PROJECT --label "priority/critical" --state open --limit 1
# If none found:
gh issue list --repo $ORG/$PROJECT --label "priority/high" --state open --limit 1
# If none found:
gh issue list --repo $ORG/$PROJECT --label "priority/medium" --state open --limit 1
Select the oldest (first created) issue from the results.
Store the selected issue number in $ISSUE_NUMBER variable.
Analyze the issue and determine size:
| Size | Expected LOC | Action |
|---|---|---|
| XS/S | < 200 | Proceed directly |
| M | 200-500 | Consider splitting into 2-3 sub-issues |
| L/XL | > 500 | Must split into sub-issues, work on first |
If splitting required:
Part of #ORIGINAL referencecd $PROJECT
git fetch origin
git checkout develop && git pull origin develop
# Extract issue title for branch name
ISSUE_TITLE=$(gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT --json title -q '.title')
# Convert to kebab-case (lowercase, replace spaces with hyphens)
SHORT_DESC=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g' | sed -E 's/^-+|-+$//g' | cut -c1-50)
# Determine branch type from issue labels
LABELS=$(gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT --json labels -q '.labels[].name')
if echo "$LABELS" | grep -q "type/feature"; then
BRANCH_TYPE="feat"
elif echo "$LABELS" | grep -q "type/bug"; then
BRANCH_TYPE="fix"
elif echo "$LABELS" | grep -q "type/refactor"; then
BRANCH_TYPE="refactor"
elif echo "$LABELS" | grep -q "type/docs"; then
BRANCH_TYPE="docs"
else
BRANCH_TYPE="feat" # Default
fi
BRANCH_NAME="${BRANCH_TYPE}/issue-${ISSUE_NUMBER}-${SHORT_DESC}"
git checkout -b "$BRANCH_NAME"
gh issue edit <NUMBER> --repo $ORG/$PROJECT --add-assignee @me
Priority: Start implementation immediately. Minimize upfront planning — analyze code as you implement, not in a separate planning phase.
Analyze existing code style:
.clang-format, .editorconfig if presentImplement changes:
Header file review (C/C++ projects):
Commit per logical unit:
type(scope): descriptionCLAUDE_CONTENT_LANGUAGE policy resolved from commit-settings.md (default english; supports korean_plus_english, exclusive_bilingual, any). Do not assume English-only.Follow the build verification workflow rule (build-verification.md) to select the
appropriate strategy based on expected build duration.
Before running local builds, verify required toolchains are installed:
# Check availability — do NOT install without asking the user
command -v go &>/dev/null # Go
command -v cargo &>/dev/null # Rust
command -v cmake &>/dev/null # C++
command -v npm &>/dev/null # Node.js
If toolchain is unavailable: Skip local build verification and rely on CI. Do NOT attempt to install toolchains without asking the user first. Report what was verified locally vs what needs CI.
| Build System | Typical Duration | Strategy |
|---|---|---|
go build / cargo check | < 30s | Inline (synchronous) |
cmake --build / gradle build | 30s - 5min | Background + log polling |
ctest / pytest (large suites) | 1 - 10min | Background + log polling |
CI pipeline (gh workflow run) | 5min+ | CI log check |
For builds expected under 30 seconds:
Bash(command="go build ./...", timeout=60000)
Bash(command="cargo check", timeout=60000)
For builds expected over 30 seconds:
Bash(command="cmake --build build/ ...", run_in_background=true)TaskOutput(task_id="<id>", block=false, timeout=10000)Built target/Finished = success, error:/FAILED = fix neededBash(command="ctest --test-dir build/ ...", run_in_background=true)Do NOT retry the same build without changes -- diagnose first.
Update relevant documentation if applicable:
Commit separately:
docs(scope): update documentation for <feature>
git push -u origin "$BRANCH_NAME"
gh pr create --repo $ORG/$PROJECT \
--title "${BRANCH_TYPE}(scope): description" \
--body "Closes #${ISSUE_NUMBER}
## Summary
- Brief description of changes
## Test Plan
- How to verify the changes"
Required:
Closes #<NUMBER> keyword to link issueCLAUDE_CONTENT_LANGUAGE policy (see commit-settings.md). PR title and description must each comply with the per-artifact rule of the resolved policy; under exclusive_bilingual, each artifact must be wholly English-only or wholly Korean-only.commit-settings.md)After PR creation, capture the PR URL from gh pr create output for the summary.
After PR creation, monitor CI with non-blocking polling:
# Wait briefly for workflows to register
sleep 8
Poll all PR checks every 30 seconds, max 10 minutes:
gh run list --repo $ORG/$PROJECT --branch "$BRANCH_NAME" \
--json databaseId,name,status,conclusion
Decision table — apply per run, evaluate ALL runs each poll cycle:
| All runs status | Any conclusion=failure | Action |
|---|---|---|
All completed | No | All pass → proceed to merge |
All completed | Yes | Diagnose, fix, push, re-poll |
Any in_progress or queued | — | Poll again after 30s |
Merge gate: Do NOT merge until every run shows status: completed.
A run that is in_progress or queued is NOT a passing run — wait for it.
Timeout: If 10-minute polling limit is reached and any run is still
in_progress or queued, stop polling, report the current status table
to the user, and do NOT merge.
Default (no --wait-on-timeout): leave the PR open and print a resume
command so CI can finish unattended:
[CI still running after 10 min — leaving PR open. Resume with: pr-work $PR_NUMBER]
Do not block on a prompt. Only when --wait-on-timeout was passed, ask the
user whether to wait longer or leave the PR open for manual merge. This
mirrors the ci-fix timeout behavior of defaulting to a resumable hand-off
rather than an interactive stall.
Do NOT use gh run watch — it blocks the entire session.
On CI failure, fix the issue and push. Repeat up to 3 attempts. After 3 failures, convert the PR to draft, report the status, and do NOT proceed to merge or produce a completion summary. The task is NOT complete until all CI checks pass and the PR is merged.
ABSOLUTE CI GATE — MANDATORY PRE-MERGE VERIFICATION:
Before executing gh pr merge, you MUST run gh pr checks and verify every single check:
gh pr checks $PR_NUMBER --repo $ORG/$PROJECT
Do NOT merge if ANY check shows:
fail or failure conclusion (regardless of perceived cause)pending, queued, or in_progress statuscancelled, timed_out, or startup_failure conclusionALL checks must show pass or neutral to proceed. No exceptions. No rationalization.
Never judge a failure as "unrelated", "pre-existing", or "infrastructure-only" — all failures block merge.
If any check is not passing, STOP. Do NOT proceed to merge. Instead:
gh pr checks output to the userOnly when ALL checks pass:
gh pr merge $PR_NUMBER --repo $ORG/$PROJECT --squash --delete-branch
If merge fails (e.g., review required), report the status and skip merge.
After merge:
# Verify the linked issue was closed by the merge
STATE=$(gh issue view $ISSUE_NUMBER --repo $ORG/$PROJECT --json state -q '.state')
if [[ "$STATE" != "CLOSED" ]]; then
gh issue close $ISSUE_NUMBER --repo $ORG/$PROJECT
fi
Epic closure: If the issue references a parent epic (e.g., Part of #N),
check if all sub-issues of that epic are now closed. If so, close the epic
with a summary comment.
IMPORTANT: Issue comments must comply with the active CLAUDE_CONTENT_LANGUAGE policy (resolved from commit-settings.md; default english). Do not hard-code "English only" — under exclusive_bilingual a Korean-only comment is valid, and under korean_plus_english mixed inline is valid.
gh issue comment <NUMBER> --repo $ORG/$PROJECT \
--body "Implementation PR: #<PR_NUMBER>"
See reference/team-mode.md for the complete team mode workflow with 3-team architecture (dev, reviewer, doc-writer), feedback loops, and cleanup.
See _policy.md for common rules, including the Atomic Multi-Phase Execution rule — when the user specifies multiple phases (e.g., "Phase 1/2/3"), complete all phases without pausing between them for confirmation.
| Item | Rule |
|---|---|
| Language | All issue comments, PR titles, PR descriptions, and commit messages follow the active CLAUDE_CONTENT_LANGUAGE policy (see commit-settings.md) |
| Issue linking | Closes #NUM required in PR |
| Build verification | Must pass before PR creation |
CRITICAL: Do NOT produce a completion summary if CI has any failing, pending, or incomplete checks. A task is only complete when the PR is merged with all CI checks passing.
After successful merge, provide summary:
## Work Summary
| Item | Value |
|------|-------|
| Repository | $ORG/$PROJECT |
| Issue | #$ISSUE_NUMBER - Title |
| Branch | $BRANCH_NAME |
| Execution mode | Solo / Team |
| PR | [#PR_NUMBER](https://github.com/$ORG/$PROJECT/pull/PR_NUMBER) |
| CI Status | All checks passed |
| Merged | Yes |
| Commits | N commits |
### Changes Made
- List of changes
### Files Modified
- file1.cpp
- file2.h
### Next Steps
- Any follow-up items
If CI failed or the PR was not merged, use this format instead:
## Work Summary (INCOMPLETE)
| Item | Value |
|------|-------|
| Repository | $ORG/$PROJECT |
| Issue | #$ISSUE_NUMBER - Title |
| Branch | $BRANCH_NAME |
| PR | [#PR_NUMBER](https://github.com/$ORG/$PROJECT/pull/PR_NUMBER) |
| CI Status | FAILING — [list failed checks] |
| Merged | No |
| Reason | [CI failure / Max retries exceeded / Timeout] |
### Action Required
- User must resolve CI failures before merge
IMPORTANT: Always include the full PR URL in the output (e.g., https://github.com/org/repo/pull/123).
In batch mode, use the summary format from Phase B-5 instead. Include per-item results and the overall success/failure count.
See reference/error-handling.md for prerequisite checks, runtime errors, and batch mode errors.
This skill is loop_safe: false. Each invocation creates branches, opens or advances pull requests, and posts comments against live GitHub issues. Wrapping it in /loop would re-trigger work on already-handled issues and create duplicate branches/PRs. The exit contract is "one resolved issue (or batch) per invocation," not a no-side-effect retry — resume an interrupted run from the documented session-resume state rather than re-running blindly.