How to pick one
Skills are named after the intent you bring to them. Reviewing something? /critique or /audit. Fixing type? /typeset. Last-mile pass before shipping? /polish. The categories below group skills by the job.
${categoriesHtml}
`;
}
/**
* Wrap sidebar + main content in the docs-browser layout shell.
*/
function wrapInDocsLayout(sidebarHtml, mainHtml) {
return `
How to read this
Rules are grouped by the section of the /impeccable skill that teaches the pattern to avoid. AI slop rules flag the specific visual tells (gradient text, purple palettes, side-tab borders, nested cards). Quality rules flag general design mistakes that are not AI-specific but still hurt the work.
${sectionsHtml}
`;
}
/**
* Entry point. Generates all sub-page HTML files.
*
* @param {string} rootDir
* @returns {Promise<{ files: string[] }>} list of generated file paths (absolute)
*/
export async function generateSubPages(rootDir) {
const data = await buildSubPageData(rootDir);
const outDirs = {
skills: path.join(rootDir, 'public/skills'),
antiPatterns: path.join(rootDir, 'public/anti-patterns'),
tutorials: path.join(rootDir, 'public/tutorials'),
};
// Fresh output dirs each time so stale files don't linger.
for (const dir of Object.values(outDirs)) {
if (fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true });
fs.mkdirSync(dir, { recursive: true });
}
const generated = [];
// Skills index: docs-browser layout with unified sidebar.
{
const sidebar = renderDocsSidebar(data.skillsByCategory, data.tutorials, null);
const main = renderSkillsOverviewMain(data.skillsByCategory);
const html = renderPage({
title: 'Skills | Impeccable',
description:
'21 commands that teach your AI harness how to design. Browse by category: create, evaluate, refine, simplify, harden, system.',
bodyHtml: wrapInDocsLayout(sidebar, main),
activeNav: 'docs',
canonicalPath: '/skills',
bodyClass: 'sub-page skills-layout-page',
});
const out = path.join(outDirs.skills, 'index.html');
fs.writeFileSync(out, html, 'utf-8');
generated.push(out);
}
// Skills detail pages: same docs-browser shell as the overview.
for (const skill of data.skills) {
const sidebar = renderDocsSidebar(data.skillsByCategory, data.tutorials, { kind: 'skill', id: skill.id });
const main = renderSkillDetail(skill, data.knownSkillIds);
const title = `/${skill.id} | Impeccable`;
const description = skill.editorial?.frontmatter?.tagline || skill.description;
const html = renderPage({
title,
description,
bodyHtml: wrapInDocsLayout(sidebar, main),
activeNav: 'docs',
canonicalPath: `/skills/${skill.id}`,
bodyClass: 'sub-page skills-layout-page',
});
const out = path.join(outDirs.skills, `${skill.id}.html`);
fs.writeFileSync(out, html, 'utf-8');
generated.push(out);
}
// Anti-patterns index: single page, docs-browser shell with TOC sidebar.
{
const grouped = groupRulesBySection(data.rules);
const sidebar = renderAntiPatternsSidebar(grouped);
const main = renderAntiPatternsMain(grouped, data.rules.length);
const html = renderPage({
title: 'Anti-patterns | Impeccable',
description: `${data.rules.length} deterministic detection rules that flag the visible tells of AI-generated interfaces and common quality issues. Used by npx impeccable detect and the browser extension.`,
bodyHtml: wrapInDocsLayout(sidebar, main),
activeNav: 'anti-patterns',
canonicalPath: '/anti-patterns',
bodyClass: 'sub-page skills-layout-page anti-patterns-page',
});
const out = path.join(outDirs.antiPatterns, 'index.html');
fs.writeFileSync(out, html, 'utf-8');
generated.push(out);
}
// Tutorials index (under the unified Docs umbrella).
if (data.tutorials.length > 0) {
const sidebar = renderDocsSidebar(data.skillsByCategory, data.tutorials, null);
const main = renderTutorialsIndexMain(data.tutorials);
const html = renderPage({
title: 'Tutorials | Impeccable',
description: `${data.tutorials.length} short, opinionated walk-throughs of the highest-leverage Impeccable workflows.`,
bodyHtml: wrapInDocsLayout(sidebar, main),
activeNav: 'docs',
canonicalPath: '/tutorials',
bodyClass: 'sub-page skills-layout-page tutorials-page',
});
const out = path.join(outDirs.tutorials, 'index.html');
fs.writeFileSync(out, html, 'utf-8');
generated.push(out);
}
// Tutorial detail pages.
for (const tutorial of data.tutorials) {
const sidebar = renderDocsSidebar(data.skillsByCategory, data.tutorials, { kind: 'tutorial', slug: tutorial.slug });
const main = renderTutorialDetail(tutorial, data.knownSkillIds);
const html = renderPage({
title: `${tutorial.title} | Tutorials | Impeccable`,
description: tutorial.description || tutorial.tagline || '',
bodyHtml: wrapInDocsLayout(sidebar, main),
activeNav: 'docs',
canonicalPath: `/tutorials/${tutorial.slug}`,
bodyClass: 'sub-page skills-layout-page tutorials-page',
});
const out = path.join(outDirs.tutorials, `${tutorial.slug}.html`);
fs.writeFileSync(out, html, 'utf-8');
generated.push(out);
}
return { files: generated };
}