Claude
Skills
Sign in
Back

issue-list

Included with Lifetime
$97 forever

List and filter tickets/issues from configured backend

Backend & APIs

What this skill does


<!-- AIWG-SKILL-CALLOUT -->
> **Skill access pattern (post-kernel-pivot, 2026.5+)**
>
> Skill names referenced in this document are AIWG skills, **not slash commands**. Most are not kernel-listed and cannot be invoked as `/skill-name` by the platform. Reach them via:
>
> ```bash
> aiwg discover "<capability>"
> aiwg show skill <name>
> ```
>
> Only kernel-listed skills (`aiwg-doctor`, `aiwg-refresh`, `aiwg-status`, `aiwg-help`, `use`, `steward`) are directly invokable as slash commands. See [skill-discovery rule](../../../addons/aiwg-utils/rules/skill-discovery.md).


# Issue List

## Purpose

List and filter tickets/issues from the configured ticketing provider (Gitea, GitHub, Jira, Linear) or local file-based tracking. Supports filtering by status, labels, assignee, and custom output formats.

## Task

Given optional filter parameters:

1. **Load configuration** from `.aiwg/config.yaml` or project `CLAUDE.md`
2. **Fetch tickets** from provider or local files
3. **Apply filters** (status, labels, assignee)
4. **Format output** (table, JSON, or markdown)
5. **Display results** with summary statistics

## Parameters

- **`--status STATE`** (optional): Filter by status (open|in_progress|closed|blocked|review|all)
  - Default: `open` (only show open tickets)
  - Use `all` to show all tickets regardless of status
- **`--label LABEL`** (optional): Filter by label (can specify multiple: `--label bug --label high-priority`)
- **`--assignee USER`** (optional): Filter by assignee (use `unassigned` for unassigned tickets)
- **`--limit NUM`** (optional): Limit results to NUM tickets (default: 50)
- **`--sort FIELD`** (optional): Sort by field (created|updated|priority|id)
  - Default: `created` (newest first)
- **`--format FORMAT`** (optional): Output format (table|json|markdown|compact)
  - Default: `table`
- **`--provider NAME`** (optional): Override configured provider

## Inputs

**Configuration sources** (same as `issue-create` and `issue-update`):
1. `.aiwg/config.yaml` - Project-level configuration
2. `CLAUDE.md` - User-level configuration
3. Default: `local` provider

## Outputs

**Table Format** (default):
```
┌──────────┬────────────────────────┬────────────┬──────────┬──────────┬────────────┐
│ ID       │ Title                  │ Status     │ Priority │ Assignee │ Labels     │
├──────────┼────────────────────────┼────────────┼──────────┼──────────┼────────────┤
│ ISSUE-1 │ Implement user auth    │ in_progress│ high     │ johndoe  │ feature,ui │
│ ISSUE-2 │ Add dark mode          │ open       │ medium   │ janedoe  │ feature    │
│ ISSUE-3 │ Fix navigation bug     │ closed     │ critical │ johndoe  │ bug        │
└──────────┴────────────────────────┴────────────┴──────────┴──────────┴────────────┘

Summary: 3 tickets (1 open, 1 in_progress, 1 closed)
```

**Compact Format**:
```
ISSUE-1  [in_progress] [high]     Implement user auth          @johndoe  [feature,ui]
ISSUE-2  [open]        [medium]   Add dark mode                @janedoe  [feature]
ISSUE-3  [closed]      [critical] Fix navigation bug           @johndoe  [bug]

Summary: 3 tickets (1 open, 1 in_progress, 1 closed)
```

**Markdown Format**:
```markdown
# Issues

## ISSUE-1: Implement user auth

**Status**: in_progress
**Priority**: high
**Assignee**: @johndoe
**Labels**: feature, ui
**Created**: 2026-01-10
**Updated**: 2026-01-13

---

## ISSUE-2: Add dark mode

**Status**: open
**Priority**: medium
**Assignee**: @janedoe
**Labels**: feature
**Created**: 2026-01-11
**Updated**: 2026-01-11

---

## Summary

3 tickets (1 open, 1 in_progress, 1 closed)
```

**JSON Format**:
```json
{
  "tickets": [
    {
      "id": "ISSUE-1",
      "title": "Implement user auth",
      "status": "in_progress",
      "priority": "high",
      "assignee": "johndoe",
      "labels": ["feature", "ui"],
      "created": "2026-01-10",
      "updated": "2026-01-13",
      "url": "https://git.integrolabs.net/roctinam/ai-writing-guide/issues/1"
    },
    {
      "id": "ISSUE-2",
      "title": "Add dark mode",
      "status": "open",
      "priority": "medium",
      "assignee": "janedoe",
      "labels": ["feature"],
      "created": "2026-01-11",
      "updated": "2026-01-11",
      "url": "https://git.integrolabs.net/roctinam/ai-writing-guide/issues/2"
    }
  ],
  "summary": {
    "total": 3,
    "open": 1,
    "in_progress": 1,
    "closed": 1
  }
}
```

## Workflow

### Step 1: Parse Parameters

Extract from command invocation:

```bash
# List all open tickets (default)
/issue-list

# List all tickets (including closed)
/issue-list --status all

# Filter by status
/issue-list --status in_progress
/issue-list --status closed

# Filter by label
/issue-list --label bug
/issue-list --label feature --label high-priority

# Filter by assignee
/issue-list --assignee johndoe
/issue-list --assignee unassigned

# Combine filters
/issue-list --status open --label bug --assignee johndoe

# Limit results
/issue-list --limit 10

# Sort by field
/issue-list --sort updated
/issue-list --sort priority

# Change format
/issue-list --format compact
/issue-list --format json
/issue-list --format markdown
```

**Parameter extraction**:
- All parameters optional
- Default: `--status open --limit 50 --format table --sort created`

### Step 2: Load Configuration

Same resolution rules as `issue-create` (preferred path):

1. **`--provider` flag** — explicit override always wins.
2. **`.aiwg/aiwg.config` `remotes.issue_tracker`** (#994) — derive provider via `resolveRemotes()` + `resolveRemoteProvider()` from `src/config/aiwg-config.ts`.
3. **Legacy `.aiwg/config.yaml`** (`ticketing` block) — back-compat.
4. **`CLAUDE.md` "Issueing Configuration"** — fallback.
5. **`local`** — default.

When `resolveRemoteProvider(url)` returns `'unknown'` (self-hosted instances), the operator must pass `--provider` explicitly. Don't guess.

### Step 3: Fetch Issues (Provider-Specific)

#### Gitea

Use Gitea REST API:

```bash
# Build query parameters
STATE="open"  # or "closed" or "all"
LABELS="${LABEL:-}"
ASSIGNEE="${ASSIGNEE:-}"
LIMIT="${LIMIT:-50}"
SORT="created"  # or "updated"
ORDER="desc"

# Fetch issues
curl -s -H "Authorization: token $(cat ~/.config/gitea/token)" \
  "${URL}/api/v1/repos/${OWNER}/${REPO}/issues?state=${STATE}&labels=${LABELS}&assignee=${ASSIGNEE}&limit=${LIMIT}&sort=${SORT}&order=${ORDER}"
```

**Response mapping**:
```json
[
  {
    "number": 1,
    "title": "Implement user auth",
    "state": "open",
    "labels": [{"name": "feature"}, {"name": "ui"}],
    "assignee": {"login": "johndoe"},
    "created_at": "2026-01-10T10:00:00Z",
    "updated_at": "2026-01-13T15:30:00Z",
    "html_url": "https://git.integrolabs.net/roctinam/ai-writing-guide/issues/1"
  }
]
```

**Map to internal format**:
```bash
ID="ISSUE-${number}"
TITLE="${title}"
STATUS="${state}"  # map to generic status
PRIORITY="${extracted from body or labels}"
ASSIGNEE="${assignee.login}"
LABELS="${labels[].name joined by comma}"
CREATED="${created_at}"
UPDATED="${updated_at}"
URL="${html_url}"
```

#### GitHub

Use `gh` CLI:

```bash
# Build query
STATE="${STATUS:-open}"  # or "closed" or "all"
LABELS="${LABEL:-}"
ASSIGNEE="${ASSIGNEE:-}"
LIMIT="${LIMIT:-50}"

# Fetch issues
gh issue list \
  --repo "${OWNER}/${REPO}" \
  --state "${STATE}" \
  --label "${LABELS}" \
  --assignee "${ASSIGNEE}" \
  --limit "${LIMIT}" \
  --json number,title,state,labels,assignees,createdAt,updatedAt,url
```

**Response mapping**:
```json
[
  {
    "number": 42,
    "title": "Implement user auth",
    "state": "OPEN",
    "labels": [{"name": "feature"}, {"name": "ui"}],
    "assignees": [{"login": "johndoe"}],
    "createdAt": "2026-01-10T10:00:00Z",
    "updatedAt": "2026-01-13T15:30:00Z",
    "url": "https://github.com/jmagly/aiwg/issues/42"
  }
]
```

**Map to internal format**:
```bash
ID="#${number}"
TITLE="${title}"
STATUS="${state}"  # map OPEN → open, CLOSED → closed
PRIORITY="${extracted from labels or body}"
ASSIGNEE="${assignees[0].login}"
LABELS="${labels[].name joined b

Related in Backend & APIs