next
Next: Issue Triage & Recommendation
Analyze open GitHub issues, build a dependency graph, and recommend the highest-impact issue to work on next.
Workflow
1. Fetch & Pre-process → 2. Build Dependency Graph → 3. Detect Cycles
→ 4. Rank Issues → 5. Present Recommendations → 6. Select & Assign
Step 1: Fetch and Pre-process Issues
Run the open-issues.sh script from the plugin's scripts/ directory (two levels up from this skill):
# Auto-detect repository from current directory
sh ../../scripts/open-issues.sh
# Or specify repository explicitly
sh ../../scripts/open-issues.sh OWNER/REPO
# Include assigned issues in results
sh ../../scripts/open-issues.sh --include-assigned
Validate the response:
- Check stderr for a JSON
errorobject — if present, abort with the error message (auth failures, missing tools, repo detection failures are handled by the script) - Extract and store the full JSON output as
$ISSUES_DATA
Edge case — no issues: If .total_open == 0, report "No open issues found" (if --include-assigned was used) or "No unassigned issues found (try --include-assigned to include assigned items)" (default mode) and stop.
Edge case — 100+ issues: If .total_open >= 100, warn: "Results capped at 100 issues. Consider filtering by label or milestone for a broader view."
The JSON output contains pre-computed fields for each issue:
blocked_by,blocks— parsed from issue body patterns (Blocked by:,Blocks:,Depends on:)blockers_resolved—trueif all blockers are closed (not in the open issue set)unblocked—trueif no open blockers remainage_days— days since issue creationmilestone_due_on— milestone due date (ISO 8601) ornulldependency_graph.edges—[[blocker, blocked], ...]pairs for graph analysis
Step 2: Build Dependency Graph
The script pre-computes blocked_by and blocks arrays per issue, and provides dependency_graph.edges as [[blocker, blocked], ...] pairs.
Build two maps from the pre-computed data:
blockedBy[issue] → Set<issue>— from each issue's.blocked_byarrayblocks[issue] → Set<issue>— from each issue's.blocksarray
Blocker resolution is already handled by the script via blockers_resolved/unblocked; the blocked_by/blocks arrays still list all referenced issues (including closed ones). Use the unblocked flag to determine eligibility.
Edge case — no dependency markers found: If dependency_graph.edges is empty, skip Step 3 (no cycles possible) and omit the "blocks others" dependency weight factor from Step 4 ranking. Rank purely on priority, type, age, and milestone.
Step 3: Detect Circular Dependencies
Using dependency_graph.edges from Step 1, run DFS traversal on the blockedBy graph to detect cycles.
If cycles found:
- Report each cycle: e.g., "#12 → #15 → #12"
- Warn the user that these issues are mutually blocked
- Exclude all issues in cycles from recommendations
- Suggest the user resolve the cycle by editing one of the issues
If no cycles: Proceed to ranking.
Step 4: Rank Unblocked Issues
An issue is eligible if:
unblocked == true(all blockers are resolved — pre-computed by the script)- It is not assigned to anyone (
.assigneesis empty), unless--include-assignedwas used - It is not in a cycle (from Step 3)
Scoring formula — Total = Σ (Weight × Score) for each factor:
| Factor | Weight | Score | Notes |
|---|---|---|---|
| Blocks others | 3 | +3 per issue this unblocks | e.g., unblocks 2 → 3 × 6 = 18 |
| Priority label | 2 | P0=8, P1=6, P2=4, P3=2, none=3 | none > P3: unlabeled may be anything; explicitly-low is known-low |
| Type label | 1 | bug=5, security=5, enhancement=3, chore=2, research=1, none=2 | Default none=2 — treat unlabeled same as chore |
| Age | 1 | +1 per 7 days (use age_days from Step 1, max +8) |
Caps at 56 days to avoid age dominating |
| Milestone | 1 | +4 / +2 / 0 (see below) | Heuristic below for "current/next" detection |
Milestone heuristic: Compare milestone due_on dates. The milestone with the earliest future (or most recently past) due date is "current"; the next one is "next" — these score +4. All other milestones score +2. Milestones without due_on default to +2. No milestone = 0.
Sort by total score descending. Break ties by issue number (lower = older = first).
Step 5: Present Recommendations
Show the top 3-5 issues in a structured table:
## Recommended Next Issues
| Rank | Issue | Title | Score | Key Factor |
|------|-------|-------|-------|------------|
| 1 | #42 | Fix auth token refresh | 24 | Unblocks #43, #44, #45 |
| 2 | #38 | Add rate limiting | 18 | P0-critical, 3 weeks old |
| 3 | #51 | Update CI pipeline | 14 | Blocks #52, in v2.0 milestone |
For each recommendation, show a brief rationale:
- What makes it high-priority
- What it unblocks (if anything)
- How old it is
- Any milestone context
Edge case — all issues are assigned: Report that all eligible issues have assignees. Show the top 3 anyway with their current assignees, and ask if the user wants to pick one up regardless.
Edge case — all issues are blocked: Report the blocking chain. Identify the root blockers (issues that block others but aren't blocked themselves) and recommend those first.
Step 6: Interactive Selection
Use AskUserQuestion to let the user choose:
Question: "Which issue do you want to work on?"
Options:
- #42: Fix auth token refresh (Score: 24)
- #38: Add rate limiting (Score: 18)
- #51: Update CI pipeline (Score: 14)
- Show more issues
After selection:
- Show the full issue details (
gh issue view ISSUE_NUMBER) - Ask: "Want me to assign this to you?"
- If yes:
gh issue edit ISSUE_NUMBER --add-assignee @me - Suggest: "Run
/pm:updateperiodically to audit stale issues."
More from rube-de/cc-skills
doppler
>-
33council
Consult external AI council (Gemini, Codex, Qwen, GLM-5.1) for thorough reviews and consensus-driven decisions. Use ONLY when explicitly invoked with "/council" or when user says "consult the council", "invoke council", or "council review". Do NOT auto-trigger on generic phrases like "thorough review".
2update
>-
1perf
>-
1dlc
>-
1temporal
>-
1