ormidales

github-issue-generator

Analyzes source code sent by the user to generate relevant GitHub issues and create them via the GitHub API. Use this skill as soon as the user sends code (files, snippets, repos) and mentions GitHub, issues, bugs, improvements, or requests a code review. Works with all languages. Generates issues classified as major/minor/patch covering bugs, security, performance, refactoring, documentation, and tests. ALWAYS produce an executable .mjs file as the final output (e.g. create-github-issues.mjs). The .mjs file contains the labels, fully formatted issues with their complete template, and the Node.js code to create them via the GitHub API.

ormidales 0 Updated 2mo ago

Resources

4
GitHub

Install

npx skillscat add ormidales/daemon

Install via the SkillsCat registry.

SKILL.md

GitHub Issue Generator

This skill analyzes source code, generates structured GitHub issues classified by severity, then produces an executable .mjs file ready to run with node create-github-issues.mjs.


Step 1 — Deeply analyze the code

When the user sends code, read it entirely and carefully before generating anything. Actively look for issues in these categories:

Issue categories to detect

Category Examples
🐛 Bug / Error Incorrect logic, unhandled cases, potential runtime errors
🔒 Security Injections, hardcoded secrets, unvalidated data, misconfigured CORS
Performance N+1 queries, unnecessary loops, unreleased memory, heavy imports
🔧 Refactoring Duplicated code, overly long functions, unclear naming, tight coupling
📄 Documentation Public functions without JSDoc/docstring, missing README, undocumented parameters
🧪 Tests Critical functions without tests, uncovered edge cases, missing mocks
📦 Dependencies Outdated packages, known vulnerabilities, unused imports
🎨 Style / Conventions Style inconsistencies, failure to follow project conventions

Important rule

Only generate useful, non-trivial issues. Avoid:

  • Issues that are too vague ("improve the code")
  • Issues already resolved in the provided code
  • Duplicates
  • Nitpicks with no real impact

Step 2 — Classify each issue

Use the major / minor / patch system inspired by SemVer:

Level GitHub Label When to use
🔴 major major Blocks functionality, critical security flaw, possible data loss
🟡 minor minor Degraded feature, significantly impacted performance, non-blocking bug
🟢 patch patch Cosmetic improvement, minor refactoring, missing documentation

Also add a category label: bug, security, performance, refactoring, documentation, testing, dependencies


Step 3 — Issue template (REQUIRED, always follow exactly)

All issues (title, description, body, acceptance criteria) must be written in English.

Each issue must use this exact template in the body field of the .mjs file:

**Category**: bug | security | performance | refactoring | documentation | testing | dependencies
**Severity**: major | minor | patch
**File(s)**: `path/to/file.ext` (line X)

#### Description
Clear explanation of the problem or desired improvement.

#### Problematic code example
```lang
// relevant code excerpt

Suggested fix

Description of how to fix or improve, with corrected code example if possible.

// fixed code

Acceptance criteria

  • Criterion 1
  • Criterion 2
  • Criterion 3

The **title** of each issue follows this format: `[LEVEL] Short and descriptive title` (in English)

Examples:
- `[MAJOR] Memory leak — event listeners never removed in OrbitalCameraSystem`
- `[MINOR] ShaderCache builds full string before cache lookup on every frame`
- `[PATCH] DEFAULT_VERTEX_SOURCE exported without JSDoc`

---

## Step 4 — Present the summary to the user

First display a **summary** in the conversation:

📊 Analysis complete

🔴 Major: X issues
🟡 Minor: Y issues
🟢 Patch: Z issues

Total: N issues detected


Then display the titles of all issues grouped by severity (major first).

Ask the user:
1. Whether they want to modify/remove certain issues
2. Their GitHub repo (`owner/repository`) and their Personal Access Token (scope `repo`)
3. (Optional) A milestone **name** to associate with all issues (e.g. `v1.2.0`). The script will search for an existing milestone with that name; if none is found, it will automatically create it and link all issues to it. If the user doesn't want one, leave it empty.

---

## Step 5 — Generate the `.mjs` file (ALWAYS do this step)

**This is the main output of the skill.** After validation, generate `create-github-issues.mjs` following exactly this structure:

```javascript
#!/usr/bin/env node
/**
 * Script for automatically creating N GitHub issues for owner/repo
 * Usage: node create-github-issues.mjs
 * Requirements: Node.js 18+
 */

const TOKEN          = "GITHUB_TOKEN_HERE";  // ← replace with your actual token
const REPO           = "owner/repository";   // ← replace with your actual repo
const MILESTONE_NAME = null;                  // ← set to a milestone name (e.g. "v1.2.0") or leave null to skip
const BASE           = `https://api.github.com/repos/${REPO}`;

const HEADERS = {
  "Authorization": `Bearer ${TOKEN}`,
  "Content-Type":  "application/json",
  "Accept":        "application/vnd.github+json",
  "X-GitHub-Api-Version": "2022-11-28",
};

// ─── Labels ────────────────────────────────────────────────────────────────
const LABELS = [
  { name: "major",         color: "d73a4a", description: "Breaking change or critical issue" },
  { name: "minor",         color: "fbca04", description: "Non-blocking bug or significant performance issue" },
  { name: "patch",         color: "0075ca", description: "Cosmetic improvement or minor refactoring" },
  { name: "bug",           color: "ee0701", description: "Something isn't working" },
  { name: "security",      color: "e4e669", description: "Security issue" },
  { name: "performance",   color: "c5def5", description: "Performance issue" },
  { name: "refactoring",   color: "bfd4f2", description: "Code refactoring" },
  { name: "documentation", color: "0052cc", description: "Documentation improvement" },
  { name: "testing",       color: "5319e7", description: "Test coverage improvement" },
  { name: "dependencies",  color: "e4e669", description: "Dependency update or cleanup" },
];

// ─── Issues ────────────────────────────────────────────────────────────────
const ISSUES = [
  // ── MAJOR ──────────────────────────────────────────────────────────────
  {
    title: "[MAJOR] Descriptive issue title",
    labels: ["major", "bug"],
    body: `**Category**: bug
**Severity**: major
**File(s)**: \`src/file.ts\` (l.XX)

#### Description
Description of the problem.

#### Problematic code example
\`\`\`ts
// problematic code
\`\`\`

#### Suggested fix
\`\`\`ts
// fixed code
\`\`\`

#### Acceptance criteria
- [ ] Criterion 1
- [ ] Criterion 2`,
  },
  // ── MINOR ──────────────────────────────────────────────────────────────
  // ── PATCH ──────────────────────────────────────────────────────────────
];

// ─── Helpers ───────────────────────────────────────────────────────────────
async function apiPost(path, body) {
  const res = await fetch(`${BASE}${path}`, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify(body),
  });
  return { status: res.status, data: await res.json() };
}

async function apiGet(path) {
  const res = await fetch(`${BASE}${path}`, { headers: HEADERS });
  return { status: res.status, data: await res.json() };
}

async function sleep(ms) {
  return new Promise(r => setTimeout(r, ms));
}

async function resolveMilestone(name) {
  if (!name) return null;
  // Search existing milestones (open + closed) by name
  for (const state of ["open", "closed"]) {
    const { data } = await apiGet(`/milestones?state=${state}&per_page=100`);
    if (Array.isArray(data)) {
      const found = data.find(m => m.title === name);
      if (found) {
        console.log(`  🎯 Milestone found: "${name}" (#${found.number})`);
        return found.number;
      }
    }
  }
  // Not found → create it
  const { status, data } = await apiPost("/milestones", { title: name });
  if (status === 201) {
    console.log(`  ✨ Milestone created: "${name}" (#${data.number})`);
    return data.number;
  }
  console.log(`  ❌ Failed to create milestone "${name}": ${data.message}`);
  return null;
}

// ─── Main ──────────────────────────────────────────────────────────────────
console.log("🏷️  Creating labels…");
for (const label of LABELS) {
  const { status } = await apiPost("/labels", label);
  const icon = status === 201 ? "✅" : status === 422 ? "⏭️  (already exists)" : `❌ HTTP ${status}`;
  console.log(`  ${icon} ${label.name}`);
}

console.log("\n🔖 Resolving milestone…");
const milestoneNumber = await resolveMilestone(MILESTONE_NAME);

console.log("\n📝 Creating issues…");
const created = [];
const failed  = [];

for (const issue of ISSUES) {
  const payload = { ...issue };
  if (milestoneNumber !== null) payload.milestone = milestoneNumber;

  const { status, data } = await apiPost("/issues", payload);
  if (status === 201) {
    created.push({ title: issue.title, url: data.html_url, number: data.number });
    console.log(`  ✅ #${data.number} → ${data.html_url}`);
  } else {
    failed.push({ title: issue.title, status, message: data.message });
    console.log(`  ❌ FAILED (HTTP ${status}): ${data.message} — ${issue.title}`);
  }
  await sleep(300); // avoid secondary rate limit
}

console.log("\n─────────────────────────────────────────────");
console.log(`✅ Created : ${created.length} issues`);
console.log(`❌ Failed  : ${failed.length} issues`);
if (failed.length) {
  console.log("\nFailed issues:");
  failed.forEach(f => console.log(`  - [HTTP ${f.status}] ${f.title}\n    ${f.message}`));
}

Rules for generating the .mjs

  • All text in the file (titles, descriptions, issue bodies, acceptance criteria, code comments) must be in English
  • If the user provided their token and repo → integrate them directly into the file
  • If not → leave the placeholders "GITHUB_TOKEN_HERE" and "owner/repository" with // ← replace comments
  • If the user provided a milestone name → replace null with that name as a string (e.g. const MILESTONE_NAME = "v1.2.0";). If not → leave null
  • Issues grouped in ISSUES by severity: MAJOR first, then MINOR, then PATCH, with separator comments
  • Each body uses exactly the template from Step 3 (backticks escaped with ```)
  • Always include all 10 labels, even if some categories are not used in the issues
  • Always add the 300ms delay between each issue creation to avoid the GitHub rate limit
  • Save to /mnt/user-data/outputs/create-github-issues.mjs and use present_files to share

Additional tips

  • If multiple files are sent, analyze the interactions between files
  • Use README, package.json, pyproject.toml to understand the project context
  • Adapt the level of technical detail to the detected language
  • When in doubt about severity, lean downward (minor rather than major)
  • Never log the GitHub token in the console or in comments