← Public packages
@kentcdodds/skills
Store, retrieve, edit, version, and revert reusable agent skill documents via skillList then skillGet.
AGENTS.md
117 lines · 3.9 KB · Markdown@kentcdodds/skills — agent notes
Human setup and intent live in README.md. This file is for
agents: imports, smoke checks, snippets, and edge cases. No user secrets.
Do not disable live webhooks or jobs (including the repo.pushed index sync).
Secrets
None. Durable state is packageStorage (SQLite). Do not require a plain Kody
repo named skills for skillGet.
Import paths
| Export | Import |
|---|---|
| overview | kody:@kentcdodds/skills |
| skill-list | kody:@kentcdodds/skills/skill-list |
| skill-get | kody:@kentcdodds/skills/skill-get |
| skill-save | kody:@kentcdodds/skills/skill-save |
| skill-delete | kody:@kentcdodds/skills/skill-delete |
| skill-history | kody:@kentcdodds/skills/skill-history |
| skill-revert | kody:@kentcdodds/skills/skill-revert |
| skill-search (retriever) | kody:@kentcdodds/skills/skill-search |
| legacy-dump | kody:@kentcdodds/skills/legacy-dump |
| migrate-to-repo | kody:@kentcdodds/skills/migrate-to-repo |
| use-package-storage | kody:@kentcdodds/skills/use-package-storage |
| on-repo-pushed | kody:@kentcdodds/skills/on-repo-pushed |
Prefer static imports from execute. Do not lead with packages.invoke.
Agent flow: skillList then skillGet.
Smoke test (read-only)
import skillList from 'kody:@kentcdodds/skills/skill-list'
export default async function main() {
return await skillList()
// => [{ id, name, description, files, updatedAt }, ...]
}Load one known skill (read-only):
import skillGet from 'kody:@kentcdodds/skills/skill-get'
export default async function main() {
return await skillGet({ id: 'kent-writing-voice' })
}Retriever soft-fail path:
import skillSearch from 'kody:@kentcdodds/skills/skill-search'
export default async function main() {
return await skillSearch({ query: 'writing voice', limit: 5 })
// => { results: [...] } or empty on budget miss
}Mutations (no dryRun)
skillSave / skillDelete / skillRevert write immediately. Prefer
read-only list/get for smoke. First create requires name and description:
import skillSave from 'kody:@kentcdodds/skills/skill-save'
export default async function main() {
return await skillSave({
id: 'temp-agent-smoke',
path: 'SKILL.md',
content: '# temp\n\nDelete me.',
name: 'temp-agent-smoke',
description: 'Temporary smoke skill — safe to delete.',
})
}Version recovery:
import skillHistory from 'kody:@kentcdodds/skills/skill-history'
import skillRevert from 'kody:@kentcdodds/skills/skill-revert'
export default async function main() {
const history = await skillHistory({
id: 'temp-agent-smoke',
path: 'SKILL.md',
limit: 10,
})
if (!history[0]) return { ok: false, reason: 'no history' }
return await skillRevert({ versionId: history[0].versionId })
}Edge cases
- Durable home is packageStorage. Package workflows must not open a user
plain
skillsrepo for ordinary get/list/save. - Forkers start empty.
./use-package-storagecopies from a leftover plainskillsrepo into SQLite and switches reads/writes tolegacy. skillList/skill-searchuse theskills_indexprojection (~250ms budget); search soft-fails to{ results: [] }if storage is slow.skillGetreads live content.skillSave/skillDeleteupdate the index in the same call. If a plainskillsrepo still receives git pushes,repo.pushed→./on-repo-pushedresyncs the index — do not disable that subscription.- Skill ids: lower-kebab-case. Prefer a
SKILL.mdentry file; makedescriptioncomplete enough to choose fromskillListalone. ./legacy-dumpis read-only../migrate-to-reposyncs projections and can optionally switch reads; it never deletes legacy tables.- Public TS API fields are camelCase (
updatedAt,versionId, …). SQLite column names stay snake_case;repo.pushedwire payloads stay snake_case.