Install
openclaw skills install @djc00p/gh-issue-writerDraft well-structured GitHub issues from a description, error, or idea. Supports bug reports, feature requests, enhancements, and tasks. Optionally submits directly via the GitHub CLI or API. Use when someone says "write a GitHub issue", "open an issue for", "file a bug", "create a feature request", or describes a problem that needs to be tracked.
openclaw skills install @djc00p/gh-issue-writerDraft clear, actionable GitHub issues from a brief description, error message, or idea. Covers bug reports, feature requests, enhancements, and tasks.
Ask (or infer from context):
git remote get-url origin if in a git dir, otherwise ask)If the user gives you enough context, proceed without asking — draft and show for confirmation.
Use the appropriate template below. Fill every field; omit sections only if genuinely not applicable.
## Description
<!-- Clear, one-paragraph summary of the problem. -->
## Steps to Reproduce
1.
2.
3.
## Expected Behavior
<!-- What should have happened? -->
## Actual Behavior
<!-- What actually happened? Include error messages verbatim. -->
## Environment
- OS:
- Browser / Runtime / Version:
- Relevant config or dependencies:
## Logs / Screenshots
<!-- Paste relevant logs, stack traces, or attach screenshots. -->
## Additional Context
<!-- Anything else that might help: related issues, recent changes, workarounds tried. -->
## Problem / Motivation
<!-- What problem does this solve? Why does it matter? -->
## Proposed Solution
<!-- Describe the feature clearly. What would it look like? How would it work? -->
## Alternatives Considered
<!-- Other approaches you thought about and why you ruled them out. -->
## Acceptance Criteria
- [ ]
- [ ]
## Additional Context
<!-- Mockups, related issues, prior art, links. -->
## Current Behavior
<!-- What does it do now? -->
## Desired Behavior
<!-- What should it do instead? -->
## Why This Matters
<!-- Impact: who benefits, how much, how often? -->
## Suggested Implementation
<!-- Optional: any technical ideas or constraints. -->
## What needs to be done
<!-- Clear, specific description of the work. -->
## Why / Context
<!-- Why is this needed now? What does it unblock? -->
## Definition of Done
- [ ]
- [ ]
Title format by type:
| Type | Pattern | Example |
|---|---|---|
| Bug | Bug: <what fails> on <where> | Bug: 500 on POST /login when payload missing field |
| Feature | Feature: <capability> for <who/where> | Feature: CSV export for admin reports |
| Enhancement | Enhance: <what> — <improvement> | Enhance: error messages — add field-level detail |
| Task | Task: <verb> <thing> | Task: upgrade Stripe SDK to v16 |
Rules:
Recommend labels based on type and content:
| Signal | Suggested Labels |
|---|---|
| Bug | bug, needs-repro |
| Feature | enhancement, feature-request |
| High impact / blocking | priority:high |
| Needs more info | needs-info |
| Good for contributors | good first issue |
| Security | security |
| Performance | performance |
| Docs | documentation |
Also suggest:
Show the complete draft:
**Title:** <title>
**Type:** Bug / Feature / Enhancement / Task
**Suggested labels:** bug, priority:high
**Suggested assignee:** (if known)
---
<full issue body>
---
Ask: "Does this look right? I can adjust the title, add details, or submit it directly."
Prerequisites for submission:
ghCLI (authenticated viagh auth login) — preferred pathGH_TOKENenv var — required for the curl API fallbackgit— used to detect the repo fromgit remote get-url originDrafting (Steps 1–5) works without any of these.
If the user says "submit", "create it", "go ahead", or similar:
gh issue create \
--repo owner/repo \
--title "<title>" \
--body "<body>" \
--label "bug,priority:high" \
--assignee "@me"
gh isn't available)curl -s -X POST \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/{owner}/{repo}/issues \
-d '{
"title": "<title>",
"body": "<body>",
"labels": ["bug"],
"assignees": []
}'
On success, output the issue URL. On error, show the response and offer to retry.
Before presenting the draft, verify:
Do:
#<number>Don't:
.github/ISSUE_TEMPLATE/ in your repoIssue content is user-supplied text. Never interpolate it into a shell command string or hand-write it into JSON.
Do not build shell commands by string concatenation. A title or body
containing quotes, backticks, $(...), or newlines can break out of the
argument and execute unintended commands. Pass values as separate arguments:
# WRONG - interpolates user text into a shell string
gh issue create --title "$TITLE" --body "$BODY"
# RIGHT - write the body to a file and let gh read it
BODY_FILE=$(mktemp)
trap 'rm -f "$BODY_FILE"' EXIT
cat > "$BODY_FILE" <<'ISSUE_BODY_EOF'
...issue body text goes here...
ISSUE_BODY_EOF
gh issue create \
--repo "OWNER/REPO" \
--title "Short issue title" \
--body-file "$BODY_FILE"
For the curl fallback, serialize the JSON with a real JSON encoder rather
than pasting placeholders into a JSON literal, and validate the repository
identifier before sending:
# WRONG - hand-written JSON with interpolated values
curl -s -X POST "https://api.github.com/repos/OWNER/REPO/issues" \
-H "Authorization: Bearer $GH_TOKEN" \
-d '{"title": "<title>", "body": "<body>"}'
# RIGHT - serialize with python so quoting and newlines are handled correctly
python3 - "$OWNER" "$REPO" "$TITLE" "$BODY_FILE" <<'PY_EOF'
import json, os, sys, urllib.request
owner, repo, title, body_file = sys.argv[1:5]
if not re.fullmatch(r"[A-Za-z0-9._-]+", owner) or not re.fullmatch(r"[A-Za-z0-9._-]+", repo):
sys.exit("invalid owner/repo identifier")
with open(body_file, encoding="utf-8") as f:
body = f.read()
payload = json.dumps({"title": title, "body": body}).encode()
req = urllib.request.Request(
f"https://api.github.com/repos/{owner}/{repo}/issues",
data=payload,
headers={"Authorization": f"Bearer {os.environ['GH_TOKEN']}",
"Accept": "application/vnd.github+json",
"Content-Type": "application/json"},
)
print(urllib.request.urlopen(req).read().decode())
PY_EOF
Before submitting, always confirm with the user: the target repository
(verify OWNER/REPO), the exact title, the full body, labels, and assignees.
Scrub secrets, API keys, tokens, and internal hostnames from the body first.