--- name: issue-create description: Create well-formatted GitHub issues with intelligent AI-powered label suggestions and content type detection. Use whenever the user wants to. allowed-tools: Read, Bash, Grep, Glob --- # Issue Create Skill Create well-formatted GitHub issues with intelligent automation including AI-powered label suggestions, content type detection, template formatting, and related issue linking. > **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. ## When to Use This Skill Use this skill when: - Creating bug reports, feature requests, questions, or documentation issues - Need AI-powered label suggestions from repository's existing taxonomy - Want automatic duplicate detection and related issue linking - Need consistent issue formatting across different repositories ## Invocation **Slash command**: `/gh-tools:issue-create` **Natural language triggers**: - "Create an issue about..." - "File a bug for..." - "Submit a feature request..." - "Report this problem to..." - "Post an issue on GitHub..." ## Features ### 1. Repository Detection - Auto-detects repository from current git directory - Supports explicit `--repo owner/repo` flag - Checks permissions before attempting to create ### 2. Content Type Detection - AI-powered detection (gpt-4.1 via gh-models) - Fallback to keyword matching - Types: Bug, Feature, Question, Documentation ### 3. Title Extraction - Extracts informative title from content - Adds type prefix (Bug:, Feature:, etc.) - **Maximizes GitHub's 256-character limit** for informative titles ### 4. Body Limit Maximization (65,536 Characters) GitHub issue bodies support **65,536 characters** (not bytes — UTF-8 multibyte characters count as 1). Always aim to fill a single post rather than splitting across multiple issues or comments. **Principle**: One comprehensive post is more valuable than many fragmented ones. Pack as much analysis, context, history, and multi-perspective reasoning as possible into a single issue body or comment. **When composing long-form issue content**: - **Check remaining capacity**: `echo "$BODY" | wc -m` (characters, not bytes) - **Target ~60,000 chars** to leave headroom for GFM rendering edge cases - **Use collapsible sections** (`
`) for dense reference material — they don't reduce the char budget but improve readability - **Include all perspectives**: if the issue documents a decision, include the alternatives considered, trade-offs, evidence for/against, and why the chosen path won - **Embed historical context**: timelines, prior art, links to related issues, session provenance — all belong in one post - **Never pre-emptively split**: only split if you genuinely exceed 65,536 chars (rare) **Pre-post size check pattern**: ```bash # Build body, then verify it fits BODY=$(cat <<'EOF' ... your content ... EOF ) CHARS=$(echo "$BODY" | wc -m | tr -d ' ') echo "Body size: ${CHARS}/65536 chars" if [ "$CHARS" -gt 65536 ]; then echo "WARNING: Exceeds limit by $((CHARS - 65536)) chars — trim or split" fi ``` ### 5. Template Formatting - Auto-selects template based on content type - Bug: Steps to reproduce, Expected/Actual behavior - Feature: Use case, Proposed solution - Question: Context, What was tried - Documentation: Location, Suggested change ### 5. Label Suggestion - Fetches repository's existing labels - AI suggests 2-4 relevant labels - Only suggests labels that exist (taxonomy-aware) - 24-hour cache for performance ### 6. Related Issues - Searches for similar issues - Links related issues in body - Warns about potential duplicates ### 7. Preview & Confirm - Full preview before creation - Dry-run mode available - Edit option for modifications ## Usage Examples ### Basic Usage ```bash # From within a git repository bun ~/eon/cc-skills/plugins/gh-tools/scripts/issue-create.ts \ --body "Login page crashes when using special characters in password" ``` ### With Explicit Repository ```bash bun ~/eon/cc-skills/plugins/gh-tools/scripts/issue-create.ts \ --repo owner/repo \ --body "Feature: Add dark mode support for better accessibility" ``` ### Dry Run (Preview Only) ```bash bun ~/eon/cc-skills/plugins/gh-tools/scripts/issue-create.ts \ --repo owner/repo \ --body "Bug: API returns 500 error" \ --dry-run ``` ### With Custom Title and Labels ```bash bun ~/eon/cc-skills/plugins/gh-tools/scripts/issue-create.ts \ --repo owner/repo \ --title "Bug: Login fails with OAuth" \ --body "Detailed description..." \ --labels "bug,authentication" ``` ### Disable AI Features ```bash bun ~/eon/cc-skills/plugins/gh-tools/scripts/issue-create.ts \ --body "Question: How to configure..." \ --no-ai ``` ## CLI Options | Option | Short | Description | | ----------- | ----- | ------------------------------- | | `--repo` | `-r` | Repository in owner/repo format | | `--body` | `-b` | Issue body content (required) | | `--title` | `-t` | Issue title (optional) | | `--labels` | `-l` | Comma-separated labels | | `--dry-run` | | Preview without creating | | `--no-ai` | | Disable AI features | | `--verbose` | `-v` | Enable verbose output | | `--help` | `-h` | Show help | ## Dependencies - `gh` CLI (required) - GitHub CLI tool - `gh-models` extension (optional) - Enables AI features ### Installing gh-models ```bash gh extension install github/gh-models ``` ## Permission Handling | Level | Behavior | | ----------- | --------------------------------------- | | WRITE/ADMIN | Full functionality | | TRIAGE | Can apply labels | | READ | Shows formatted content for manual copy | | NONE | Suggests fork workflow | ## Logging Logs to: `~/.claude/logs/gh-issue-create.jsonl` Events logged: - `preflight` - Initial checks - `type_detected` - Content type detection - `labels_suggested` - Label suggestions - `related_found` - Related issues search - `issue_created` - Successful creation - `dry_run` - Dry run completion ## Related Documentation - [Content Types Reference](./references/content-types.md) - [Label Strategy Reference](./references/label-strategy.md) - [AI Prompts Reference](./references/ai-prompts.md) ## Embedding Images in Issues GitHub Issues have **no API for programmatic image upload**. The web UI's drag-and-drop uses an internal S3 policy flow that is intentionally not exposed to API clients ([cli/cli#1895](https://github.com/cli/cli/issues/1895)). ### Preflight: Ensure Images Are Reachable The `?raw=true` URL resolves via `github.com` — if the image doesn't exist at that path on the remote, it silently 404s (broken image, no error). **Run this preflight before creating the issue:** ```bash # 1. Detect repo context OWNER_REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner') BRANCH=$(git rev-parse --abbrev-ref HEAD) VISIBILITY=$(gh repo view --json visibility -q '.visibility') # 2. Verify images are git-tracked (not gitignored) IMG_DIR="path/to/images" for f in ${IMG_DIR}/*.png; do git ls-files --error-unmatch "$f" >/dev/null 2>&1 \ || echo "WARNING: $f is NOT tracked by git (check .gitignore)" done # 3. Verify images are committed (not just staged or untracked) UNCOMMITTED=$(git diff --name-only HEAD -- "${IMG_DIR}/" 2>/dev/null) UNTRACKED=$(git ls-files --others --exclude-standard -- "${IMG_DIR}/" 2>/dev/null) if [[ -n "$UNCOMMITTED" || -n "$UNTRACKED" ]]; then echo "FAIL: Images not committed — commit and push first" echo " Uncommitted: ${UNCOMMITTED}" echo " Untracked: ${UNTRACKED}" exit 1 fi # 4. Verify commit is pushed to remote (local commits invisible to github.com) LOCAL_SHA=$(git rev-parse HEAD) REMOTE_SHA=$(git rev-parse "origin/${BRANCH}" 2>/dev/null) if [[ "$LOCAL_SHA" != "$REMOTE_SHA" ]]; then echo "FAIL: Local commits not pushed — run: git push origin ${BRANCH}" exit 1 fi # 5. Build image base URL IMG_BASE="https://github.com/${OWNER_REPO}/blob/${BRANCH}/${IMG_DIR}" echo "Image base URL: ${IMG_BASE}/.png?raw=true" echo "Repo visibility: ${VISIBILITY}" if [[ "$VISIBILITY" == "PRIVATE" ]]; then echo "NOTE: Images only visible to authenticated collaborators" fi ``` **Preflight checklist** (what each step catches): | Step | Check | Failure Mode | | ---- | ---------------------- | ------------------------------------------------ | | 1 | Repo context exists | No `OWNER_REPO` to build URLs | | 2 | Images are git-tracked | `.gitignore` silently excludes them | | 3 | Images are committed | Staged/untracked files don't exist on remote | | 4 | Commit is pushed | Local-only commits are invisible to `github.com` | | 5 | URL construction | Wrong branch name → 404 | ### URL Format: `?raw=true` vs `raw.githubusercontent.com` For images already committed and pushed, use `github.com/blob/...?raw=true` URLs — **not** `raw.githubusercontent.com`: ```markdown ![img](https://raw.githubusercontent.com/owner/repo/main/path/image.png) ![img](https://github.com/owner/repo/blob/main/path/image.png?raw=true) ``` **Scripting pattern** (batch images → issue body): ```bash IMG_BASE="https://github.com/${OWNER_REPO}/blob/${BRANCH}/${IMG_DIR}" gh issue create --title "Feedback with screenshots" --body "$(cat <` tag with a `user-attachments` CDN URL into the comment textarea 5. Script extracts the CDN URL and clears the textarea (no comment is actually posted) **Key implementation details** (GitHub's 2026 React comment composer): - Comment textarea selector: `textarea[placeholder="Use Markdown to format your comment"]` (dynamic React IDs — do NOT match by `id`) - File upload trigger: click the "Paste, drop, or click to add files" text, then intercept `page.waitForEvent("filechooser")` - Upload result format: `Image` (HTML `` tag, not `![](...)` markdown) - Old `textarea#new_comment_field` and `file-attachment input[type='file']` selectors no longer exist - Batch uploads: clear textarea between uploads with `textarea.fill("")` **Chrome CDP note**: `chromium.connectOverCDP()` fails with Chrome 136+ (WebSocket timeout). Use `chromium.launchPersistentContext()` with Playwright's bundled Chromium instead. Chrome 136+ also requires `--user-data-dir` for CDP (`DevTools remote debugging requires a non-default data directory`), making CDP impractical for reusing existing browser sessions. --- ## Troubleshooting ### "No repository context" Run from a git directory or use `--repo owner/repo` flag. ### Labels not suggested - Check if gh-models is installed: `gh extension list` - Verify repository has labels: `gh label list --repo owner/repo` - Check label cache: `ls ~/.cache/gh-issue-skill/labels/` ### AI features not working Install gh-models extension: ```bash gh extension install github/gh-models ``` ## Post-Execution Reflection After this skill completes, check before closing: 1. **Did the command succeed?** — If not, fix the instruction or error table that caused the failure. 2. **Did parameters or output change?** — If the underlying tool's interface drifted, update Usage examples and Parameters table to match. 3. **Was a workaround needed?** — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround. Only update if the issue is real and reproducible — not speculative.