skilld 0.1.1 → 0.2.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.
Files changed (40) hide show
  1. package/README.md +24 -23
  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 +2170 -1436
  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
@@ -17,7 +17,7 @@ Agents already know how most packages work from training data. Skills should foc
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
18
 
19
19
  ```
20
- npm install vueuse → skilld vueuse → AI knows current vueuse API
20
+ npm install vueuse → skilld add vueuse → AI knows current vueuse API
21
21
  ```
22
22
 
23
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.
@@ -38,6 +38,7 @@ Compatible with [skills-npm](https://github.com/antfu/skills-npm)—if a package
38
38
  - 🎯 **Best practices first** - Token-optimized output focused on non-obvious patterns and conventions, not generic knowledge
39
39
  - 🔗 **Context-aware** - Generation adapts to your preferences and accepts custom prompts
40
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
41
42
  - 🚀 **Zero friction** - Works with any public npm package, no author opt-in; respects `llms.txt` and shipped `skills/` when available
42
43
 
43
44
  ## Installation
@@ -66,21 +67,25 @@ skilld fast-paths unchanged versions—only regenerates when minor/major version
66
67
  # Interactive mode — auto-discover from package.json
67
68
  skilld
68
69
 
69
- # Sync specific package(s)
70
- skilld vueuse
71
- skilld vue,nuxt,pinia
70
+ # Add skills for specific package(s)
71
+ skilld add vueuse
72
+ skilld add vue nuxt pinia
73
+
74
+ # Update outdated skills
75
+ skilld update
76
+ skilld update vue
72
77
 
73
78
  # Search docs across installed skills
74
- skilld nuxt -q "useFetch options"
79
+ skilld search "useFetch options" -p nuxt
75
80
 
76
81
  # Target a specific agent
77
- skilld vueuse --agent cursor
82
+ skilld add vueuse --agent cursor
78
83
 
79
84
  # Install globally to ~/.claude/skills
80
- skilld vueuse --global
85
+ skilld add vueuse --global
81
86
 
82
87
  # Skip prompts
83
- skilld vueuse --yes
88
+ skilld add vueuse --yes
84
89
 
85
90
  # Check skill status
86
91
  skilld status
@@ -94,7 +99,9 @@ skilld config
94
99
  | Command | Description |
95
100
  |---------|-------------|
96
101
  | `skilld` | Interactive wizard (first run) or status menu (existing skills) |
97
- | `skilld <pkg>` | Sync specific package(s), comma-separated |
102
+ | `skilld add <pkg...>` | Add skills for package(s), space or comma-separated |
103
+ | `skilld update [pkg]` | Update outdated skills (all or specific) |
104
+ | `skilld search <query>` | Search indexed docs (`-p` to filter by package) |
98
105
  | `skilld status` | Show skill status across agents |
99
106
  | `skilld config` | Configure agent, model, preferences |
100
107
  | `skilld install` | Restore references from lockfile |
@@ -105,10 +112,10 @@ skilld config
105
112
 
106
113
  | Option | Alias | Default | Description |
107
114
  |--------|-------|---------|-------------|
108
- | `--query` | `-q` | | Search docs: `skilld nuxt -q "useFetch"` |
109
115
  | `--global` | `-g` | `false` | Install globally to `~/<agent>/skills` |
110
116
  | `--agent` | `-a` | auto-detect | Target specific agent (claude-code, cursor, etc.) |
111
117
  | `--yes` | `-y` | `false` | Skip prompts, use defaults |
118
+ | `--force` | `-f` | `false` | Ignore all caches, re-fetch docs and regenerate |
112
119
  | `--prepare` | | `false` | Non-interactive sync for prepare hook (outdated only) |
113
120
  | `--background` | `-b` | `false` | Run `--prepare` in a detached background process |
114
121
 
@@ -132,12 +139,16 @@ Skills install to each detected agent's skill directory. References are cached g
132
139
 
133
140
  ```
134
141
  .claude/skills/vueuse/
135
- └── SKILL.md # Project-specific, adapts to your conventions
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
136
146
 
137
147
  ~/.skilld/references/
138
148
  └── vueuse@10.9.0/ # Global cache, static docs
139
- ├── chunks/
140
- └── search.db
149
+ ├── docs/
150
+ ├── issues/
151
+ └── discussions/
141
152
  ```
142
153
 
143
154
  SKILL.md is regenerated per-project (different conventions), but references stay static (same package docs). Version frontmatter enables sync:
@@ -166,16 +177,6 @@ On first run, skilld launches a wizard to configure your agent and model, then l
166
177
 
167
178
  Skips `@types/*` and common dev tools (typescript, eslint, vitest, etc).
168
179
 
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
180
  ## Shipped Skills (skills-npm)
180
181
 
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.
@@ -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"}