---
name: okstra-pr-gen
description: Use when the user wants to register a PR body template or generate a PR description from a branch diff using a stored (or default) template. Manages templates under ~/.okstra/template/pr and drives okstra pr {template,branches,gen}. Trigger words include "okstra pr", "register PR template", "generate PR body", "generate PR message", "generate PR", "pr gen", and "register template".
---

# okstra-pr-gen

Register PR body templates and generate PR descriptions. Templates live in the
user home at `~/.okstra/template/pr/`. This skill is **global** — it does not
require `<PROJECT_ROOT>/.okstra/project.json`. PR generation additionally
requires the current directory to be a git repository.

## Step 0: Check CLI availability

Run as a separate Bash tool call with a literal leading token:

```bash
okstra pr --help
```

If `okstra` is not on PATH, tell the user:

`okstra not installed — run npx okstra@latest install once, then retry this skill.`

**Bash invocation rule:** every Bash command begins with the literal token
`okstra` and passes literal argument values. Do not introduce shell variables,
`$(...)`, leading `VAR=`, or wrap in `if`/`eval`/`||`/`&&` — that defeats the
`Bash(okstra:*)` permission match. Paste literal values emitted by a prior call.

## Step 1: Pick the mode (always first)

Present a 3-option picker (`AskUserQuestion`):

1. `Generate PR` — generate a PR body from a branch diff.
2. `Register template` — save a new PR body template.
3. `Enter directly` — always the last option (okstra picker convention).

## Mode A — Generate PR

### A0. Branch naming (allowlist)

Whenever this skill creates or proposes a head branch name, the prefix comes
from this list and nothing else:

| work kind | prefix |
| --- | --- |
| feature, improvement | `feature/` |
| bug fix | `fix/` |
| refactor | `refactor/` |
| ops, chore | `ops/` |
| unclassified | `task/` |

`feat/`, `bugfix/`, `chore/`, `hotfix/` are not in the allowlist — do not emit
them. This mirrors okstra's worktree branch namespace, whose SSOT is
`_WORK_CATEGORY_NAMESPACE` in `scripts/okstra_ctl/worktree/naming.py`. A branch name
the user states explicitly wins verbatim; never rewrite it.

### A1. Pick a template

```bash
okstra pr template list
```

- If `templates` is non-empty, present a picker: 1–2 recommended templates from
  the list, plus `Default template` (the bundled default), plus `Enter directly`
  last.
- If empty, tell the user the bundled default template will be used.

Carry the chosen template name as `<template>` (`default` for the bundled one).

### A2. Pick the base branch

```bash
okstra pr branches
```

Present a 3-option base picker from `recommended` (top entries) plus `Enter directly`
last. Carry the choice as `<base>`.

### A3. Build the generation bundle and fill the template

```bash
okstra pr gen --base <base> --template <template>
```

Read the fixed `Base`, `Current branch`, `Template name`, `Commits`, `Diff stat`,
and `Template` sections. Then
read the full diff honestly — it is the source of truth:

```bash
git diff <base>...HEAD
```

For a large diff, read it in sections. Fill the `template` placeholders from the
diff and commits: describe only what actually changed. Mark checklist boxes
`[x]` only when the diff supports them (tests touched → tests box, docs touched →
docs box). If `commits`/`diffStat` are empty, tell the user there is nothing to
describe and stop. **Never** append AI trailers/footers.

### A3b. Identifier allowlist for the body

Reviewers have never seen okstra, so an okstra-internal id reads as a nonsense
token. Identifiers in the PR title and body come from this list and nothing else:

| allowed | example |
| --- | --- |
| repo-relative source path, optionally with a line | `src/commands/pr/pr.mjs:42` |
| symbol name that exists in the diff | `resolveTemplate()` |
| branch name, commit subject, commit SHA | `feature/dev-9436`, `a1b2c3d` |
| issue-tracker ticket id the reviewer can open | `dev-9436` |

okstra's own artifact identifiers are out of the allowlist — drop them:

- report item ids — `F-001`, `C-001`, `R-001`, `D-0001`, `PREP-001`
- run artifact names and their `<task-type>-<seq>` suffixes —
  `final-report-implementation-3.data.json`, `run-manifest-implementation-3.json`
- phase / stage / worker labels — `final-verification`, `stage-2`, `codex-worker`
- any path under `.okstra/` — reports, decisions, glossary, user-response sidecars

When the only source for a claim is such an artifact, restate its substance in
the reviewer's terms — what changed in the code, and why — instead of citing the
id.

### A4. Output and offer to create the PR

Print the filled PR body to chat as a single fenced markdown block. Then ask the
user whether to open a real PR. Only on an explicit yes:

```bash
gh pr create --base <base> --title "<title>" --body-file <path-to-body>
```

Write the body to a temp file first and pass `--body-file`. If `gh` is missing
or not authenticated (`gh auth status` fails), leave the text in chat and tell
the user to create the PR manually. Do not push or create the PR without the
user's explicit confirmation.

## Mode B — Register template

1. Ask for a template name (`AskUserQuestion`, free text). It must match
   `^[A-Za-z0-9._-]+$`; re-ask on invalid input.
2. Ask for the template body — either pasted text or an absolute file path.
3. Save it:

   ```bash
   okstra pr template add --name <name> --file <abs-path>
   ```

   or, for pasted text, `--content "<body>"`. Add `--yes` only if the user
   confirmed overwriting an existing template of the same name. Report the
   saved path (`saved: ...`) back to the user.
