Skip to main content
ClaudeWave
Skill596 repo starsupdated 3d ago

fix-issues

|

Install in Claude Code
Copy
git clone --depth 1 https://github.com/FerroxLabs/wayland /tmp/fix-issues && cp -r /tmp/fix-issues/.claude/skills/fix-issues ~/.claude/skills/fix-issues
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Fix Issues Skill

Automated workflow: GitHub bug issues → analyze → fix → PR.

**Announce at start:** "I'm using fix-issues skill to find and fix a GitHub bug issue."

## Operating Modes

### Batch Mode (default)

Invocation: `/fix-issues`

- Fetches open bug issues, finds the best candidate, fixes it
- Runs full Phase 1 → Phase 2 → Phase 3
- Fixes 1 issue per invocation

### Daemon Mode

Invocation: `/fix-issues limit=1` (from daemon script)

- Phase 1 uses **priority descent**: high-signal issues first, then progressively lower
- Fixes only 1 issue (controlled by `limit` parameter), then exits
- If no fixable issue exists → outputs `[NO_FIXABLE_ISSUES]` and exits

## Prerequisites

- **gh CLI** must be authenticated
- Working directory will be auto-cleaned (stash + checkout main) at startup

## Workflow

### Phase 1: Collect & Filter Issues

#### Step 1.1: Verify Environment

```bash
git status --porcelain
git branch --show-current
```

If working directory has **staged or modified tracked files**, stash them and proceed:

```bash
git stash -m "fix-issues: auto-stash before starting"
```

**Do NOT use `--include-untracked`** - untracked files (like skill files not yet merged to main)
must remain in the working directory.

Then switch to main:

```bash
git checkout main
git pull origin main
```

#### Step 1.1b: Load Skip List (Daemon Mode Only)

In daemon mode (`limit > 0`), load the skip list to avoid re-analyzing issues that were already
triaged in previous sessions. The skip list is stored at:

```
~/.wayland-fix-issues/skip-list.json
```

Format:

```json
{
  "1782": { "reason": "already_fixed", "summary": "PR #1800 merged" },
  "1707": { "reason": "environment_issue", "summary": "Kaspersky antivirus blocking" },
  "1697": {
    "reason": "needs_more_info",
    "summary": "Missing reproduction steps",
    "commented_at": "2026-03-27T12:00:00Z"
  },
  "1774": {
    "reason": "fix_failed",
    "summary": "Type check failed after 3 attempts",
    "commented_at": "2026-03-27T14:00:00Z"
  }
}
```

Entries **never expire**. Re-analysis is triggered only by concrete signals.

**On load:**

1. Read the file (if it doesn't exist, start with an empty skip list)
2. All entries remain active (no expiry logic)

**During Phase 1.2 (Fetch Issues):**

When iterating through fetched issues, if an issue number is in the active skip list,
check whether re-analysis is warranted based on the reason:

| Reason              | Re-analyze condition                                | How to check                                     |
| ------------------- | --------------------------------------------------- | ------------------------------------------------ |
| `needs_more_info`   | New comment on issue since `commented_at`           | `gh api` check (see below)                       |
| `fix_failed`        | New comment on issue since `commented_at`           | `gh api` check (see below)                       |
| `already_fixed`     | Issue was **reopened** (state changed back to open) | Already filtered by `--state open` in fetch      |
| `fix_pending_merge` | Linked PR was **closed without merge**              | `gh pr list --state closed --search "<keyword>"` |
| `environment_issue` | **Always** - re-run Classification Gate (Grep)      | Run Step 1.4 gate on every `environment_issue`   |
| `unclear_unfixable` | **Always** - re-run Classification Gate (Grep)      | Run Step 1.4 gate on every `unclear_unfixable`   |

**Re-analysis for `environment_issue` / `unclear_unfixable` (MANDATORY):**

These classifications are error-prone and must be re-verified every session. For each
`environment_issue` or `unclear_unfixable` entry in the skip list:

1. Extract keywords from the skip-list `summary` field
2. Run `Grep` against `src/` with those keywords
3. If matching code is found → **remove from skip list and re-analyze** as `direct_fix` or `defensive_fix`
4. If no matching code → keep in skip list

This prevents misclassifications from becoming permanent. The Grep check is cheap and
ensures issues with code paths in our repo are never permanently skipped.

**Comment check for `needs_more_info` / `fix_failed`:**

First, get the authenticated user login (the bot account):

```bash
BOT_LOGIN=$(gh api user --jq '.login')
```

Then check for comments from **other users** after `commented_at`:

```bash
gh api repos/FerroxLabs/wayland/issues/<number>/comments \
  --jq '[.[] | select(.created_at > "<commented_at>" and .user.login != "'$BOT_LOGIN'")] | length'
```

- If result > 0 → **remove from skip list and re-analyze**
  Log: `Re-analyzing #1697 (new comments from other users since last attempt)`
- If result == 0 → **skip**
  Log: `Skipping #1697 (needs_more_info - no new comments from others)`

This ensures:

- Our own bot comments (analysis started, fix failed, needs info) are excluded
- Only human-provided information triggers re-analysis

**In batch mode (`limit=0`):** skip list is ignored - always analyze everything fresh.

#### Step 1.2: Fetch Open Bug Issues

```bash
gh issue list --repo FerroxLabs/wayland --state open --label bug --limit 50 \
  --json number,title,body,labels,assignees,comments,createdAt
```

##### Filtering Pipeline

Apply these filters **in order** to narrow down candidates:

**Filter 1 - No assignee:**

```
assignees == [] (nobody is working on it)
```

**Filter 2 - Has sufficient description:**

Issue body must contain at least ONE of:

- Error message or stack trace
- Steps to reproduce
- Log output
- Screenshot (image link) - will be analyzed in Step 1.3e
- Code snippet or file path reference

Issues with empty body, only a title, or body like `[Bug]:` with no content → **skip**.

**Note:** Issues with screenshots as the only detail should NOT be skipped here.
Pass them through to Step 1.3e for image analysis before deciding.

**Filter 3 - No linked PR (open or merged):**

```bash
# Check if this issue already has a linked PR (via "Closes #N" or manual link)
gh api repos/FerroxLabs/wa