| name | issue-fixer |
| description | End-to-end automation: discover open-source GitHub repos, find fixable issues, analyze difficulty, fork/clone, implement fixes with self-testing, and submit merge-ready PRs. Supports two modes: target a specific repo/issue, or auto-discover active projects by domain (Linux, systems, CLI, etc.). Use when the user says "fix issue", "help me contribute", "find issues to fix", "auto-fix", "hunt for issues", "search repos and fix issues", "帮我去github找issue修", or references a GitHub issue/URL that should be resolved. Also use when the user wants to contribute to open-source but doesn't know where to start. Make sure to use this skill whenever the user mentions GitHub issues, PRs, open-source contribution, or finding bugs to fix in external repos, even if they don't explicitly invoke the skill name.
|
| user-invocable | true |
| argument-hint | [repo-name | issue-URL | --discover <domain> | --hunt] |
Issue Fixer
Full automation from discovering open-source GitHub issues to submitting merge-ready PRs.
When to use
- "Fix issue #123 in owner/repo"
- "Help me find issues to fix in Linux projects"
- "Search GitHub for open-source repos and fix an issue"
- "帮我去github找一些Linux系统库的issue来修"
- "Go hunt for good first issues"
- "Contribute to this project" (when pointing at a GitHub repo)
- Any GitHub issue URL pasted with intent to resolve
Input modes
$ARGUMENTS determines the entry point:
| Input | Mode | Example |
|---|
owner/repo | Target repo — find and fix an issue | issue-fixer htop-dev/htop |
owner/repo#42 or URL | Target issue — fix this specific issue | issue-fixer htop-dev/htop#1838 |
https://github.com/.../issues/42 | Target issue from URL | issue-fixer https://... |
--discover <domain> | Discover repos, then fix | issue-fixer --discover linux |
--hunt | Fully autonomous discovery + fix | issue-fixer --hunt |
| (none) | Interactive — ask user what they want | issue-fixer |
Preflight
Before any phase, verify the environment:
gh auth status — GitHub CLI authenticated
git --version — Git available
- Write permission to the working directory for clones/worktrees
If any check fails, report the blocker and stop.
Phase 0: Repo Discovery (only for --discover / --hunt)
Discover active, well-known open-source repos matching a domain. Read references/repo-discovery.md for domain templates and command details.
Discovery query
Build a gh search repos query based on the domain template. The domain argument maps to topic + language + star thresholds.
gh search repos \
--topic=linux \
--language=c \
--stars=">=500" \
--archived=false \
--sort=updated \
--limit=20 \
--json fullName,stargazersCount,openIssuesCount,updatedAt,description \
| jq '[.[] | select(.openIssuesCount >= 5)]'
Output: candidate list
Present the user with a numbered list:
# | Repo | Stars | Open Issues | Updated
---|------------------------|-------|-------------|--------
1 | htop-dev/htop | 8,095 | 344 | 2h ago
2 | i3/i3 |10,474 | 362 | 1d ago
3 | AppImage/AppImageKit | 9,344 | 236 | 4h ago
Ask the user to pick one (or --hunt mode auto-selects the top candidate).
If no repos found, try broadening: lower star threshold, remove topic filter, or try adjacent topics from references/repo-discovery.md.
Phase 1: Issue Discovery
Find fixable issues in the target repo.
Search strategy
Try these in order, stop when sufficient candidates found (≥ 3 issues):
-
Labeled issues — repos with "good first issue" / "help wanted" labels:
gh search issues --repo="$REPO" --label="good first issue" --state=open \
--json number,title,url,labels,updatedAt,body --limit=10
-
Unlabeled but fixable — keyword search for common fixable patterns:
gh search issues --repo="$REPO" --state=open --no-assignee \
--sort=updated --limit=10 \
--json number,title,url,labels,updatedAt,body
-
Cross-label search — try alternative labels:
for label in "help wanted" "beginner friendly" "up for grabs" "documentation" "enhancement"; do
gh search issues --repo="$REPO" --label="$label" --state=open --limit=5 \
--json number,title,url,labels,updatedAt
done
Filter criteria
Keep issues that pass ALL of these:
- No assignee — unassigned issues are available. Use
--json and jq to filter: | jq '[.[] | select(.assignees == [])]'
- Not locked — skip locked conversations
- Recent activity — updated within last 90 days
- Has enough context — body ≥ 50 characters or has comments
- Not a meta issue — skip "track X", "epic", "meta" titles
- Not already PR'd — check if a PR already references this issue number
Output: issue candidates
Present filtered issues as a table:
# | Issue | Labels | Age | Summary (first line of body)
---|-------|--------|-----|-------------------------------
1 | #1838 add fan speed | good first issue | 2d | Add an option to display...
2 | #1991 No UI feedback... | good first issue | 19d | This is a UX issue...
If $ARGUMENTS specified a specific issue, skip discovery and go directly to Phase 2 with that issue.
Phase 2: Difficulty Analysis
Assess whether the issue is realistically fixable. Read references/difficulty-analysis.md for the full scoring rubric.
Quick assessment
For each candidate issue, analyze these dimensions:
| Dimension | Trivial/Easy | Moderate | Hard |
|---|
| Scope | 1-2 files | 3-5 files | 6+ files or architecture |
| Familiarity | Common pattern (null check, typo, docs) | Requires reading codebase | Domain-specific knowledge |
| Testability | Clear repro steps | Can write a test | No clear test strategy |
| Risk | Isolated change | Touches shared code | Could break other things |
Decision
- Trivial / Easy → proceed automatically
- Moderate → present analysis, ask user to confirm
- Hard → skip with explanation ("This issue requires significant domain knowledge / architectural changes. Recommend a simpler issue first.")
Output
For the selected issue, produce a brief plan:
Issue: #1838 add fan speed display
Difficulty: Easy (2-3 files, well-defined scope, clear test path)
Approach: Add fan_speed field to ProcessField, wire up reading from /sys/class/hwmon
Files likely affected: linux/LinuxProcess.c, htop/ProcessField.c, htop/ListItem.c
Estimated: 1-2 hours
Phase 3: Fork & Clone
Set up an isolated working environment.
Permission check
PERMISSION=$(gh repo view "$REPO" --json viewerPermission --jq '.viewerPermission')
WRITE / TRIAGE / ADMIN → you're a collaborator, clone directly
READ → external contributor, fork first
Fork (if needed)
First check if a fork already exists:
FORK_EXISTS=$(gh repo view "$GITHUB_USER/$(basename $REPO)" --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null)
if [ -n "$FORK_EXISTS" ]; then
gh repo clone "$GITHUB_USER/$(basename $REPO)"
cd "$(basename $REPO)"
git remote add upstream "https://github.com/$REPO.git" 2>/dev/null
git fetch upstream
else
gh repo fork "$REPO" --clone --default-branch-only
fi
This handles:
- Fork the upstream repo to your GitHub account
- Clone the fork as
origin
- Set the upstream repo as
upstream remote
- Fetch latest upstream changes
- Check out the default branch
Direct clone (if collaborator)
gh repo clone "$REPO"
cd "$(basename $REPO)"
Create working branch
Use git worktree for isolation — don't pollute the main clone:
BRANCH="fix/issue-$ISSUE_NUM-$(echo $ISSUE_TITLE | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd 'a-z0-9-' | head -c 40)"
if git remote get-url upstream &>/dev/null; then
git fetch upstream
BASE_BRANCH="upstream/$(git symbolic-ref refs/remotes/upstream/HEAD --short 2>/dev/null | sed 's|upstream/||' || echo main)"
else
git fetch origin
BASE_BRANCH="origin/main"
fi
git worktree add ".worktrees/issue-$ISSUE_NUM" -b "$BRANCH" "$BASE_BRANCH"
Read project context
Before writing any code, read repo instruction files that define project conventions:
for f in AGENTS.md CLAUDE.md CONTRIBUTING.md README.md; do
[ -f "$WORKTREE/$f" ] && echo "=== $f ===" && head -100 "$WORKTREE/$f"
done
Also check for:
DCO (Developer Certificate of Origin) requirements
Signed-off-by commit trailer expectations
Phase 4: Analyze & Fix
Understand the codebase, implement the fix, and verify it.
Step 1: Study the existing PR style
Analyze recently merged PRs to match the project's conventions. Read references/pr-convention-analyzer.md for details.
gh pr list --repo="$REPO" --state=merged --limit=5 \
--json number,title,body,headRefName
Step 2: Root cause analysis
- Read the issue body and comments thoroughly
- Search the codebase for relevant files and functions
- Trace the data flow — understand how the bug manifests
- Identify the minimal change that fixes the issue
- Do NOT refactor adjacent code, do NOT add features beyond the issue scope
Step 3: Implement the fix
- Make the smallest possible change that resolves the issue
- Follow the project's coding style (indentation, naming, patterns)
- If the issue mentions a specific file or function, start there
Step 4: Write/update tests
This is non-negotiable. A fix without a test is not a fix.
- If the issue has clear repro steps → translate to a test
- If the project has existing tests → add a test case following the same pattern
- If no test framework → at minimum verify the fix manually with a concrete reproduction
Step 5: Self-verify
Run the fix through the project's quality gate (see Phase 5). Do NOT commit until Phase 5 passes. If tests pass locally, proceed to Phase 6 for commit and push.
Phase 5: Quality Gate
Run the project's own quality checks before pushing. This catches what CI would catch 3-5 minutes later.
Detect the gate, in this order:
- Repo instruction files (
CLAUDE.md, AGENTS.md, CONTRIBUTING.md). If one documents a quality-gate command, use it.
- Lockfile + scripts for Node:
bun.lock → bun, pnpm-lock.yaml → pnpm, yarn.lock → yarn, package-lock.json → npm. Read package.json scripts for check, check-types, build, test.
- Other ecosystems:
Makefile / configure.ac / meson.build → make check / make test
Cargo.toml → cargo check && cargo clippy && cargo test
go.mod → go vet ./... && go test ./...
CMakeLists.txt → cmake --build build && ctest --test-dir build
- Python
pyproject.toml → ruff check && pytest
- Fallback: ask the user what the gate is.
Fix loop
If any check fails:
- Read the error output carefully
- Fix the root cause — not the symptom
- Commit the fix as a separate conventional commit (
fix(lint): ..., fix(test): ...)
- Re-run until all checks pass
Do NOT suppress errors with as any, @ts-ignore, or equivalent. Do NOT skip failing tests.
Phase 6: Push & PR
Commit
Get the GitHub username and use conventional commits matching the project's style:
GITHUB_USER=$(gh api user --jq '.login')
git add -A
git commit -s
Do NOT add any AI-related identification — no Co-Authored-By AI trailers, no "Assisted-by", no "AI-generated" labels. Commits and PRs must appear as if written by a human contributor.
Push
git push -u origin "$BRANCH"
Never force-push. If the push fails due to remote changes, pull/rebase first.
Create PR
Always create a draft PR — it avoids accidental merge and signals "work in progress" to reviewers.
cat > /tmp/pr-body.md << 'EOF'
- <bullet point describing the fix>
| File | Change |
|------|--------|
| `path/to/file` | What was changed |
- [ ] <test that was added or run>
- [ ] <manual verification step>
Fixes
EOF
if [ "$PERMISSION" = "READ" ]; then
gh pr create --repo="$REPO" --head="$GITHUB_USER:$BRANCH" \
--base main \
--title "fix(<scope>): <description>" \
--body-file /tmp/pr-body.md --draft
else
gh pr create --repo="$REPO" \
--title "fix(<scope>): <description>" \
--body-file /tmp/pr-body.md --draft
fi
CI & Review loop
After creating the PR, monitor CI and handle reviewer feedback:
- Reviewer-first invariant: After every push, check for reviewer comments before waiting on CI
- CI monitoring:
gh pr checks --watch for the PR
- If CI fails: Read logs with
gh run view {run_id} --log-failed, fix root cause, push
- If review feedback: Classify as fix/false-positive/out-of-scope, address fixes, reply on threads
- Sync with upstream: Periodically
git fetch upstream && git merge upstream/main
- Max retries: 3 rounds of CI fix attempts. After 3 failures, escalate to user
Done condition
The PR is ready when:
- No new actionable comments
- No unresolved review threads
- All CI checks passing
- Branch synced with target
- GitHub reports PR as mergeable
Two consecutive clean checks. Do NOT merge — that's the user's call.
Cleanup
After the PR is submitted and passing CI:
git worktree remove ".worktrees/issue-$ISSUE_NUM"
Safety guardrails
These protect both the target project and the contributor's reputation:
- Never commit to
main — always work on a feature branch
- Never force-push — use
--force-with-lease only if explicitly asked
- Never delete tests — fixing failing tests by deleting them is forbidden
- Max 15 files changed — if the fix touches more, stop and ask
- Security issues → guided mode — vulnerabilities, auth bypass, injection always require human oversight
- Database migrations → guided mode — schema changes need review
- Draft PR by default — never create a ready-to-merge PR without explicit user consent
- Never add AI identification — no
Co-Authored-By: AI, Assisted-by, or any mention of AI tools in commits, PRs, or any output. All contributions must appear as human-written.
- Respect CLA/DCO — if the project requires a Contributor License Agreement, inform the user before submitting