References between skills
How one skill can mention another, what airskills tracks about it, and what it doesn't do
Skills can reference each other. If your SKILL.md body mentions
/changelog-parsing, airskills picks that up as a dependency and
tracks it server-side: who references whom, whether the referenced
skill still exists, whether it's private.
What this is not: an automatic installer. airskills add does NOT
pull in the skills your skill references. If you want a group of
skills to install together, that's what
skillsets are for.
Declaring a reference
Mention the slug in your SKILL.md body, prefixed with /:
This skill writes release emails using /house-tone for voice and
/changelog-parsing to extract entries from CHANGELOG.md.
Airskills picks up /house-tone and /changelog-parsing as
references when you push.
References inside fenced code blocks, inline backticks, markdown link
URLs, and a denylist of common command-or-path tokens (/tmp,
/clear, etc.) are ignored — only real references count.
What airskills does with references
- Dashboard: each skill's page lists what it references and what references it.
- Broken-ref detection:
airskills doctorflags references that point at skills that have been renamed, transferred, or archived. Renames are followed automatically because refs are stored byskill_id; transfers and archives surface as needing attention. - Public-publish warning:
airskills publishwarns if a public skill references private skills — consumers won't be able to resolve those.
What it does NOT do today
- No transitive install.
airskills add chrismdp/release-emailinstalls only that one skill. If it references/house-toneand you don't havehouse-toneinstalled, that's a broken ref the doctor will flag. Use a skillset if you want a group to land together.
Broken references
If a referenced skill is renamed,
transferred, or archived,
airskills pull mentions it:
! 1 broken ref(s) found. Run 'airskills doctor' for details.
airskills doctor distinguishes the cases:
- Renamed: the reference is followed automatically (
skill_idis stable across renames); doctor reports the new slug so you can update your text if you want it to read better. - Transferred (e.g. moved into an organization): the old slug is gone; doctor tells you the new namespace so you can update the reference.
- Archived: the skill is gone; remove the reference or find an alternative.
Cycles are fine
Skills are not code. If skill A references B and B references A back, both just load — the agent reads them both. We don't refuse cycles, we don't warn about them, and there's no parent-first install order to break because there's no transitive walker today anyway.
If a cycle feels uncomfortable, that's a design hint — maybe the two skills overlap and could merge, or the responsibilities want a different split. But that's a judgement call, not a constraint.
Deep dive: what the server actually stores
For curious developers — skip if you just want to use it.
On every skill push the platform's archive route extracts /slug
references from the SKILL.md body (skipping frontmatter, fenced code
blocks, inline code spans, markdown link URLs, and the
REF_SLUG_DENYLIST of filesystem and built-in command paths) and
upserts rows into skill_dependencies (skill_id, depends_on, slug).
Resolution prefers the owner's current skills first, then falls back
to skill_slug_redirects so references survive a transfer.
Self-references are silently skipped. There is no cycle check — not in the CLI, not in the upsert, not as a database constraint. Because the dashboard reads from the table directly and the CLI doesn't walk the graph for installation, cycles are inert.
airskills doctor runs a parallel extractor on local content
(cmd/doctor.go:extractRefSlugs) and queries the server for each
referenced slug's current status. The CLI and server extractors are
kept in sync and share the same denylist.
Was this page helpful?