@kody/skills
README.md
125 lines · 6.3 KB · Markdown@kody/skills
Official community helpers for a reusable agent skill registry.
Share this listing: https://kody.codes/@kody/skills
Intent
Give every Kody account a generic skills registry: store, retrieve, edit, version, and revert reusable skill documents (markdown). Agents discover skills with skill_list, then load them with skill_get. Edits go through skill_save (and delete/history/revert). Versioning is real git when the account uses a plain skills repo; otherwise the package keeps documents in its own packageStorage(). Success means a forked copy can list, read, dry-run a mutation, then write — without Kent-only skills, personal remotes, or a shared platform registry.
Live @kody/skills storage is the official package bucket. Fork first (or invoke your copy) so skills stay in your account.
Auth
Zero-auth. No OAuth, API key, or bot token.
- OAuth: not used. Do not open
https://kody.codes/connect/oauth?provider=skills. - Secrets: not used. Do not open
https://kody.codes/account/secrets/new?name=skills. - Required hosts: none.
- Scopes: none.
Agent setup
- Fork or install https://kody.codes/@kody/skills so the account owns a saved
skillspackage. Each fork starts with an empty registry. - Prefer static imports of your fork (
kody:@you/skills/...) so list/get/save use your bucket. The live official package is shared platform storage. - Discover with
skill_list, then load withskill_get({ id }). Do not guess skill ids. - Mutations (
skill_save,skill_delete,skill_revert,migrate-to-repo) acceptdryRun: true. Preview that way before a live write. - Optional git durable home:
repo_create({ name: "skills" }), push an initial commit viarepo_get_git_remote({ name: "skills", scope: "write" }), thenmigrate-to-repo({ switch_reads: true, dryRun: true })before switching. Do not hard-code another account's git remote.
Quickstart
import skillList from 'kody:@kody/skills/skill-list'
import skillGet from 'kody:@kody/skills/skill-get'
import skillSave from 'kody:@kody/skills/skill-save'
export default async function main() {
const preview = await skillSave({
id: 'my-skill',
path: 'SKILL.md',
content: '# My skill\n\nInstructions here…',
name: 'my-skill',
description: 'What this skill is for and when an agent should load it.',
dryRun: true,
})
const index = await skillList()
return { preview, index }
}After a confirmed live save:
import skillGet from 'kody:@kody/skills/skill-get'
const skill = await skillGet({ id: 'my-skill' })Version recovery:
import skillHistory from 'kody:@kody/skills/skill-history'
import skillRevert from 'kody:@kody/skills/skill-revert'
const history = await skillHistory({ id: 'my-skill', path: 'SKILL.md', limit: 10 })
await skillRevert({ version_id: history[0].version_id, dryRun: true })Bulk edits (git lane)
For multi-file refactors, skip per-file skill_save and edit the account's own plain repo:
repo_get_git_remote({ name: "skills", scope: "write" })- Clone locally, edit skill directories (
{id}/SKILL.md,{id}/skill.json, …) - Commit and push — plain repos are live-at-HEAD (no package publish step)
Kody enforces a 10 MiB per-file gate on session/file writes; the direct git lane is bounded only by Artifacts (~32 MiB per push pack).
Keeping list/search current
skill_getalways reads the live repo HEAD when the backend isrepo.skill_list/skill-searchuse a fastskills_indexprojection in package storage.skill_save/skill_deleteupdate that index in the same call.- Git-lane pushes to the plain
skillsrepo firerepo.pushed; this package resyncsskills_index. - Manual fallback:
import migrateToRepo from 'kody:@kody/skills/migrate-to-repo'thenmigrateToRepo({ dryRun: true }).
Exports
| Export | Input | Output |
|---|---|---|
./skill-list | none | Array<{ id, name, description, files: string[], updated_at }> — the agents' index |
./skill-get | { id, path? } | Without path: skill metadata + files: [{ path, content }]. With path: that one file |
./skill-save | { id, path, content, name?, description?, dryRun? } (name/description required on first create) | { id, path, version_saved, dryRun? } — commits when not dry-run |
./skill-delete | { id, path?, dryRun? } | With path: deletes one file. Without: deletes the whole skill |
./skill-history | { id, path?, limit? } | Array<{ version_id, path, replaced_at, content_length, commit_oid? }> — metadata only |
./skill-revert | { version_id, dryRun? } | Restores that revision via repo_restore + publish (or legacy snapshot) |
./skill-search | { query?, limit? } (retriever contract) | { results: [...] } — powers the package retriever |
./legacy-dump | none | Read-only dump of the pre-migration SQLite store |
./migrate-to-repo | { revisions?, switch_reads?, dryRun? } | Sync index from the skills repo; optionally flip reads to repo |
. | none | Package overview with the recommended agent flow |
Search integration (retriever)
The package declares a retriever under package.json#kody.retrievers with scopes ["search", "context"]. Matching is case-insensitive over skill name + description. ./skill-search reads the skills_index projection (budgeted ~250ms) and soft-fails empty if storage is slow.
Durable home layout
Optional plain repo name: skills (per account — create with repo_create, never copy another user's remote).
README.md
{skill-id}/
skill.json # name, description, created_at, updated_at, files[]
SKILL.md
...optional reference filesFresh forks start on the legacy packageStorage() tables (skills, skill_files, skill_versions). After you populate a skills repo, migrate-to-repo({ switch_reads: true }) points reads at the repo. Legacy tables stay intact.
Conventions
- Skill ids are lower-kebab-case (for example
writing-styleorcode-review). - Give each skill a
SKILL.mdentry file; add reference files alongside as needed. - Make
descriptioncomplete enough that an agent can decide fromskill_listalone whether to load the skill. - Do not bake personal skill documents, personal git remotes, or another account's registry into this package.