Extend an Adapter
Purpose #
Walk through adding a new skill template to @aidokit/adapter-claude-code (the canonical Strict adapter), keeping the dogfood byte-compare clean.
Big Picture #
The adapter is the emitter — it doesn't own the skill content, it formats it. New built-in skills land in @aidokit/base-skills; the adapter automatically picks them up through emitSkills(ctx, skills). Cardinal references: .docs/docs/specs/adapter-contract.md, concepts/kit-content-v4.md, concepts/dogfood-gate.md.
How It Works #
1. Add the skill body to @aidokit/base-skills #
# packages/base-skills/src/files/skills/my-new-skill.md
## Purpose
What this skill is for.
## When to use
...
## Steps
...
Note: the body is checked in without a leading # Title. The adapter's emitSkills re-adds the heading from SkillTemplate.name.
2. Register the skill in @aidokit/base-skills/src/skills.ts #
Add an entry to the metadata table:
{
id: 'my-new-skill',
name: 'My new skill',
preloadedBy: ['builder', 'tester-reviewer'],
required: false,
description: 'One-line description for SKILL.md frontmatter', // ADR-0013
allowedTools: ['Read', 'Grep'], // ADR-0013
}
@aidokit/base-skills reads src/files/skills/<id>.md and exposes the merged SkillTemplate via BASE_SKILLS.
3. Update the hand-built reference #
To keep the dogfood gate clean, add the same skill to the repository's own .claude/skills/:
mkdir -p .claude/skills/my-new-skill
# Write the same body with the # Title heading prepended and the SKILL.md frontmatter
The adapter will emit a SKILL.md with frontmatter built from description + allowedTools per ADR-0013; the hand-built file must match.
4. Build and test #
pnpm --filter @aidokit/base-skills build
pnpm --filter @aidokit/base-skills test
pnpm --filter @aidokit/adapter-claude-code test
pnpm --filter aidokit test test/integration/init-emit.test.ts
The integration test asserts skill count (≥18 skills); your new skill will bring it up by one.
5. Run the dogfood compare #
Locally:
# After build, run aidokit init in a temp dir, then diff against the repo's .claude/
mkdir /tmp/dog && cd /tmp/dog && git init
node /path/to/aidokit/packages/cli/dist/bin/aidokit.js init --adapter claude-code --stack node-ts --yes
diff -r /path/to/aidokit/.claude ./.claude
The diff should be empty (modulo documented variable-interpolation differences).
6. Add a changeset #
pnpm changeset
# minor bump for @aidokit/base-skills
# patch bump for @aidokit/adapter-claude-code if you also touched its code
Example: extending the adapter's emit logic #
If you need new behavior (not just new content), the same pattern applies but in the adapter package:
- Locate the relevant emit method (
emitSkills,emitRoles, etc.) inpackages/adapter-claude-code/src/emit/. - Modify the implementation. Keep the method synchronous (per ADR-0005 §5 — emission methods are pure computation; only IO-bound methods are async).
- Add unit tests for the new branch in
packages/adapter-claude-code/test/. - If the change affects emitted output, update the hand-built
.claude/to match. - Re-run the conformance harness and integration test.
- Changeset.
Common Mistakes #
- Editing
dist/files/directly — that directory is regenerated fromsrc/files/byscripts/copy-files.mjs. - Adding a non-deterministic field (timestamp, random id) — breaks
adapter.determinism.repeated-invocation-stableand the dogfood compare. - Forgetting to update the hand-built
.claude/— the dogfood gate will fail. - Adding a new write target outside
capabilityDeclarations.writesPaths— AD-STD-CAP-01 conformance check will fail. - Making
emitSkillsasync to do I/O — wrong place. Read templates fromsrc/files/via the synchronousfiles-resolver.
Checklist #
- [ ] Skill body in
packages/base-skills/src/files/skills/<id>.md(no# Title). - [ ] Metadata in
packages/base-skills/src/skills.ts(withdescription+allowedTools). - [ ] Hand-built
.claude/skills/<id>/SKILL.mdupdated to match. - [ ] Unit + integration tests pass.
- [ ] Conformance harness passes for
adapter-claude-code(still Strict). - [ ] Dogfood byte-compare clean.
- [ ] Changeset filed (minor for base-skills; patch for adapter if applicable).