src/autoskillit/skills_extended/prepare-issue/SKILL.md
Create a single GitHub issue and immediately triage it — dedup check, classification (recipe:implementation or recipe:remediation), mixed-concern detection, and label application. Use when user says "open an issue", "create an issue", "file an issue", or "file a bug". The user-facing counterpart to report_bug.
npx skillsauth add talont-org/autoskillit prepare-issueInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create a GitHub issue and immediately triage it with LLM classification.
/autoskillit:prepare-issue directly/autoskillit:prepare-issue [--issue N] [--split] [--dry-run] [--repo owner/repo] [description...]
description... — free-form text describing the problem or feature (becomes issue title + body)--issue N — adopt and triage an existing unlabeled issue instead of creating new--split — when mixed concerns detected, create sub-issues automatically--dry-run — show classification and labels without creating or editing anything--repo owner/repo — target repository (falls back to gh default repo context)Parse ARGUMENTS for:
--issue N → set issue_number = N, skip dedup--split → set split = true--dry-run → set dry_run = true--repo owner/repo → set repo = "owner/repo"descriptionAfter parsing arguments, check whether the description is a validated audit report:
description is a file path (relative or absolute) pointing to an existing .md file,
read the first non-blank line of that file. If the file cannot be read (e.g., permission
error), skip to case 4 and set is_validated_report = false.\r), is
exactly validated: true, set is_validated_report = true and record
report_path = description.description itself (not a file path) begins with validated: true (after stripping
trailing whitespace) as its first non-blank line, set is_validated_report = true and
treat description as the report content directly.is_validated_report = false.When is_validated_report = true:
is_validated_report = true): skip requirement generation entirely.requirements_generated: false in the final result block.gh auth status
Fail fast with a clear error if authentication is not available.
If --repo owner/repo was provided, use it. Otherwise rely on gh's default repo context.
Confirm access:
gh repo view --json owner,name
--issue N provided)Extract multiple keyword sets from the description — individual key terms and 2–3 phrase combinations that capture the core topic. For each keyword set, search all issues:
gh issue list --state all --search "{keyword-set}" \
--json number,title,url,body,labels,state --limit 15
labelsis returned as an array of objects[{"name": "..."}]bygh. Extract label names as a flat list when classifying eligibility.
Run searches for each keyword set and deduplicate results by issue number, tracking the
match_count (number of keyword sets that matched) per candidate.
After deduplication, apply a relevance gate to closed issues: include a closed issue as a candidate only if it was matched by two or more keyword sets. Open issues are included regardless of match count (same threshold as before). Discard single-match closed results — they are likely false positives.
Classify each surviving candidate as extend-eligible or informational-only:
| Condition | Classification |
|-----------|---------------|
| state == open AND no in-progress label AND no staged label | extend-eligible |
| state == open AND has in-progress label | informational-only |
| state == open AND has staged label | informational-only |
| state == closed | informational-only |
Assign sequential numbers [1], [2], … only to extend-eligible candidates.
Informational-only candidates receive a [—] marker.
If candidates are found, display them with state annotations per candidate:
━━━ Possible Duplicates Found ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[1] #{number} — {title} (open)
{url}
[—] #{number} — {title} (in-progress)
{url}
[—] #{number} — {title} (closed)
{url}
Options:
[1]–[{N}] Add to / extend an existing issue (only shown if extend-eligible candidates exist)
C Create a new issue anyway
Your choice [C]:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If no extend-eligible candidates exist (all are informational-only), omit the [N]
option entirely — only C appears.
If the user enters C (or presses Enter): Continue to Step 4a.
If the user enters a number corresponding to an extend-eligible candidate (extend existing):
ts=$(date +%Y-%m-%d_%H%M%S)
EDIT_BODY_FILE="{{AUTOSKILLIT_TEMP}}/prepare-issue/edit_body_${ts}.md"
mkdir -p "{{AUTOSKILLIT_TEMP}}/prepare-issue"
gh issue view {selected_number} --json body -q .body > "${EDIT_BODY_FILE}"
printf '\n## Additional Context\n\n%s' "{description}" >> "${EDIT_BODY_FILE}"
gh issue edit {selected_number} --body-file "${EDIT_BODY_FILE}"
issue_number = selected_number (no new issue will be created).gh issue view {selected_number} --json number,title,body,labels,url
If no candidates found: Continue directly to Step 4a.
Before creating any new issue, display the proposed title and body to the user and wait for explicit approval:
━━━ Draft Issue ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Title: {title}
Body:
{body}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Create this issue? [Y/n/edit]
prepare-issue-result block with "aborted": true and exit.This gate fires for every new-issue creation path. Skip this step when --issue N is
provided (adopting an existing issue) or when --dry-run is active.
Creating new:
Validated audit report input (is_validated_report = true):
Derive the issue title from the validated report's H1 heading: strip the leading #
and use the result verbatim.
Apply all strip transforms in a single deterministic shell pipeline:
ts=$(date +%Y-%m-%d_%H%M%S)
ISSUE_BODY_FILE="{{AUTOSKILLIT_TEMP}}/prepare-issue/issue_body_${ts}.md"
mkdir -p "{{AUTOSKILLIT_TEMP}}/prepare-issue"
grep -v 'validated: true' "$report_path" \
| grep -v '\.autoskillit/' \
| grep -v 'contested_findings_' \
| grep -v '| CONTESTED |' \
| grep -v '| VALID BUT EXCEPTION WARRANTED |' \
| sed 's/ | \*\*Contested:\*\* [0-9][0-9]*//' \
| sed 's/ | \*\*Exception warranted:\*\* [0-9][0-9]*//' \
> "${ISSUE_BODY_FILE}" || { echo 'ERROR: failed to process report_path'; exit 1; }
# Strip the ## Findings with Exceptions section entirely:
awk '/^## Findings with Exceptions/{skip=1} skip && /^---/{skip=0; next} !skip' \
"${ISSUE_BODY_FILE}" > "${ISSUE_BODY_FILE}.tmp" \
&& mv "${ISSUE_BODY_FILE}.tmp" "${ISSUE_BODY_FILE}"
# Defensive strip: remove any finding detail section that contains an exception note
# (guards against exception-warranted findings leaking inline into ## Validated Findings)
awk '
/^\*\*Exception note:\*\*/ { in_exception=1; next }
in_exception && /^---$/ { in_exception=0; next }
in_exception && /^## / { in_exception=0 }
!in_exception
END { in_exception=0 }
' "${ISSUE_BODY_FILE}" > "${ISSUE_BODY_FILE}.tmp" \
&& mv "${ISSUE_BODY_FILE}.tmp" "${ISSUE_BODY_FILE}"
What each transform removes:
validated: true — YAML front-matter sentinel (not content).autoskillit/ lines — all artifact paths (**Original report:** and any future variants)contested_findings_ lines — footer reference to the excluded-findings file| CONTESTED | rows — CONTESTED verdict rows from ## Validation Status table| VALID BUT EXCEPTION WARRANTED | rows — exception verdict rows from ## Validation Status| **Contested:** N and | **Exception warranted:** N — count segments from the
**Findings processed:** summary line; leaves **Findings processed:** {total} | **Valid:** {N}## Findings with Exceptions through next --- — the entire exception-findings section**Exception note:** blocks — exception-warranted finding detail sectionsCall gh issue create using the temp file:
gh issue create \
--title "{title}" \
--body-file "${ISSUE_BODY_FILE}"
Capture the returned issue URL and extract the issue number from it.
The resulting body contains only actionable, VALID findings: the H1 title, the
## Validation Status table (VALID rows only), and the ## Validated Findings section.
No artifact paths, no contested content, no exception-warranted content.
Standard input (is_validated_report = false):
Derive a concise title (first sentence of description, max 80 chars) and a structured body from the full description:
gh issue create \
--title "{title}" \
--body "{body}"
Capture the returned issue URL and extract the issue number from it.
Adopting existing (--issue N):
gh issue view N --json number,title,body,labels,url
Use the fetched data as the issue context.
Shortcut — Validated audit report: When is_validated_report = true (set in Step 1b),
immediately assign:
route = implementationissue_type = enhancementconfidence = highrationale = "Validated audit report — structural/quality improvement work, not broken behavior"Skip the heuristic table below and proceed directly to Step 7.
Analyze the issue title + body using in-context reasoning for all other inputs:
| Signal | Route | Issue Type |
|--------|-------|------------|
| Existing behavior broken / error traceback present | remediation | bug |
| New feature / enhancement with clear acceptance criteria | implementation | enhancement |
| "X doesn't support Y" / clearly absent feature | implementation | enhancement |
| Validated audit report with structural/quality findings (finding IDs present, no tracebacks, no crashes) | implementation | enhancement |
| Large/ambiguous scope / unclear root cause | remediation | enhancement |
Record: route (implementation|remediation), issue_type (bug|enhancement),
confidence (high|low), rationale (one sentence).
Note: The audit-signal table row is a secondary defense for --issue N adoption of pre-existing validated audit issues where is_validated_report may not be set.
If confidence == "low":
Skip entirely when is_validated_report = true — the validated report IS the
specification. No requirements section will be generated or appended.
Set requirements_generated: false in the result block and proceed directly to Step 8.
Skip if route is recipe:remediation — proceed directly to Step 8.
If route is recipe:implementation:
**REQ-{GRP}-NNN:** {single-sentence condition}.
gh issue view {N} --json body -q .body
## Requirements section already exists in the body: skip (idempotent).--dry-run is set: print the generated requirements to stdout but do NOT call
gh issue edit. Set requirements_generated: true, requirements_appended: false.ts=$(date +%Y-%m-%d_%H%M%S)
EDIT_BODY_FILE="{{AUTOSKILLIT_TEMP}}/prepare-issue/edit_body_${ts}.md"
REQUIREMENTS_FILE="{{AUTOSKILLIT_TEMP}}/prepare-issue/requirements_${ts}.md"
mkdir -p "{{AUTOSKILLIT_TEMP}}/prepare-issue"
# Fetch current issue body to temp file (avoids shell interpolation):
gh issue view {N} --json body -q .body > "${EDIT_BODY_FILE}"
# Populate ${REQUIREMENTS_FILE} with the generated requirements content, then:
printf '\n\n## Requirements\n\n' >> "${EDIT_BODY_FILE}"
cat "${REQUIREMENTS_FILE}" >> "${EDIT_BODY_FILE}"
gh issue edit {N} --body-file "${EDIT_BODY_FILE}"
requirements_generated: false.requirements_generated: true, requirements_appended: true.Examine whether the issue blends distinct concern categories (e.g., bug fix + new feature, investigation + implementation work). Criteria: the issue describes two separate, independently-completable outcomes.
If mixed concerns detected:
--split is set: create a sub-issue for each concern via gh issue create,
link them back to the parent with a comment, and track all sub-issue numbers.If --dry-run: skip this step, print a preview of what would be applied, emit result
block, exit.
Otherwise:
# Ensure labels exist (idempotent)
gh label create "recipe:implementation" --force \
--description "Route: proceed directly to implementation" \
--color "0E8A16"
sleep 1 # Rate-limit discipline: 1s between mutating calls
gh label create "recipe:remediation" --force \
--description "Route: investigate/decompose before implementation" \
--color "D93F0B"
sleep 1 # Rate-limit discipline: 1s between mutating calls
gh label create "bug" --force \
--description "Existing behavior is broken" \
--color "d73a4a"
sleep 1 # Rate-limit discipline: 1s between mutating calls
gh label create "enhancement" --force \
--description "New feature or request" \
--color "a2eeef"
sleep 1 # Rate-limit discipline: 1s between mutating calls
# Apply triage labels (use the route determined in Step 6)
gh issue edit {issue_number} --add-label "recipe:implementation"
sleep 1 # Rate-limit discipline: 1s between mutating calls
# or, for remediation route:
gh issue edit {issue_number} --add-label "recipe:remediation"
sleep 1 # Rate-limit discipline: 1s between mutating calls
gh issue edit {issue_number} --add-label "{issue_type}"
NEVER:
recipe:implementation, recipe:remediation, bug, enhancement)--issue N is provided)gh auth status fails--issue N or --dry-run is active)--body inline for the validated-report gh issue create — always write the
stripped body to {{AUTOSKILLIT_TEMP}}/prepare-issue/issue_body_{timestamp}.md and
pass --body-file (prevents LLM paraphrase, shell truncation, and special-character injection)--body shell substitution (--body "$(...)) for gh issue edit — always write to
{{AUTOSKILLIT_TEMP}}/prepare-issue/req_body_{timestamp}.md and use --body-fileALWAYS:
gh repo view before any issue operations--force on all gh label create calls for idempotency---prepare-issue-result---) even on dry-run--dry-run: never create or edit anything when this flag is setEmit to stdout for recipe capture:
---prepare-issue-result---
{
"issue_url": "https://github.com/owner/repo/issues/N",
"issue_number": N,
"route": "recipe:implementation",
"issue_type": "enhancement",
"confidence": "high",
"rationale": "...",
"labels_applied": ["recipe:implementation", "enhancement"],
"dry_run": false,
"sub_issues": [],
"requirements_generated": true,
"requirements_appended": true
}
---/prepare-issue-result---
Also emit the issue URL as a standalone structured token for recipe capture:
issue_url = https://github.com/owner/repo/issues/N
development
Generate YAML recipes for .autoskillit/recipes/. Use when user says "make script skill", "generate script", "script a workflow", "write a script", "create a script", "new recipe", "write a pipeline", or when loaded by other skills for script formatting.
data-ai
Create Uncertainty Representation visualization planning spec showing error bar definitions, distribution-aware alternatives, and multi-seed variance protocols. Statistical lens answering "How is uncertainty honestly represented?"
data-ai
Create Temporal Dynamics visualization planning spec showing axis scaling (linear vs log), smoothing disclosure, epoch/step alignment, run aggregation (mean + variance bands), early-stopping markers, and wall-clock vs step-count x-axis. Temporal lens answering "Are training dynamics shown clearly and honestly?"
data-ai
Create Narrative Story Arc visualization planning spec showing visual consistency across the report (same color = same model everywhere), logical figure progression, redundant figure detection, and narrative dependency between figures. Narrative lens answering "Do the figures tell a coherent story across the report?"