---
name: create-pr
description: "Create a pull request for the current branch. Handles uncommitted changes, generates a PR title matching the `[{modules}] {type}: {description}` format enforced by CI, and fills in the PR description template. Trigger: 'create pr', 'open pr', 'submit pr', 'make pr'."
---

## Interaction Principle

**Minimize confirmations.** The only user confirmation is for uncommitted changes (Step 1.3). Everything after that — drafting, writing file, pushing, creating PR — runs automatically. Tool-level permission prompts (file write, git push) serve as implicit confirmation; do not add extra "are you sure?" pauses on top.

## Steps

### Step 1: Pre-flight Checks

1. **Identify current branch**:
   ```bash
   git branch --show-current
   ```
   If on `main` — stop and ask the user to create a feature branch first.

2. **Determine base branch**: use `main` unless the user specifies otherwise.

3. **Check for uncommitted changes** (only confirmation point):
   ```bash
   git status
   git diff --stat
   ```
   If there are staged or unstaged changes, show a summary and ask the user:
   > "There are uncommitted changes. Commit them before creating the PR?"

   - If yes: run `make quality`, stage relevant files (skip `.env`, credentials, large binaries), commit.
   - If no: proceed with what's already committed.
   - If `make quality` fails: stop and report errors.

4. **Check for existing PR** on this branch:
   ```bash
   gh pr view --json number,title,body 2>/dev/null
   ```
   Note the PR number if one exists.

5. **Check commits ahead of base**:
   ```bash
   git log origin/main..HEAD --oneline
   ```
   If the branch has no commits ahead of `main`, stop — nothing to open a PR for.

### Step 2: Analyze Changes (automatic)

1. Collect the full diff against the base branch:
   ```bash
   git diff main...HEAD
   git log main..HEAD --oneline
   ```

2. Identify **affected modules** by mapping changed file paths to allowed module names:

   | Path prefix | Module |
   |------------|--------|
   | `veomni/models/` | `model` |
   | `veomni/trainer/` | `trainer` |
   | `veomni/data/` | `data` |
   | `veomni/distributed/` | `dist` (use `parallel` when the change is about a parallelism strategy rather than the plumbing) |
   | `veomni/ops/` | `ops` |
   | `veomni/checkpoint/` | `ckpt` |
   | `veomni/optim/` | `optim` |
   | `veomni/lora/` | `lora` |
   | `configs/` | `config` |
   | `docs/` | `docs` |
   | `tests/`, `.github/workflows/` | `ci` |
   | `docker/` | `docker` |
   | `tasks/` | `task` |
   | `.agents/` | `agent` |
   | anything with a measurable speed/memory claim | add `perf` |
   | other / mixed | `misc` |

   `omni`, `logging` and `release` have no directory of their own — use them
   for omni-model, log/telemetry-surface and release-plumbing changes
   respectively.

   The authoritative module and type lists live in
   `.github/workflows/check_pr_title.yml` (`allowedModules` / `allowedTypes`).
   Read it rather than trusting this table if a name is rejected.

3. Determine **change type**:

   | Type | When |
   |------|------|
   | `feat` | New functionality or capability |
   | `fix` | Bug fix |
   | `refactor` | Same behavior, better structure |
   | `chore` | Maintenance, cleanup, config changes |
   | `test` | Test-only changes |

### Step 3: Generate Draft File and Push (automatic)

0. **Apply `/veomni-review` before pushing.** Use its applicability rules for
   `<base>...HEAD`, including the documentation self-check and the narrowly
   defined exemption for clean, exact reverts or approved-diff reapplications.
   Partial reverts, extra edits and conflict resolutions need the normal gate.
   Review again before a substantive update to an open PR. A `risky` verdict
   stops the PR: report it and wait for the user.

1. Draft PR title in `[{modules}] {type}: {description}` format:
   - Multiple modules separated by comma: `[model, data] feat: ...`
   - Description: concise, lowercase start, no period, under 60 chars
   - Breaking changes: prepend `[BREAKING]`
   - Must pass the regex in `.github/workflows/check_pr_title.yml`

2. Draft the PR description by **reading `.github/PULL_REQUEST_TEMPLATE.md`**
   and filling in its sections. Do not reproduce the template from memory — it
   changes, and a stale copy silently drops checklist items.

3. **Write to `.pr-drafts/`** (already in `.gitignore`):
   ```bash
   mkdir -p .pr-drafts
   ```

   **Filename convention**:
   - Existing PR: `.pr-drafts/<pr-number>.md` (e.g. `.pr-drafts/123.md`)
   - New PR: `.pr-drafts/<branch-name>.md` — renamed to PR# after creation.

   **File format** — first line is the PR title, blank line, then the description body:

   ```markdown
   [model] feat: add support for Qwen4

   <sections copied from .github/PULL_REQUEST_TEMPLATE.md, filled in>
   ```

   Keep the template's own bullet/checkbox style. Fill every section: an empty
   `### Test` section is the most common review blocker. If the PR adds an
   extension point (a mixin, hook or callback other modules must implement),
   name its `docs/` page under **Design & Code Changes**; with no such page,
   write it first (see "Documenting an extension point" in `/veomni-develop`)
   rather than claiming "Added/updated documentation".

4. Tell the user the draft file path (so they know where to find it if they want to review later).

### Step 4: Push and Create/Update PR (automatic, immediately after Step 3)

1. Push the branch:
   ```bash
   git push -u origin HEAD
   ```

2. **Create or update**:
   - New PR (use `--body-file` to avoid shell escaping issues):
     ```bash
     # Extract body from draft file (everything after the first blank line)
     tail -n +3 .pr-drafts/<branch-name>.md > /tmp/pr-body.md
     gh pr create --base <base-branch> --title "<title>" --body-file /tmp/pr-body.md
     ```
     After creation, rename the draft file from `<branch-name>.md` to `<pr-number>.md`.
   - Existing PR:
     ```bash
     tail -n +3 .pr-drafts/<pr-number>.md > /tmp/pr-body.md
     gh pr edit <pr-number> --title "<title>" --body-file /tmp/pr-body.md
     ```

3. Output the PR URL and the draft file path.

## Common Pitfalls

- **Title format is enforced by CI** — a malformed title will block the PR. Always validate against the allowed modules and types listed above.
- **Don't force-push** unless the user explicitly asks.
- **Check for sensitive files** before committing — skip `.env`, credentials, large binaries and warn the user.
