skilld 0.1.2 → 0.2.1

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.
Files changed (40) hide show
  1. package/README.md +70 -120
  2. package/dist/_chunks/config.mjs +8 -2
  3. package/dist/_chunks/config.mjs.map +1 -1
  4. package/dist/_chunks/llm.mjs +710 -204
  5. package/dist/_chunks/llm.mjs.map +1 -1
  6. package/dist/_chunks/pool.mjs +115 -0
  7. package/dist/_chunks/pool.mjs.map +1 -0
  8. package/dist/_chunks/releases.mjs +689 -179
  9. package/dist/_chunks/releases.mjs.map +1 -1
  10. package/dist/_chunks/storage.mjs +311 -19
  11. package/dist/_chunks/storage.mjs.map +1 -1
  12. package/dist/_chunks/sync-parallel.mjs +134 -378
  13. package/dist/_chunks/sync-parallel.mjs.map +1 -1
  14. package/dist/_chunks/types.d.mts +9 -6
  15. package/dist/_chunks/types.d.mts.map +1 -1
  16. package/dist/_chunks/utils.d.mts +137 -68
  17. package/dist/_chunks/utils.d.mts.map +1 -1
  18. package/dist/_chunks/version.d.mts +43 -6
  19. package/dist/_chunks/version.d.mts.map +1 -1
  20. package/dist/agent/index.d.mts +58 -15
  21. package/dist/agent/index.d.mts.map +1 -1
  22. package/dist/agent/index.mjs +4 -2
  23. package/dist/cache/index.d.mts +2 -2
  24. package/dist/cache/index.mjs +2 -2
  25. package/dist/cli.mjs +2175 -1435
  26. package/dist/cli.mjs.map +1 -1
  27. package/dist/index.d.mts +4 -3
  28. package/dist/index.mjs +2 -2
  29. package/dist/retriv/index.d.mts +16 -2
  30. package/dist/retriv/index.d.mts.map +1 -1
  31. package/dist/retriv/index.mjs +44 -15
  32. package/dist/retriv/index.mjs.map +1 -1
  33. package/dist/retriv/worker.d.mts +33 -0
  34. package/dist/retriv/worker.d.mts.map +1 -0
  35. package/dist/retriv/worker.mjs +47 -0
  36. package/dist/retriv/worker.mjs.map +1 -0
  37. package/dist/sources/index.d.mts +2 -2
  38. package/dist/sources/index.mjs +2 -2
  39. package/dist/types.d.mts +5 -3
  40. package/package.json +11 -7
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
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 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,19 +34,36 @@ 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
- - 🚀 **Zero friction** - Works with any public npm package, no author opt-in; respects `llms.txt` and shipped `skills/` when available
37
+ - 🌍 **Any NPM Package** - Repo, 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.
42
53
 
43
54
  ## Installation
44
55
 
56
+ If you'd like to install skilld and track the lock file references, add it as a dev dependency:
57
+
45
58
  ```bash
46
- pnpm add -g skilld
59
+ npm install -D skilld
60
+ # or
61
+ yarn add -D skilld
62
+ # or
63
+ pnpm add -D skilld
47
64
  ```
48
65
 
49
- ## Automatic Updates
66
+ ### Automatic Updates
50
67
 
51
68
  Add to `package.json` to keep skills fresh on install:
52
69
 
@@ -58,32 +75,38 @@ Add to `package.json` to keep skills fresh on install:
58
75
  }
59
76
  ```
60
77
 
61
- skilld fast-paths unchanged versions—only regenerates when minor/major versions bump.
62
-
63
78
  ## CLI Usage
64
79
 
65
80
  ```bash
66
81
  # Interactive mode — auto-discover from package.json
67
82
  skilld
68
83
 
69
- # Sync specific package(s)
70
- skilld vueuse
71
- skilld vue,nuxt,pinia
84
+ # Add skills for specific package(s)
85
+ skilld add vueuse
86
+ skilld add vue nuxt pinia
87
+
88
+ # Update outdated skills
89
+ skilld update
90
+ skilld update vue
72
91
 
73
92
  # Search docs across installed skills
74
- skilld nuxt -q "useFetch options"
93
+ skilld search "useFetch options" -p nuxt
75
94
 
76
95
  # Target a specific agent
77
- skilld vueuse --agent cursor
96
+ skilld add vueuse --agent cursor
78
97
 
79
98
  # Install globally to ~/.claude/skills
80
- skilld vueuse --global
99
+ skilld add vueuse --global
81
100
 
82
101
  # Skip prompts
83
- skilld vueuse --yes
102
+ skilld add vueuse --yes
103
+
104
+ # Check skill info
105
+ skilld info
84
106
 
85
- # Check skill status
86
- skilld status
107
+ # List installed skills
108
+ skilld list
109
+ skilld list --json
87
110
 
88
111
  # Manage settings
89
112
  skilld config
@@ -94,108 +117,35 @@ skilld config
94
117
  | Command | Description |
95
118
  |---------|-------------|
96
119
  | `skilld` | Interactive wizard (first run) or status menu (existing skills) |
97
- | `skilld <pkg>` | Sync specific package(s), comma-separated |
98
- | `skilld status` | Show skill status across agents |
99
- | `skilld config` | Configure agent, model, preferences |
100
- | `skilld install` | Restore references from lockfile |
101
- | `skilld remove` | Remove installed skills |
102
- | `skilld uninstall` | Remove all skilld data |
120
+ | `skilld add <pkg...>` | Add skills for package(s), space or comma-separated |
121
+ | `skilld update [pkg]` | Update outdated skills (all or specific) |
122
+ | `skilld search <query>` | Search indexed docs (`-p` to filter by package) |
123
+ | `skilld list` | List installed skills (`--json` for machine-readable output) |
124
+ | `skilld info` | Show skill info and config |
125
+ | `skilld config` | Configure agent, model, preferences |
126
+ | `skilld install` | Restore references from lockfile |
127
+ | `skilld remove` | Remove installed skills |
128
+ | `skilld uninstall` | Remove all skilld data |
129
+ | `skilld cache` | Cache management (clean expired LLM cache entries) |
103
130
 
104
131
  ### CLI Options
105
132
 
106
133
  | Option | Alias | Default | Description |
107
134
  |--------|-------|---------|-------------|
108
- | `--query` | `-q` | | Search docs: `skilld nuxt -q "useFetch"` |
109
135
  | `--global` | `-g` | `false` | Install globally to `~/<agent>/skills` |
110
136
  | `--agent` | `-a` | auto-detect | Target specific agent (claude-code, cursor, etc.) |
111
137
  | `--yes` | `-y` | `false` | Skip prompts, use defaults |
112
- | `--prepare` | | `false` | Non-interactive sync for prepare hook (outdated only) |
113
- | `--background` | `-b` | `false` | Run `--prepare` in a detached background process |
114
-
115
- ## How It Works
116
-
117
- ```
118
- Package name → Resolve docs → Fetch → Generate → Install
119
- ```
120
-
121
- 1. **Resolve** - Looks up npm registry for homepage, repository URL
122
- 2. **Fetch** - Tries versioned git docs → GitHub README → llms.txt (via ungh)
123
- 3. **Generate** - Your agent creates SKILL.md from fetched docs
124
- 4. **Cache** - References stored in `~/.skilld/` (shared across projects)
125
- 5. **Install** - Writes SKILL.md to `./<agent>/skills/<package>/` (e.g. `.claude/skills/vueuse/`)
126
-
127
- Supported agents: Claude Code, Cursor, Windsurf, Cline, Codex, GitHub Copilot, Gemini CLI, Goose, Amp, OpenCode, Roo Code
128
-
129
- ## Output Structure
130
-
131
- Skills install to each detected agent's skill directory. References are cached globally and shared across projects:
132
-
133
- ```
134
- .claude/skills/vueuse/
135
- └── SKILL.md # Project-specific, adapts to your conventions
136
-
137
- ~/.skilld/references/
138
- └── vueuse@10.9.0/ # Global cache, static docs
139
- ├── chunks/
140
- └── search.db
141
- ```
142
-
143
- SKILL.md is regenerated per-project (different conventions), but references stay static (same package docs). Version frontmatter enables sync:
144
-
145
- ```yaml
146
- ---
147
- name: vueuse
148
- version: 10.9.0
149
- description: Collection of Vue Composition Utilities
150
- ---
151
- ```
152
-
153
- ## Package.json Auto-Discovery
154
-
155
- Run `skilld` without arguments to interactively generate skills for your dependencies:
156
-
157
- ```bash
158
- cd my-project
159
- pnpx skilld
160
- ```
161
-
162
- On first run, skilld launches a wizard to configure your agent and model, then lets you choose packages from:
163
- - **Source imports** — scans your code for actually used packages
164
- - **package.json** — all dependencies and devDependencies
165
- - **Manual entry** — comma-separated package names
166
-
167
- Skips `@types/*` and common dev tools (typescript, eslint, vitest, etc).
168
-
169
- ## Roadmap
170
-
171
- - [ ] **Team sync** - SKILL.md files commit with version frontmatter; `skilld sync` hydrates references from global cache
172
- - [ ] **Community skills repo** - Pull pre-generated skills from `skilld-community/skills` before generating; `skilld --share` to submit PRs
173
- - [ ] **Migration docs** - Generate upgrade guides when re-running after major version bumps
174
- - [ ] **MCP server mode** - Expose search as tool for Claude Code real-time doc lookups
175
- - [ ] **Eval command** - Validate skill quality against known patterns and usage
176
- - [ ] **CI integration** - GitHub Action to auto-regenerate skills on dependency updates
177
- - [ ] **Smart presets** - Auto-detect recommended packages from project config (nuxt.config.ts → nuxt, vue, nitro, h3)
178
-
179
- ## Shipped Skills (skills-npm)
180
-
181
- 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.
182
-
183
- ```
184
- node_modules/@slidev/cli/skills/
185
- slidev/
186
- SKILL.md
187
- references/
188
-
189
- → .claude/skills/slidev -> node_modules/@slidev/cli/skills/slidev
190
- ```
191
-
192
- 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.
138
+ | `--force` | `-f` | `false` | Ignore all caches, re-fetch docs and regenerate |
139
+ | `--model` | `-m` | config default | LLM model for skill generation (sonnet, haiku, opus, etc.) |
140
+ | `--debug` | | `false` | Save raw LLM output to logs/ for each section |
141
+ | `--prepare` | | `false` | Non-interactive sync for prepare hook (outdated only) |
142
+ | `--background` | `-b` | `false` | Run `--prepare` in a detached background process |
193
143
 
194
144
  ## Related
195
145
 
196
146
  - [skills-npm](https://github.com/antfu/skills-npm) - Convention for shipping agent skills in npm packages
197
- - [mdream](https://github.com/harlan-zw/mdream) - HTML to Markdown converter used for crawling
198
- - [retriv](https://github.com/harlan-zw/retriv) - Vector database abstraction layer
147
+ - [mdream](https://github.com/harlan-zw/mdream) - HTML to Markdown converter
148
+ - [retriv](https://github.com/harlan-zw/retriv) - Vector search with sqlite-vec
199
149
 
200
150
  ## License
201
151
 
@@ -1,5 +1,7 @@
1
1
  import { homedir } from "node:os";
2
- import { join } from "node:path";
2
+ import { join, resolve } from "pathe";
3
+ const VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\/)?[a-z0-9][-a-z0-9._]*$/;
4
+ const VALID_VERSION = /^[a-z0-9][-\w.+]*$/i;
3
5
  function getVersionKey(version) {
4
6
  return version;
5
7
  }
@@ -7,7 +9,11 @@ function getCacheKey(name, version) {
7
9
  return `${name}@${getVersionKey(version)}`;
8
10
  }
9
11
  function getCacheDir(name, version) {
10
- return join(REFERENCES_DIR, getCacheKey(name, version));
12
+ if (!VALID_PKG_NAME.test(name)) throw new Error(`Invalid package name: ${name}`);
13
+ if (!VALID_VERSION.test(version)) throw new Error(`Invalid version: ${version}`);
14
+ const dir = resolve(REFERENCES_DIR, getCacheKey(name, version));
15
+ if (!dir.startsWith(REFERENCES_DIR)) throw new Error(`Path traversal detected: ${dir}`);
16
+ return dir;
11
17
  }
12
18
  const CACHE_DIR = join(homedir(), ".skilld");
13
19
  const REFERENCES_DIR = join(CACHE_DIR, "references");
@@ -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 { join } from 'node:path'\nimport { REFERENCES_DIR } from './config'\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 */\nexport function getCacheDir(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version))\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\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":";;AAUA,SAAgB,cAAc,SAAyB;AACrD,QAAO;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;AAM1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,CAAC;;AChBzD,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/** @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"}