next

Installation
SKILL.md

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 error object — 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_resolvedtrue if all blockers are closed (not in the open issue set)
  • unblockedtrue if no open blockers remain
  • age_days — days since issue creation
  • milestone_due_on — milestone due date (ISO 8601) or null
  • dependency_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_by array
  • blocks[issue] → Set<issue> — from each issue's .blocks array

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:

  1. Report each cycle: e.g., "#12 → #15 → #12"
  2. Warn the user that these issues are mutually blocked
  3. Exclude all issues in cycles from recommendations
  4. 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 (.assignees is empty), unless --include-assigned was used
  • It is not in a cycle (from Step 3)

Scoring formulaTotal = Σ (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:

  1. Show the full issue details (gh issue view ISSUE_NUMBER)
  2. Ask: "Want me to assign this to you?"
  3. If yes:
    gh issue edit ISSUE_NUMBER --add-assignee @me
    
  4. Suggest: "Run /pm:update periodically to audit stale issues."
Related skills
Installs
1
GitHub Stars
8
First Seen
Apr 20, 2026