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.
Resources
4Install
npx skillscat add ormidales/daemon Install via the SkillsCat registry.
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 excerptSuggested fix
Description of how to fix or improve, with corrected code example if possible.
// fixed codeAcceptance 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// ← replacecomments - If the user provided a milestone name → replace
nullwith that name as a string (e.g.const MILESTONE_NAME = "v1.2.0";). If not → leavenull - Issues grouped in
ISSUESby severity: MAJOR first, then MINOR, then PATCH, with separator comments - Each
bodyuses 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.mjsand usepresent_filesto share
Additional tips
- If multiple files are sent, analyze the interactions between files
- Use
README,package.json,pyproject.tomlto 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