# @kody/skills — agent notes Human setup and intent live in [`README.md`](./README.md). This file is for agents: imports, smoke/dryRun execute snippets, bulk git lane, and edge cases. Do not disable live webhooks or jobs (including the `repo.pushed` subscription that resyncs `skills_index`). ## Auth Zero-auth. No OAuth, secrets, or required hosts. Prefer static imports of **your** fork (`kody:@you/skills/...`). The live `@kody/skills` package bucket is shared platform storage. ## Import paths | Export | Import | | --- | --- | | package overview | `kody:@kody/skills` | | skill-list | `kody:@kody/skills/skill-list` | | skill-get | `kody:@kody/skills/skill-get` | | skill-save | `kody:@kody/skills/skill-save` | | skill-delete | `kody:@kody/skills/skill-delete` | | skill-history | `kody:@kody/skills/skill-history` | | skill-revert | `kody:@kody/skills/skill-revert` | | skill-search | `kody:@kody/skills/skill-search` | | legacy-dump | `kody:@kody/skills/legacy-dump` | | migrate-to-repo | `kody:@kody/skills/migrate-to-repo` | Prefer static `kody:@kody/skills/...` (or your fork) imports from `execute`. Do not lead with `packages.invoke`. Do not guess skill ids — list first. ## Smoke / quickstart ```js 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: ```js import skillGet from 'kody:@kody/skills/skill-get' export default async function main() { return await skillGet({ id: 'my-skill' }) } ``` Version recovery: ```js import skillHistory from 'kody:@kody/skills/skill-history' import skillRevert from 'kody:@kody/skills/skill-revert' export default async function main() { const history = await skillHistory({ id: 'my-skill', path: 'SKILL.md', limit: 10, }) return await skillRevert({ version_id: history[0].version_id, dryRun: true }) } ``` ## dryRun (mutations) `skill_save`, `skill_delete`, `skill_revert`, and `migrate-to-repo` accept `dryRun: true`. Preview that way before a live write. ## Bulk edits (git lane) For multi-file refactors, skip per-file `skill_save` and edit the account's own plain repo: 1. `repo_get_git_remote({ name: "skills", scope: "write" })` 2. Clone locally, edit skill directories (`{id}/SKILL.md`, `{id}/skill.json`, …) 3. 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_get` always reads the live repo HEAD when the backend is `repo`. - `skill_list` / `skill-search` use a fast `skills_index` projection in package storage. - `skill_save` / `skill_delete` update that index in the same call. - Git-lane pushes to the plain `skills` repo fire `repo.pushed`; this package resyncs `skills_index`. **Leave that subscription enabled.** - Manual fallback: `import migrateToRepo from 'kody:@kody/skills/migrate-to-repo'` then `migrateToRepo({ dryRun: true })`. ## Export shapes | Export | Input | Output | | --- | --- | --- | | `./skill-list` | none | `Array<{ id, name, description, files, updated_at }>` | | `./skill-get` | `{ id, path? }` | Without `path`: metadata + `files`. With `path`: that file | | `./skill-save` | `{ id, path, content, name?, description?, dryRun? }` | `{ id, path, version_saved, dryRun? }` — `name`/`description` required on create | | `./skill-delete` | `{ id, path?, dryRun? }` | One file or whole skill | | `./skill-history` | `{ id, path?, limit? }` | Version metadata only | | `./skill-revert` | `{ version_id, dryRun? }` | Restores that revision | | `./skill-search` | `{ query?, limit? }` | `{ results: [...] }` — package retriever | | `./legacy-dump` | none | Read-only pre-migration SQLite dump | | `./migrate-to-repo` | `{ revisions?, switch_reads?, dryRun? }` | Sync index; optionally flip reads to repo | ## Retriever / durable layout Retriever: `package.json#kody.retrievers` scopes `["search", "context"]`. Matching is case-insensitive over skill name + description. Soft-fails empty if storage is slow (~250ms budget). Optional plain repo name: **`skills`** (per account — `repo_create`, never copy another user's remote): ``` README.md {skill-id}/ skill.json SKILL.md ...optional reference files ``` Fresh forks start on legacy `packageStorage()` tables. After you populate a `skills` repo, `migrate-to-repo({ switch_reads: true })` points reads at the repo. Legacy tables stay intact. ## Conventions / edge cases - Skill ids are lower-kebab-case (for example `writing-style`). - Give each skill a `SKILL.md` entry file; add reference files alongside. - Make `description` complete enough that an agent can decide from `skill_list` alone whether to load the skill. - Do not bake personal skill documents, personal git remotes, or another account's registry into this package.