skilld 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,25 +2,25 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/skilld?color=yellow)](https://npmjs.com/package/skilld)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/skilld?color=yellow)](https://npm.chart.dev/skilld)
5
- [![license](https://img.shields.io/github/license/harlan-zw/skilld?color=yellow)](https://github.com/harlan-zw/skilld/blob/main/LICENSE)
5
+ [![license](https://img.shields.io/npm/l/skilld?color=yellow)](https://github.com/harlan-zw/skilld/blob/main/LICENSE)
6
6
 
7
- > Skilld gives your AI agent skills for your npm dependencies, generated from versioned docs, dist files and GitHub data.
7
+ > Expert SKILL.md knowledge for your NPM dependencies.
8
8
 
9
9
  ## Why?
10
10
 
11
- Agents already know how most packages work from training data. Skills should focus on what they *don't* know and push them to follow best practices. Without this:
11
+ Agents suck at following latest conventions beyond their [reliable knowledge cut-off](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison). They shoot themselves in the foot
12
+ with new APIs and conventions, and they don't know what they don't know.
12
13
 
13
- - **Generic patterns** - AI uses common approaches instead of package-specific conventions
14
- - **Missed best practices** - Optimal patterns go unused because the AI defaults to "good enough"
15
- - **Version drift** - Training data lags behind latest APIs and deprecations
14
+ [Agent Skills](https://agentskills.io/home) help us solve this by distilling the most important patterns and conventions for a package into a single SKILL.md file.
15
+ Getting skills for our packages either involves the maintainer (or ourselves) taking on the maintenance burden and surfacing them or using skill sharing
16
+ sites like [skills.sh](https://skills.sh/).
16
17
 
17
- skilld generates skills from the package's *actual* documentation using your existing agent. Works with any public npm package, no author opt-in needed.
18
+ While these are great for generic skills, they aren't good for NPM skills:
19
+ - No version-awareness, high maintenance burden to keep up with new releases and deprecations.
20
+ - Non-optimized context windows, prompt injection risks, missing references.
21
+ - Community-sourced skills leak personal opinions and biases. Maintainers are out of the loop, and may not even know about them.
18
22
 
19
- ```
20
- npm install vueuse → skilld add vueuse → AI knows current vueuse API
21
- ```
22
-
23
- Compatible with [skills-npm](https://github.com/antfu/skills-npm)—if a package ships a `skills/` directory, skilld uses it directly. Generation is the fallback.
23
+ Skilld leverages maintainers existing effort. Maintainers write great docs for us, we generate our own local skills optimized for our models and codebase from them.
24
24
 
25
25
  <p align="center">
26
26
  <table>
@@ -34,20 +34,42 @@ Compatible with [skills-npm](https://github.com/antfu/skills-npm)—if a package
34
34
 
35
35
  ## Features
36
36
 
37
- - 🤖 **Agent-powered** - Uses your existing LLM to generate SKILL.md for your key dependencies; works with any coding agent
38
- - 🎯 **Best practices first** - Token-optimized output focused on non-obvious patterns and conventions, not generic knowledge
39
- - 🔗 **Context-aware** - Generation adapts to your preferences and accepts custom prompts
40
- - ✏️ **You own it** - Skills live in your project, easy to customize; sync new package versions with zero config
41
- - 🛡️ **Sanitized content** - All fetched markdown is sanitized against known injection patterns (zero-width chars, HTML injection, entity encoding, directive lines) before reaching your agent
42
- - 🚀 **Zero friction** - Works with any public npm package, no author opt-in; respects `llms.txt` and shipped `skills/` when available
37
+ - 🌍 **Full Context SKILL.md** - Generates with the repo code, docs, releases, issues, discussions
38
+ - 🤖 **BYO Agent** - Generate SKILL.md with or without an LLM
39
+ - 📚 **Customizable** - `Best practices`, `LLM Gaps`, `Doc Map` or your own prompts
40
+ - 🔍 **Semantic Search** - Token-optimized search via [retriv](https://github.com/harlan-zw/retriv)
41
+ - 🎯 **Safe** - Prompt injection sanitization, version-aware output
42
+ - 🤝 **Ecosystem** - [skills-npm](https://github.com/antfu/skills-npm) and `/llms.txt` support
43
+
44
+ ## Quick Start
45
+
46
+ Run skilld in a project to generate skills for your dependencies through a simple interactive wizard:
47
+
48
+ ```bash
49
+ npx skilld
50
+ ```
51
+
52
+ If you need to re-configure skilld, just run `npx skilld config` to update your agent, model, or preferences.
53
+
54
+ ### Tips
55
+
56
+ - **Be selective** — only add skills for packages your agent already struggles with or that you're actively debugging. Not every dependency needs a skill.
57
+ - **LLM enhancement is optional** — skilld generates a useful SKILL.md without any LLM, but enhancing with one makes them significantly better. This costs tokens, so be mindful.
58
+ - **Multi-agent support** — if you switch between agents (e.g. Claude Code and Gemini CLI), run `skilld install --agent gemini-cli` to sync your existing skills to the other agent. The doc cache is shared, so nothing is re-downloaded.
43
59
 
44
60
  ## Installation
45
61
 
62
+ If you'd like to install skilld and track the lock file references, add it as a dev dependency:
63
+
46
64
  ```bash
47
- pnpm add -g skilld
65
+ npm install -D skilld
66
+ # or
67
+ yarn add -D skilld
68
+ # or
69
+ pnpm add -D skilld
48
70
  ```
49
71
 
50
- ## Automatic Updates
72
+ ### Automatic Updates
51
73
 
52
74
  Add to `package.json` to keep skills fresh on install:
53
75
 
@@ -59,8 +81,6 @@ Add to `package.json` to keep skills fresh on install:
59
81
  }
60
82
  ```
61
83
 
62
- skilld fast-paths unchanged versions—only regenerates when minor/major versions bump.
63
-
64
84
  ## CLI Usage
65
85
 
66
86
  ```bash
@@ -68,27 +88,30 @@ skilld fast-paths unchanged versions—only regenerates when minor/major version
68
88
  skilld
69
89
 
70
90
  # Add skills for specific package(s)
71
- skilld add vueuse
72
91
  skilld add vue nuxt pinia
73
92
 
74
93
  # Update outdated skills
75
94
  skilld update
76
- skilld update vue
95
+ skilld update tailwindcss
77
96
 
78
97
  # Search docs across installed skills
79
98
  skilld search "useFetch options" -p nuxt
80
99
 
81
100
  # Target a specific agent
82
- skilld add vueuse --agent cursor
101
+ skilld add react --agent cursor
83
102
 
84
103
  # Install globally to ~/.claude/skills
85
- skilld add vueuse --global
104
+ skilld add zod --global
86
105
 
87
106
  # Skip prompts
88
- skilld add vueuse --yes
107
+ skilld add drizzle-orm --yes
108
+
109
+ # Check skill info
110
+ skilld info
89
111
 
90
- # Check skill status
91
- skilld status
112
+ # List installed skills
113
+ skilld list
114
+ skilld list --json
92
115
 
93
116
  # Manage settings
94
117
  skilld config
@@ -102,11 +125,13 @@ skilld config
102
125
  | `skilld add <pkg...>` | Add skills for package(s), space or comma-separated |
103
126
  | `skilld update [pkg]` | Update outdated skills (all or specific) |
104
127
  | `skilld search <query>` | Search indexed docs (`-p` to filter by package) |
105
- | `skilld status` | Show skill status across agents |
106
- | `skilld config` | Configure agent, model, preferences |
107
- | `skilld install` | Restore references from lockfile |
108
- | `skilld remove` | Remove installed skills |
109
- | `skilld uninstall` | Remove all skilld data |
128
+ | `skilld list` | List installed skills (`--json` for machine-readable output) |
129
+ | `skilld info` | Show skill info and config |
130
+ | `skilld config` | Configure agent, model, preferences |
131
+ | `skilld install` | Restore references from lockfile |
132
+ | `skilld remove` | Remove installed skills |
133
+ | `skilld uninstall` | Remove all skilld data |
134
+ | `skilld cache` | Cache management (clean expired LLM cache entries) |
110
135
 
111
136
  ### CLI Options
112
137
 
@@ -116,87 +141,16 @@ skilld config
116
141
  | `--agent` | `-a` | auto-detect | Target specific agent (claude-code, cursor, etc.) |
117
142
  | `--yes` | `-y` | `false` | Skip prompts, use defaults |
118
143
  | `--force` | `-f` | `false` | Ignore all caches, re-fetch docs and regenerate |
119
- | `--prepare` | | `false` | Non-interactive sync for prepare hook (outdated only) |
120
- | `--background` | `-b` | `false` | Run `--prepare` in a detached background process |
121
-
122
- ## How It Works
123
-
124
- ```
125
- Package name → Resolve docs → Fetch → Generate → Install
126
- ```
127
-
128
- 1. **Resolve** - Looks up npm registry for homepage, repository URL
129
- 2. **Fetch** - Tries versioned git docs → GitHub README → llms.txt (via ungh)
130
- 3. **Generate** - Your agent creates SKILL.md from fetched docs
131
- 4. **Cache** - References stored in `~/.skilld/` (shared across projects)
132
- 5. **Install** - Writes SKILL.md to `./<agent>/skills/<package>/` (e.g. `.claude/skills/vueuse/`)
133
-
134
- Supported agents: Claude Code, Cursor, Windsurf, Cline, Codex, GitHub Copilot, Gemini CLI, Goose, Amp, OpenCode, Roo Code
135
-
136
- ## Output Structure
137
-
138
- Skills install to each detected agent's skill directory. References are cached globally and shared across projects:
139
-
140
- ```
141
- .claude/skills/vueuse/
142
- ├── SKILL.md # Project-specific, adapts to your conventions
143
- └── .skilld/ # Gitignored, recreated by `skilld install`
144
- ├── pkg -> node_modules/vueuse
145
- └── docs -> ~/.skilld/references/vueuse@10.9.0/docs
146
-
147
- ~/.skilld/references/
148
- └── vueuse@10.9.0/ # Global cache, static docs
149
- ├── docs/
150
- ├── issues/
151
- └── discussions/
152
- ```
153
-
154
- SKILL.md is regenerated per-project (different conventions), but references stay static (same package docs). Version frontmatter enables sync:
155
-
156
- ```yaml
157
- ---
158
- name: vueuse
159
- version: 10.9.0
160
- description: Collection of Vue Composition Utilities
161
- ---
162
- ```
163
-
164
- ## Package.json Auto-Discovery
165
-
166
- Run `skilld` without arguments to interactively generate skills for your dependencies:
167
-
168
- ```bash
169
- cd my-project
170
- pnpx skilld
171
- ```
172
-
173
- On first run, skilld launches a wizard to configure your agent and model, then lets you choose packages from:
174
- - **Source imports** — scans your code for actually used packages
175
- - **package.json** — all dependencies and devDependencies
176
- - **Manual entry** — comma-separated package names
177
-
178
- Skips `@types/*` and common dev tools (typescript, eslint, vitest, etc).
179
-
180
- ## Shipped Skills (skills-npm)
181
-
182
- skilld supports the [skills-npm](https://github.com/antfu/skills-npm) convention. If a package ships a `skills/` directory, skilld symlinks it directly — no doc fetching, no caching, no LLM generation, no tokens spent.
183
-
184
- ```
185
- node_modules/@slidev/cli/skills/
186
- slidev/
187
- SKILL.md
188
- references/
189
-
190
- → .claude/skills/slidev -> node_modules/@slidev/cli/skills/slidev
191
- ```
192
-
193
- Package authors can ship skills alongside their code. skilld detects and links them automatically during sync. Generation is the fallback for packages that haven't adopted the convention yet.
144
+ | `--model` | `-m` | config default | LLM model for skill generation (sonnet, haiku, opus, etc.) |
145
+ | `--debug` | | `false` | Save raw LLM output to logs/ for each section |
146
+ | `--prepare` | | `false` | Non-interactive sync for prepare hook (outdated only) |
147
+ | `--background` | `-b` | `false` | Run `--prepare` in a detached background process |
194
148
 
195
149
  ## Related
196
150
 
197
151
  - [skills-npm](https://github.com/antfu/skills-npm) - Convention for shipping agent skills in npm packages
198
- - [mdream](https://github.com/harlan-zw/mdream) - HTML to Markdown converter used for crawling
199
- - [retriv](https://github.com/harlan-zw/retriv) - Vector database abstraction layer
152
+ - [mdream](https://github.com/harlan-zw/mdream) - HTML to Markdown converter
153
+ - [retriv](https://github.com/harlan-zw/retriv) - Vector search with sqlite-vec
200
154
 
201
155
  ## License
202
156
 
@@ -17,10 +17,9 @@ function getCacheDir(name, version) {
17
17
  }
18
18
  const CACHE_DIR = join(homedir(), ".skilld");
19
19
  const REFERENCES_DIR = join(CACHE_DIR, "references");
20
- const SEARCH_DB = join(CACHE_DIR, "search.db");
21
20
  function getPackageDbPath(name, version) {
22
21
  return join(REFERENCES_DIR, getCacheKey(name, version), "search.db");
23
22
  }
24
- export { getCacheDir as a, getPackageDbPath as i, REFERENCES_DIR as n, getCacheKey as o, SEARCH_DB as r, getVersionKey as s, CACHE_DIR as t };
23
+ export { getCacheKey as a, getCacheDir as i, REFERENCES_DIR as n, getVersionKey as o, getPackageDbPath as r, CACHE_DIR as t };
25
24
 
26
25
  //# sourceMappingURL=config.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** @deprecated Use getPackageDbPath instead */\nexport const SEARCH_DB = join(CACHE_DIR, 'search.db')\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":";;AAQA,MAAM,iBAAiB;AAGvB,MAAM,gBAAgB;AAKtB,SAAgB,cAAc,SAAyB;AACrD,QAAO;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;AAO1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,KAAI,CAAC,eAAe,KAAK,KAAK,CAC5B,OAAM,IAAI,MAAM,yBAAyB,OAAO;AAClD,KAAI,CAAC,cAAc,KAAK,QAAQ,CAC9B,OAAM,IAAI,MAAM,oBAAoB,UAAU;CAEhD,MAAM,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,CAAC;AAC/D,KAAI,CAAC,IAAI,WAAW,eAAe,CACjC,OAAM,IAAI,MAAM,4BAA4B,MAAM;AACpD,QAAO;;AC/BT,MAAa,YAAY,KAAK,SAAS,EAAE,UAAU;AAGnD,MAAa,iBAAiB,KAAK,WAAW,aAAa;AAG3D,MAAa,YAAY,KAAK,WAAW,YAAY;AAGrD,SAAgB,iBAAiB,MAAc,SAAyB;AACtE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,EAAE,YAAY"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":";;AAQA,MAAM,iBAAiB;AAGvB,MAAM,gBAAgB;AAKtB,SAAgB,cAAc,SAAyB;AACrD,QAAO;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;AAO1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,KAAI,CAAC,eAAe,KAAK,KAAK,CAC5B,OAAM,IAAI,MAAM,yBAAyB,OAAO;AAClD,KAAI,CAAC,cAAc,KAAK,QAAQ,CAC9B,OAAM,IAAI,MAAM,oBAAoB,UAAU;CAEhD,MAAM,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,CAAC;AAC/D,KAAI,CAAC,IAAI,WAAW,eAAe,CACjC,OAAM,IAAI,MAAM,4BAA4B,MAAM;AACpD,QAAO;;AC/BT,MAAa,YAAY,KAAK,SAAS,EAAE,UAAU;AAGnD,MAAa,iBAAiB,KAAK,WAAW,aAAa;AAG3D,SAAgB,iBAAiB,MAAc,SAAyB;AACtE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,EAAE,YAAY"}