# Issue Create

> Create a GitHub issue with a structured body (Context, What, Why, Scope, Solution) and curated labels via the gh CLI. Use when filing new issues, or when invoked from other skills.

- Skill: `awinogradov/issue-create` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add awinogradov/issue-create`
- Raw SKILL.md: https://api.skillmd.com/api/skills/awinogradov/issue-create/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: awinogradov (https://skillmd.com/u/awinogradov)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/awinogradov/issue-create

---


# Create Issue

Create a GitHub issue with a structured body and curated labels. The body uses a fixed five-section structure (Context, What, Why, Scope, Solution). Titles are plain business descriptions — no Conventional Commits or prefix conventions. Labels are pulled from the repository and only labels that exist may be selected.

## When to Use

- When filing a new GitHub issue for tracking work
- When invoked from other skills that need to open an issue

## Input

Arguments: `$ARGUMENTS`

Expected form:

- `[title hint or short description]` — optional free-form hint that seeds the title and body generation (e.g., `"users cannot reset password via email"`).

## Input resolution

- **Title hint** — `$ARGUMENTS` → if empty, prompt once via AskUserQuestion: "What is this issue about?" with a free-form slot. Do not abort silently.
- **Repository** — `gh repo view --json nameWithOwner --jq .nameWithOwner`. No prompt.

## Completion Requirement

This workflow is not complete until [Phase 8](#phase-8-create-issue) executes `gh issue create` and outputs the issue URL. Generating a title, generating a body, or running label selection does not constitute completion. Execute all eight phases in sequence.

## AskUserQuestion Contract (MANDATORY)

Every AskUserQuestion call that presents content for review (the issue preview in [Phase 7](#phase-7-verify-with-user)) is governed by the shared contract: read [`askuserquestion-contract.md`](../shared-rules/references/askuserquestion-contract.md) and apply it. In this skill the preview content is the issue title + body + labels, plus an optional duplicate-warning line at the top.

## Phase 0: Resolve Repository and Hint

1. Parse `$ARGUMENTS` as an optional title hint. If empty, prompt the user via AskUserQuestion ("What is this issue about?") with a free-form slot.
2. Resolve the repository:
   ```bash
   gh repo view --json nameWithOwner --jq .nameWithOwner
   ```
   Store as `<repo>` (format: `owner/name`).
3. **No preflight-check is invoked.** Issue creation does not depend on git branch state — the user may file an issue from any branch including `main`.

## Phase 1: Gather Context

Ground the generated body in real code, not hallucinated structure.

1. Find files/symbols related to the hint (keywords from `$ARGUMENTS`) with `Grep` and `Glob`.
2. Read only the sections the search matched with targeted `Read`. Do NOT sweep the tree.
3. Also collect git context:
   ```bash
   git log -20 --oneline
   git status --short
   ```
   These inform the Context and Why sections.
4. **External documentation lookup (best-effort).** Classify keywords from `$ARGUMENTS` plus the file/symbol names that grep matched in step 1, then call the matching MCP(s) below. Each call is best-effort: on error, timeout, or empty result, log a warning and continue with whatever was collected. Do NOT block issue creation on MCP availability.
   - **Library / framework / SDK / CLI named in the hint** (e.g., React, Bun, Zod, `gh` CLI, Prisma) → call `mcp__context7__resolve-library-id` then `mcp__context7__query-docs` with a task-relevant topic. Run multiple library lookups in parallel.
   - **Official documentation URL or technology name** → `mcp__Ref__ref_search_documentation`, then `mcp__Ref__ref_read_url` for specific pages from the results.
   - **Code-pattern / "how do projects do X" / migration examples** → `mcp__exa__web_search_exa` for API patterns, changelogs, migration guides, and real-world usage.
   - **Recency / news / "is X deprecated" / general web Q&A** → `mcp__perplexity__perplexity_search` for factual lookups; `mcp__perplexity__perplexity_reason` for trade-off / architectural reasoning.

   Each MCP provides different information; use as many as the hint warrants. Feed the collected snippets into the body generated by [Phase 5](#phase-5-generate-body) (Context and Solution sections in particular).

**Fallback:** if any MCP server (context7, Ref, exa, perplexity) is unavailable or returns no results, continue with whatever the remaining sources produced. Do not block the skill on MCP availability — the generated body should still ship, just with less external context.

## Phase 2: Fetch Available Labels

```bash
gh label list -R <repo> --limit 100 --json name,description,color
```

- On success with non-empty output: store the label list for [Phase 6](#phase-6-suggest-labels) (suggestion matching).
- On success with empty output (`[]`): continue with no label suggestions. [Phase 7](#phase-7-verify-with-user) preview will show `Labels: (none)`.
- On error (non-zero exit, network failure): log a warning and continue with no labels. Do not block the skill.

## Phase 3: Find Related Issues and PRs

Search the repository for related work in both directions (open + closed) so the new issue can reference duplicates, prior art, and in-flight work.

1. Extract 3-5 keyword phrases from `$ARGUMENTS` + [Phase 1](#phase-1-gather-context) context. Example: for `"users cannot reset password via email"` → `password reset`, `email reset`, `reset password`.
2. For each keyword phrase, run both:
   ```bash
   gh issue list -R <repo> --search "<phrase>" --state all --limit 10 --json number,title,state,url,labels,updatedAt
   gh pr   list -R <repo> --search "<phrase>" --state all --limit 10 --json number,title,state,url,updatedAt
   ```
3. Merge and deduplicate by `number`. Rank by relevance (keyword match count + recency from `updatedAt`).
4. Keep the top 5 results across issues+PRs combined. Categorise each as `[open]`, `[closed]`, or `[merged]` (PRs).
5. On error (non-zero exit, network failure): log a warning and continue with no related items. Do not block the skill.
6. Pass the related items into [Phase 5](#phase-5-generate-body) (used in the body's Context section as a `Related: #N, #M` line — magic-word free so it does NOT auto-close anything). The duplicate-detection check against the planned title runs in [Phase 4](#phase-4-generate-title) (after the title exists).

## Phase 4: Generate Title

**Rules:**

- Capitalized first letter
- ≤ 80 characters total
- No trailing period
- Business-focused, understandable by someone on their first day
- **NOT** Conventional Commits format (no `feat:`, `fix:`, `chore:`)
- **NO** prefix (no `[BUG]`, `HOTFIX:`, `[FEATURE]`)
- Describes what needs to happen or the problem being solved

**Examples:**

| Hint                                                | Generated Title                                      |
| --------------------------------------------------- | ---------------------------------------------------- |
| `"users cannot reset password via email"`           | `Users cannot reset password via email`              |
| `"refactor token streaming pipeline"`               | `Refactor token streaming pipeline for backpressure` |
| `"add release notes section to PR template"`        | `Add release notes section to pull request template` |
| `"audio drops every time multiple clients connect"` | `Audio playback drops when multiple clients connect` |

**Duplicate-detection check (after the title is generated):**

For each open item returned by [Phase 3](#phase-3-find-related-issues-and-prs), compute the keyword-overlap ratio against the generated title:

- Tokenize both strings into lowercase keywords, drop English stop words (`a`, `the`, `for`, `to`, `of`, `in`, `on`, etc.).
- Empty-set guard (apply BEFORE the division):
  - If `titleKeywords` is empty AND `candidateKeywords` is empty → `overlap = 1.0` (both strings are stop-word-only; treat as identical).
  - If exactly one of the two sets is empty → `overlap = 0` (no meaningful overlap; one side has nothing to match against).
- Otherwise: `overlap = |titleKeywords ∩ candidateKeywords| / min(|titleKeywords|, |candidateKeywords|)`.
- If `overlap > 0.8` for any open item, set `possibleDuplicate` to that item (the highest-scoring one wins on ties). [Phase 7](#phase-7-verify-with-user) will surface a warning line so the user can cancel and comment on the existing issue instead.
- Closed and merged items are not duplicate candidates (they only feed the `Related:` line); only open items can trigger the warning.

## Phase 5: Generate Body

Read [`issue-body-grammar.md`](../shared-rules/references/issue-body-grammar.md) and apply it — it defines the five-section structure, the per-section rules, and the linkability pass that runs after drafting.

Caller-specific wiring:

- The related items from [Phase 3](#phase-3-find-related-issues-and-prs) feed the Context section's `Related:` line.
- Linkability-pass links must use the absolute `<repo-blob-url>` form — the body is posted outside the repo, where relative paths do not resolve.

## Phase 6: Suggest Labels

Match [Phase 2](#phase-2-fetch-available-labels)'s label list against [Phase 4](#phase-4-generate-title) title + [Phase 5](#phase-5-generate-body) body keywords.

1. Score each fetched label by: (a) presence of label name/description keywords in title (weight 2), (b) presence in body (weight 1).
2. Select the top 0-3 matches.
3. **Validation:** only labels present in the [Phase 2](#phase-2-fetch-available-labels) fetched set may be selected. NEVER invent a label name — `gh issue create --label nonexistent` will fail.
4. If no label scores > 0, select none and proceed with `Labels: (none)`.

## Phase 7: Verify with User

Present the full issue using AskUserQuestion with preview. See the AskUserQuestion Contract above — all rules are mandatory.

1. Compose the full preview string:
   - If [Phase 3](#phase-3-find-related-issues-and-prs) flagged a `possibleDuplicate`, the FIRST line is:
     ```
     Possible duplicates: #123 (<title of duplicate>), #456 (<title>)
     ```
     followed by a blank line.
   - Then the title line.
   - Blank line.
   - The five-section body (literal newlines, no escaping).
   - Blank line.
   - `Labels: label1, label2` (or `Labels: (none)`).

2. AskUserQuestion parameters:
   - `question`: "Review the issue details and choose an action."
   - `header`: "Create issue"
   - `options`:
     ```
     [
       { label: "Create issue", description: "Create this GitHub issue", preview: "<full preview>" },
       { label: "Edit content", description: "Modify title, body, or labels", preview: "<full preview>" },
       { label: "Cancel", description: "Abort issue creation", preview: "<full preview>" }
     ]
     ```
   - `multiSelect`: false

   All three options use the same `preview` content since the user is choosing an action, not content.

3. If user selects "Edit content": ask what to change (title / body section / labels), regenerate that part, re-present via AskUserQuestion.

4. If user selects "Cancel":
   - If a `possibleDuplicate` was surfaced, output: `Issue creation cancelled. Consider commenting on #<duplicate-number> instead.`
   - Otherwise: `Issue creation cancelled.`
   - Abort.

5. Only proceed to [Phase 8](#phase-8-create-issue) after the user selects "Create issue".

## Phase 8: Create Issue

This phase is mandatory. The skill is complete only after the issue URL is printed.

Execute via stdin so body content (which may contain backticks, `$()`, ASCII diagrams, quotes) is preserved exactly:

```bash
printf '%s' "<body>" | gh issue create \
  --repo <owner/repo> \
  --title "<title>" \
  --body-file - \
  --label "<label1>" --label "<label2>"
```

**Rules:**

- Pass `--repo <owner/repo>` explicitly (resolved in [Phase 0](#phase-0-resolve-repository-and-hint)). Do not rely on cwd — this matters in worktrees.
- Use `--body-file -` to read the body from stdin via `printf '%s'`. Avoids shell expansion of backticks and `$(...)` in the body.
- Repeat `--label` once per label. Do NOT comma-join — label names may contain commas.
- If no labels were selected, omit the `--label` flags entirely.
- The URL is the last line of `gh issue create` stdout. Capture it.

Output the result:

```
✓ Created issue: <url>
```

## Examples

### Solution with ASCII diagram via ascii-schemas

```
/autopilot:issue-create "refactor token streaming pipeline"
```

[Phase 5](#phase-5-generate-body) detects that the Solution describes a flow between ≥ 2 components and invokes `Skill(autopilot:ascii-schemas)` to draw the new pipeline.

[Phase 7](#phase-7-verify-with-user) AskUserQuestion parameters:

- `question`: "Review the issue details and choose an action."
- `header`: "Create issue"
- `options`: `Create issue` / `Edit content` / `Cancel`, with the descriptions listed in [Phase 7](#phase-7-verify-with-user)
- `multiSelect`: false

Preview (every option carries this same full preview string):

```
Refactor token streaming pipeline for backpressure

## Context

The current token streaming pipeline buffers an entire response before flushing to the client. Long completions exhaust the server-side buffer and back up upstream LLM calls.

## What

Convert the pipeline to a streaming model with explicit backpressure between the model adapter, the codec, and the SSE writer.

## Why

Long-form completions today block other in-flight requests, raising p99 latency for unrelated calls. Backpressure unblocks parallelism without raising memory.

## Scope

- **In scope:**
  - Streaming model adapter → codec interface
  - Codec → SSE writer with credit-based backpressure
  - Integration test covering > 100k token responses
- **Out of scope:**
  - Replacing SSE with WebSocket (separate proposal)

## Solution

Introduce a typed `TokenStream` reader/writer pair between each pipeline stage. Each stage applies credit-based backpressure: a downstream consumer signals `n` credits, the upstream producer sends at most `n` tokens before waiting.

\`\`\`text
┌─────────────┐   tokens    ┌──────────┐   credits   ┌─────────────┐
│ ModelAdapter│ ──────────▶ │  Codec   │ ──────────▶ │ SseWriter   │
│             │ ◀────────── │          │ ◀────────── │             │
└─────────────┘   credits   └──────────┘   credits   └─────────────┘
\`\`\`

Labels: refactor, performance
```

User selects "Create issue".

```
✓ Created issue: https://github.com/org/repo/issues/144
```

Further worked examples: read [references/examples.md](./references/examples.md) when a call site is ambiguous.

When you generate the issue body, apply the reference-formatting rules in [`reference-formatting.md`](../shared-rules/references/reference-formatting.md) (RFC-0001, read it first) to every reference it contains — link files, docs, skills, agents, sections, and commit SHAs as absolute `<repo-blob-url>` URLs (the body is posted outside the repo, where relative paths do not resolve), link cited external resources to their canonical source URL, and never leave a reference as bare text.

