Official Skills Installer
A custom automation pattern to scrape, download, clean, and register developer skills from officialskills.sh. Automatically formats whenToUse entries using action gerunds and integrates them with Next.js static params.
Install
curl -fsSL https://skills.vishalvoid.com/install official-skills-installer | bashArchitecture & Integration
To integrate over 250 skills across 35 different providers into this site, we built an automated pipeline. The pipeline first scrapes the master catalog on officialskills.sh, resolves GitHub source repositories, downloads raw markdown contents, structures them into TypeScript, rewrites the global array registry, and updates the sidebar filtering client state with matching brand SVG icons.
Core scrap & generation script
This Node.js script downloads the metadata from officialskills.sh, resolves GitHub repositories, downloads the skills, and writes cleaned files to data/external/.
// scratch/build-all-external-skills.js
const fs = require('fs');
const path = require('path');
const https = require('https');
// Custom logic for cleaning whenToUse (ensuring gerund verbs, min 5 items)
function cleanWhenToUse(items) {
// ensure gerund action words...
}// scratch/build-all-external-skills.js
const fs = require('fs');
const path = require('path');
const https = require('https');
// Custom logic for cleaning whenToUse (ensuring gerund verbs, min 5 items)
function cleanWhenToUse(items) {
// ensure gerund action words...
}Dynamic sidebar registration
The Next.js dynamic routes use a single page layout under app/skills/anthropic/[slug] to serve all external skills by matching their slugs, while the Sidebar filter state allows users to search across category tags and provider brands.
// components/SkillsClient.tsx
export default function SkillsClient({ skills }) {
const [provider, setProvider] = useState("All");
// filters all skills dynamically based on imported arrays
}// components/SkillsClient.tsx
export default function SkillsClient({ skills }) {
const [provider, setProvider] = useState("All");
// filters all skills dynamically based on imported arrays
}