---
name: code-implement
description: >
  Implement changes to resolve a GitLab issue: set In Progress, create branch,
  code with atomic commits, run tests/linters, create MR.
  Use when the user says /code-implement, /implement, 'implement this issue',
  'resolve this ticket', or needs to go from issue to MR.
argument-hint: "[GitLab issue IID or URL]"
allowed-tools:
  - Read
  - Edit
  - Write
  - Glob
  - Grep
  - Bash
  - Agent
  - AskUserQuestion
  - Skill
---

Implement the changes required to resolve a GitLab issue, from start to MR creation.

## 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

Detect the execution context using `detect_context` (pass `$ARGUMENTS` refs for automatic parsing of `#IID`, `!IID`, URLs):
```bash
CTX=$(pysae-ai-tools internal detect-context $ARGUMENTS_REFS)
IS_CI=$(echo "$CTX" | jq -r '.is_ci')
PROJECT_ID=$(echo "$CTX" | jq -r '.project_id // empty')
PROJECT_PATH=$(echo "$CTX" | jq -r '.project_path // empty')
ISSUE_IID=$(echo "$CTX" | jq -r '.issue_iid // empty')
```

In CI mode (`IS_CI` is `true`):
- **Never use `AskUserQuestion`** — all decisions must be resolved automatically
- If the issue has no `type::*` label, infer the type from the issue title and description (use `feat` as default if ambiguous)
- Always use **worktree** for isolation (no IDE in CI)
- On uncertainty, make a best-effort choice and document it in the commit message — do not stop

## Step 1 : Read the issue and detect type

Use `ISSUE_IID` from detect_context (resolved in Mode detection). Fetch the issue details:

```bash
glab issue view <IID> --output json
```

Extract: title, description, labels, acceptance criteria, linked epic.

Determine the type from the `type::*` label — see [../references/issue-type-mapping.md](../references/issue-type-mapping.md) for the full mapping table. If no `type::*` label is found: in local mode, ask the user; in CI mode, infer from title/description (default to `feat`).

## Step 2 : Set issue to In Progress

Move the issue to "In Progress":
```bash
pysae-ai-tools glab workflow-transition ${ISSUE_IID} "workflow::In progress"
```

## Step 3 : Create worktree and branch

**Determine the base branch** using the first matching rule:
1. If the user explicitly requested a base branch, use that.
2. If the user references a parent MR (by IID or URL), fetch it and:
   - If the MR is **open** (not merged): use its **source branch** as `BASE_BRANCH` (stacking on an in-progress MR).
   - If the MR is **merged**: use its **target branch** as `BASE_BRANCH` (the changes are already in that branch).
3. Otherwise, detect the repository's default branch:
   ```bash
   BASE_BRANCH="$(git remote show origin | sed -n 's/.*HEAD branch: //p')"
   ```

Store this value as `BASE_BRANCH` — it will also be used as the MR target branch in Step 6.

**Determine the branch name** following the naming convention from the MR skill:
```bash
# Slugify: lowercase, replace spaces/special chars with hyphens, max 40 chars
SLUG=$(echo "<short issue title>" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | cut -c1-40 | sed 's/-$//')
BRANCH="${BRANCH_PREFIX}/<IID>-${SLUG}"
```

Choisir le mode d'isolation selon ces règles **dans l'ordre** :

1. **Demande explicite de l'utilisateur** → faire ce qu'il demande (branche simple ou worktree)
2. **IDE connecté** (le tool `mcp__ide__getDiagnostics` est disponible) → **branche simple** (un worktree désynchronise l'IDE)
3. **Pas d'IDE** (terminal / headless / CI) → **worktree** via `/git-worktree`

**Worktree** : invoquer `/git-worktree` avec le nom de branche calculé ci-dessus. Le worktree isole les changements et permet de travailler sur plusieurs tickets en parallèle. `/git-worktree` crée la branche et le worktree en une seule opération — ne pas créer la branche manuellement avant.

**Branche simple** :
```bash
git fetch origin "${BASE_BRANCH}"
git checkout -b "${BRANCH}" "origin/${BASE_BRANCH}"
```

## Step 4 : Analyze and plan

Before coding, analyze the codebase to understand the problem and plan the implementation:

1. Read the repo's `CLAUDE.md` if it exists (project conventions, test commands, architecture)
2. Search for relevant files and understand the impacted code
3. Formulate an implementation plan with discrete, committable units of work

## Step 5 : First commit, then create the MR immediately

Make the **first logical unit of work** following the commit checklist below, then **push and create the MR right away** — before continuing with the rest of the implementation. This makes the work visible early, gets a CI pipeline running, and lets reviewers track progress incrementally.

1. **Make the changes** for the first unit of work — edit/create the necessary files
2. **Run relevant tests** — execute tests related to the changed code:
   - Python: `pytest <relevant_test_files>` or the test command from CLAUDE.md
   - Node/TS: `yarn test` / `npm test` / `npx vitest run`
   - If no specific test exists for the change, run the full test suite
3. **Run linters** — execute the project's linter:
   - Python: `ruff check` / `flake8` / the lint command from CLAUDE.md
   - Node/TS: `yarn lint` / `npm run lint` / `npx eslint`
4. **Fix any failures** — if tests or linters fail, fix the issues before committing
5. **Commit** the first atomic change:
   ```bash
   git add <specific_files>
   git commit -m "$(cat <<'EOF'
   ${COMMIT_PREFIX}: <short english description of this unit>

   Co-Authored-By: Claude <noreply@anthropic.com>
   EOF
   )"
   ```
6. **Push and create the MR immediately**:
   ```bash
   git push -u origin "${BRANCH}"
   ```
   Then invoke the `/glab-mr` skill with the source issue IID. If `BASE_BRANCH` is not the default branch, pass it as well (e.g., `/glab-mr <IID> --target-branch <BASE_BRANCH>`). **Never create the MR as draft** — it must be ready for review immediately, even though more commits will follow.

## Step 6 : Continue with the remaining commits

For each subsequent logical unit of work, repeat the cycle (changes → tests → linters → fix → commit) and push after each commit so the MR stays current:

```bash
git push
```

### Keep the MR description in sync

After each push, check whether the new commit introduces context that the current MR description does not capture (a new sub-feature, a non-trivial refactor, a notable design choice, an added test surface, a removed/changed behavior, etc.). If yes, **rewrite** the MR description so it describes the **current state** of the MR:

```bash
glab mr update <MR_IID> --description "$(cat <<'EOF'
<full French description, rewritten to match the current state, following the existing template/structure>
EOF
)"
```

The description is a snapshot of where the MR stands now — **never keep history, changelog-style entries, or "added X / removed Y" trails inside it**. Just describe what the MR currently does, as if it had been written from scratch. The commit history already carries the chronology.

Skip the update when the new commit is purely cosmetic (typo, comment, formatting) or already covered by the existing description — do not churn the description on every push. The MR title is updated only if the scope of the work changes meaningfully.

### Commit rules

- Each commit is a **single logical change** (one concern per commit)
- Tests and linter MUST pass before each commit
- Use the detected `COMMIT_PREFIX` consistently
- Commit message in English, imperative mood
- Never commit generated files, secrets, or `.env*` files

## Step 7 : Final validation

Once all units of work are committed and pushed, invoke the `/code-quality` skill with the `COMMIT_PREFIX` as argument. This runs the full test suite, linters, and pre-commit hooks, and fixes any remaining failures with atomic commits (which are then pushed to the existing MR).

## After MR creation

If this skill was invoked **directly by the user** (not delegated from another skill like `/code-auto-pilot`), suggest the next step:
> MR creee. Tu peux lancer `/code-review-fix` pour demarrer la boucle de review automatique.

## Critical rules

- **ALWAYS complete ALL steps (1→7)** — never stop early. The MR must be created right after the first commit (Step 5), and final validation (Step 7) must run after the last commit.
- **Never skip tests or linters** — every commit must have passing tests and clean lints
- **Atomic commits** — one logical change per commit, not one giant commit
- **Zero hallucination**: if uncertain about implementation, ask the user in local mode (do not guess); in CI mode, make a best-effort choice and document the assumption in the commit message
- **Max files**: 30 for bug/feature, 20 for technical/refactoring
- **Forbidden files**: never modify `.gitlab-ci.yml`, `.env*`, secrets, credentials
- **Language**: commit messages and MR title in English; MR description in French
- **Emojis**: preserve exactly as they appear in the loaded templates — do not add or remove any
- **Delegate to skills**: use `/glab-mr` for MR creation, `/code-quality` for validation, `/code-changelog` for changelog — do not duplicate their logic

## Self-check before each commit

- [ ] Tests pass for the changed code
- [ ] Linters pass
- [ ] No forbidden files modified
- [ ] Commit is atomic (single logical change)
- [ ] Commit message uses correct prefix and is in English

## Self-check before MR

- [ ] All planned changes implemented
- [ ] All tests pass (full suite)
- [ ] All linters pass
- [ ] Changelog entry exists (created by /glab-mr skill)
- [ ] MR exists and is up to date
- [ ] File count within limits

$ARGUMENTS
