---
name: glab-issue-next
description: >
  Pick the best next GitLab issue to implement from the Pysae backlog.
  Scores and ranks open issues by board column, priority, and user affinity.
  Use when the user says /glab-issue-next, /next, 'quel ticket',
  'prochain ticket', 'quoi faire', 'what should I work on', 'pick a ticket',
  'quick wins', 'tickets API', 'trouve un ticket', or needs help choosing their next task.
argument-hint: "[--all-projects] [--project PATH] [--user NAME] [--me] [--search TERM] [--p1|--p2|--p3] [--quick-wins] [--domain D] [--exclude-label L] [--anonymous] [--stale] [--top N]"
allowed-tools:
  - Bash
  - Read
  - AskUserQuestion
---

Find the best next issue to implement by scoring open GitLab issues across three equally-weighted dimensions.

## Required tools

- `glab`

Run `pysae-ai-tools tools require <tools>` before starting; if it exits non-zero, abort and report the install command from stderr to the user.

## Mode detection

```bash
CTX=$(pysae-ai-tools internal detect-context --local)
IS_CI=$(echo "$CTX" | jq -r '.is_ci')
PROJECT_PATH=$(echo "$CTX" | jq -r '.project_path // empty')
```

In CI mode (`IS_CI == "true"`):
- **Never use `AskUserQuestion`** — print the top candidates to stdout and exit (no interactive selection)
- Use `PROJECT_PATH` to scope to the current project if no `--project` flag is given
- Skip Step 3 (user choice) entirely

## How it works

The scoring algorithm (see `pysae_ai_tools.glab.find_issue`) ranks issues on three dimensions (each 0-100, equal weight):

1. **Board column** — `workflow::To Do` (100) > `Ready` (75) > `Refinement` (50) > Open/no label (25)
2. **Priority** — `P1` (100) > `P2` (66) > `P3` (33) > no priority (0)
3. **User affinity** — created & assigned (100) > assigned or created (75) > neither (0)

Plus bonuses:
- **Type** — `type::bug` +15, `Support` +15 (cumulative)
- **Age** — recent issues get up to +10 bonus by default. `--stale` prefers older issues instead

Issues already `In progress`, `Under review`, or `To deploy` are excluded.

See [../references/gitlab-labels.md](../references/gitlab-labels.md) for the full label taxonomy.

## Workflow

### Step 1 — Run the scoring script

```bash
pysae-ai-tools glab find-issue --top 3 [flags...]
```

#### Flag mapping

| User intent | Flag |
|---|---|
| Default: current project | *(auto-detected from repo)* |
| All Pysae projects | `--all-projects` |
| Explicit project | `--project pysae/api` |
| Specific user (fuzzy name) | `--user <NAME>` |
| Only assigned issues ("mes tickets") | `--me` |
| Priority ceiling | `--p1` / `--p2` / `--p3` |
| Quick wins ("j'ai 30 min") | `--quick-wins` |
| Domain filter ("tickets API") | `--domain API` (repeatable) |
| Exclude label ("pas d'INFRA") | `--exclude-label INFRA` (repeatable) |
| Topic search | `--search TERM` (repeatable) |
| No user bias ("objectivement") | `--anonymous` |
| Prefer older/stale issues | `--stale` |

`--me` and `--user` can be combined: `--me --user Lucas` shows only issues assigned to Lucas.

#### Natural language filtering

If the user's request contains a **topic or theme** (e.g. "ameliorer la performance", "related to GTFS", "authentication issues"), extract **2-4 short search keywords** (in both English and French when relevant) and pass each as a separate `--search` flag. The script queries the GitLab API with each term and merges results.

Examples:
- "tickets pour ameliorer la performance" → `--search performance --search cache --search optimization`
- "tickets lies au GTFS" → `--search GTFS --search GTFS-RT`
- "bugs d'authentification" → `--search auth --search login --search authentication`
- "j'ai 30 min, un truc rapide sur l'API" → `--quick-wins --domain API`
- "tickets de Lucas sauf infra" → `--user Lucas --exclude-label INFRA`

Think about synonyms and related technical terms to maximize recall.

### Step 2 — Present the candidates

Display the candidates in a clear format, including the snippet and age:

```
## Prochain ticket recommande

### 1. <title> — score: <total>/100
- **Issue**: <web_url>
- **Labels**: <labels>
- **Assigne**: <assignees or "personne">
- **Poids**: <weight or "non estime"> | **Age**: <age_days>j
- **Scoring**: board <board_score> | priorite <priority_score> | affinite <affinity_score> | bonus <bonus>
> <snippet>

### 2. ...

### 3. ...
```

### Step 3 — Let the user choose

**Default mode:** Ask the user which ticket they want to pick (default: #1). Once confirmed, suggest:

> Lance `/code-implement <IID>` pour l'implementation, ou `/code-auto-pilot <IID>` pour le pipeline complet (implement -> review -> CI -> deploy).

**Stale mode (`--stale`):** Ask the user which tickets should be closed (cancelled) among the displayed candidates:

> Parmi ces tickets anciens, que veux-tu faire ?
> - **Fermer** : numeros a fermer separes par des virgules, ou "tous"
> - **Implementer** : "impl N" pour lancer l'implementation du ticket N
> - **Passer** : "aucun" pour arreter la revue

- **If the user selects specific tickets:** close them (see [Closing a stale ticket](#closing-a-stale-ticket) below), then re-run the script to show 3 new candidates and ask again
- **If the user says "tous":** close all displayed tickets, then re-run the script to show 3 new candidates and ask again
- **If the user says "impl N":** suggest `/code-implement <IID>` or `/code-auto-pilot <IID>` for that ticket, then stop
- **If the user says "aucun":** stop the stale review

Repeat until the user says "aucun" or there are no more stale tickets.

### Closing a stale ticket

For each ticket to close, run:

```bash
PROJECT_ID=$(glab api "projects/$(echo '<PROJECT_PATH>' | sed 's|/|%2F|g')" | jq -r '.id')

# Remove all board column labels and add ANNULE
BOARD_LABELS=$(glab api "projects/${PROJECT_ID}/issues/${ISSUE_IID}" \
  | jq -r '[.labels[] | select(startswith("workflow::") or . == "Refinement" or . == "Ready")] | join(",")')
glab api -X PUT "projects/${PROJECT_ID}/issues/${ISSUE_IID}" \
  -f "remove_labels=${BOARD_LABELS}" \
  -f "add_labels=ANNULE" \
  -f "state_event=close"
```

Extract the project path from the issue's `web_url` (e.g. `https://gitlab.com/pysae/api/-/...` → `pysae/api`).

## Rules

- Always show exactly 3 candidates (or fewer if the backlog has less)
- If no open issues match, say so clearly
- Do not start implementation without user confirmation
- In stale mode, always confirm before closing tickets
- **Langue** : present results in French

$ARGUMENTS
