Agent skills for building on Solana — a curated registry of official skills from the Solana Foundation and Superteam Brasil (hosted verbatim, per-file) plus an explorer for ecosystem skill repositories (Jupiter, Helius, Metaplex, SendAI, Solana Mobile, Trail of Bits, Pyth, OKX, and more).
Unlike sites that reskin a single community aggregator, this registry indexes 30 independent source repositories — protocol-native ones included — every skill pinned to an immutable commit with published integrity hashes.
Built with Astro as a fully static site. No client framework — a few hundred bytes of vanilla JS for search, tabs, and copy buttons.
/— landing: official skills, three ways to use a skill, ecosystem highlights./skills— searchable catalog of every indexed skill (official pinned first, category filters)./skills/<id>— official skill detail: renderedSKILL.md, install tabs (skills CLI / Claude Code / no-install / git), companion-file tree, metadata./s/<id>/SKILL.md— per-file hosting: the official skill served verbatim withtext/markdown+ CORS, so any agent can consume it from a single URL — no install:(The legacy flat formRead https://kit.superteam.codes/s/solana-dev/SKILL.md and follow it for this task: …/s/<id>.md301s here; it survives as a plain-file fallback on hosts without redirect support, but its relative links only resolve from the dir-style URL.)/s/<id>/SKILL.md+/s/<id>/<companion>.md— dir-style hosting of the whole skill, companion reference files included, so relative links resolve and an agent can walk the entire skill without leaving the domain. Detail pages surface these as a Reference library (title + description parsed from each file's frontmatter)./skills/<repo-id>/<skill>— ecosystem skill detail: same layout as official pages (renderedSKILL.md, install tabs, file tree, vendor logo) with an explicit not official disclaimer./s/<repo-id>/<skill>/SKILL.md— ecosystem mirrors. Three hosting tiers:- Full (
sendaifun/skills,sendaifun/solana-new,solanabr/ai-kit):SKILL.mdverbatim + every companion.md, relative links resolve on-domain — same guarantee as official skills. - Partial (every other repo with a license):
SKILL.mdmirrored with relative links rewritten to GitHub URLs pinned at the indexed commit, plus a provenance comment; companions stay upstream. - Link-only (repos with no declared license): never republished — pages link to the pinned source instead.
- Full (
- Commit-SHA pinning, end to end — every skill on the site (official, ecosystem, and link-only community entries) is tied to an immutable git commit plus two timestamps: the upstream committer date (
commitDate) and when our refresh took the pin (pinnedAt). All mirrors are fetched at the pinned sha, all advertisedraw/githublinks point at the pinned sha (never a branch), and whole-dir install commands fetch GitHub's codeload tarball at the sha (degit can't resolve arbitrary commits — it only matches ref tips) — closing the window where upstream force-pushes or branch moves could swap content between review and install. Pins advance fail-closed: only after the content at the new sha is actually fetched, never on a metadata-only (--meta) run, and never by falling back to a branch ref — so a recorded commit always describes exactly what was mirrored. - Sanitized rendering — mirrored markdown is third-party content;
rehype-sanitizestrips raw HTML from every rendered detail page (the raw.mdmirrors under/s/are served untouched astext/markdown). (npx skills addpulls the repo's current HEAD — diff against the pin if that matters to you.) - Integrity hashes — every file mirrored on this domain publishes its
sha256in/api/skills.json(integrity, keyed by relative path). Verify any mirror withcurl -fsSL <url> | shasum -a 256; CI recomputes every hash against the built site on every PR and every refresh. - Contributor attribution — each skill records the GitHub login that last touched its
SKILL.mdas of the pin (lastAuthorin the API, "Last updated by" on detail pages), so monorepo skills credit the person who actually wrote them, not just the org. /superteam— official Superteam Brasil skills, part of the Solana AI Kit: a page per skill (/superteam/<id>) and per subskill (/superteam/<id>/<path>: auditor-skill's commands and agents, startup-builder-skill's skills). Every.mdin those repos is served at/s/<id>/<path>, and every page carries Copy .md / Open .md buttons, as do official and ecosystem skill pages and their reference files.- Contributors — the homepage counts distinct GitHub contributors (bots excluded) across every indexed repo, from each entry's
contributorslist. /ecosystem— ecosystem repo explorer grouped by aggregators/toolkits, teams & protocols, community; expandable per-repo skill lists that deep-link to the on-site detail pages./api/skills.json— machine-readable index of everything (CORS-enabled);/api/skills-min.jsonis the token-lean variant with one fetchable URL per skill (on-domain mirror preferred)./llms.txt— plain-text site map for AI agents./og/**.png— per-page social cards generated at build time (satori + resvg): Solana gradient, vendor logo, adaptive title.sitemap.xml,robots.txt, OpenGraph meta on every page.- Logos — GitHub org avatars are downloaded at refresh time into
public/logos/and shown on repo cards, catalog cards, and detail pages (no third-party requests at render time).
Everything renders from one committed snapshot:
src/data/registry.json # official skills + ecosystem repos/skills, stars, commit SHAs
src/data/skills/*.md # verbatim mirrors of official SKILL.md files
src/data/skill-files/<id>/… # verbatim mirrors of official companion .md files (reference library)
src/data/eco-skill-files/<repo>/<skill>/… # ecosystem mirrors (full or partial — see hosting tiers above)
src/data/stbr-files/<id>/… # Superteam Brasil: every .md in the repo, verbatim
src/data/stbr-render/<id>/… # the same main file and subskills, frontmatter removed, for page rendering
public/logos/<owner>.png # GitHub org avatars, refreshed with the registry
The snapshot keeps builds deterministic and the site immune to GitHub hiccups. It is refreshed by:
npm run refresh # full: mirrors, file trees, frontmatter, stars, new-skill discovery
node scripts/refresh.mjs --meta # cheap: stars + pushed_at onlyGITHUB_TOKEN is optional but raises rate limits; when a run hits the limit it waits for the hourly reset instead of failing. A weekly GitHub Action (.github/workflows/refresh.yml) runs the full refresh and commits changes. It uses the REGISTRY_TOKEN repo secret when set (a fine-grained token with public read access, 5000 calls/h), else the Actions token (1000 calls/h); CI (ci.yml) builds every PR, asserts hosted files remain byte-identical mirrors, and re-verifies every advertised sha256 against the built output (scripts/verify-integrity.mjs).
The solana-ai-kit entry tracks solanabr/ai-kit at its highest vX.Y.Z tag ("pin": "release-tag"), which is what the kit's installer ships, not its branch head. "kitStats": true reads the kit at that tag: agents and commands from .claude/agents/*.md and .claude/commands/*.md, MCP servers from .mcp.json, core and extension packs from .claude/skills/skill-registry.json, the version from .claude/VERSION. They fill the placeholders in the entry's blurbTemplate, so the card's numbers are never typed by hand.
.github/workflows/kit-sync.yml runs node scripts/refresh.mjs --only solana-ai-kit,auditor-skill,startup-builder-skill every day at 07:23 UTC, about twenty API calls. It commits only when content changed (a new tag, skill, file or count), not for a star-count move. The kit can trigger it at release time with a repository_dispatch of type kit-release, sent with a token that can reach this repo. It shares a concurrency group with the weekly refresh, so the two never push at once.
registry.json → superteam entries are mirrored whole: refresh.mjs copies every .md (except .github/) at the pin, "pin": "release-tag" for a repo that tags releases. subskillRules (kind + path regex) pick the files that get their own page, countRules the figures on the skill page, main the file rendered there (SKILL.md, or README.md for a skill set), and install the tabs. A file whose frontmatter strict YAML rejects is still mirrored; pages render from the stripped copy, so it cannot break the build. To add one, append an entry with those fields plus id, repo, displayName, tagline, summary, category, kitPack, kitTier, then node scripts/refresh.mjs --only <id> and add the id to IDS in kit-sync.yml.
When the Foundation publishes a new skill repo, add an entry to registry.json → official (id, repo, dir, title, tagline, category) and run npm run refresh — mirror, frontmatter, file tree, and metadata fill in automatically.
Add an entry to registry.json → ecosystem (id, repo, displayName, vendor, type, categories, blurb), plus a path filter in scripts/refresh.mjs → SKILL_PATHS if its skills should be auto-discovered. The next npm run refresh discovers skills, mirrors them (per the licensing tiers above), downloads the org logo, and slugs everything for detail pages. Repos listed in the Foundation's awesome-solana-ai are the natural funnel.
npm install
npm run dev # http://localhost:4321
npm run build # static output in dist/
npm run previewDeploy dist/ to any static host (Vercel / Cloudflare Pages / Netlify — zero config, no server runtime).
The site is served at kit.superteam.codes, set as site in astro.config.mjs and SITE_URL in src/lib/registry.ts; every hosted-file URL, canonical link, social image and llms.txt line is built from it. superteam.codes is on Vercel's nameservers with a wildcard record, so adding the domain under the Vercel project's Settings → Domains is the whole setup. The Solana AI Kit's installer stays at aikit.superteam.codes (curl -fsSL https://aikit.superteam.codes | bash), served by the kit's own Vercel project.
The site is published in English (the default, served at the root), Brazilian Portuguese (/pt-br) and Spanish (/es). Every page exists in every language, and the English URLs are unchanged. The skills themselves — SKILL.md bodies and mirrored files — stay in their original language, and the footer says so on translated pages; their titles, summaries and descriptions are translated (see Registry text below). The machine-readable files (/api/*, /llms.txt, /s/*, /og/*) are not translated.
- Locales are listed in
src/i18n/config.ts, with their<html lang>, hreflang, Open Graph andIntlcodes. - Strings live in
src/i18n/messages/<area>.ts, one file per area of the site, each exporting{ en, 'pt-br', es }. English is the reference: the other languages are typedtypeof en, so a missing or extra key is a type error, and the build fails with a list of differences if a key, an array length or a{token}doesn't line up. - In a page or component:
const { m, l, num, date } = i18n(Astro);, then{m.home.hero.sub},href={l('/skills')}(locale-aware link),{num(n)},{date(skill.pushedAt)}. - Inline markup (a link or
<code>inside a sentence) is a message with{token}s, rendered by<Rich text={…}>with one named slot per token — seehome.tsandsrc/components/Rich.astro. Slots are rendered by the page, so scoped styles keep working. - Registry text — skill titles, summaries and descriptions, and the titles and descriptions of reference files — arrives from the upstream repos in English and is refreshed weekly, so its translations live in
src/data/i18n/<locale>.json, keyed by the exact English text. Pages read them withtx(text)fromi18n(Astro). When upstream rewrites a sentence its key stops matching and the page shows the English until it is translated again.node scripts/i18n-content.mjsreports what is translated, missing or no longer used (--missinglists the strings still to translate,--listevery string the site shows). It never fails a build: a refresh can always add English text. - Routes: pages live under
src/pages/[...lang]/. English has no prefix (langisundefined), the others get/pt-br/…and/es/…. A page exportsgetStaticPaths = localeStaticPaths, or wraps its own paths inwithLocales(…). - SEO:
Base.astrosets<html lang>,og:locale, and hreflang alternates (with the English page asx-default); the sitemap lists every page in every language with its alternates.
To add a language: add it to LOCALES and LOCALE_META in src/i18n/config.ts, add a column to each file in src/i18n/messages/, and run npm run build — it names whatever is still missing.
Follows solana.com branding: black canvas, #9945FF → #14F195 brand gradient, Inter, pill buttons, glass cards. All tokens live in src/styles/global.css.
Site code: MIT. Skill content belongs to its authors under their repository licenses (each skill page links to its source and license).