skilld 0.0.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.
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ <h1>skilld</h1>
2
+
3
+ [![npm version](https://img.shields.io/npm/v/skilld?color=yellow)](https://npmjs.com/package/skilld)
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.md)
6
+
7
+ > A global database of searchable skills generated from live NPM package documentation.
8
+
9
+ <p align="center">
10
+ <table>
11
+ <tbody>
12
+ <td align="center">
13
+ <sub>Made possible by my <a href="https://github.com/sponsors/harlan-zw">Sponsor Program 💖</a><br> Follow me <a href="https://twitter.com/harlan_zw">@harlan_zw</a> 🐦 • Join <a href="https://discord.gg/275MBUBvgP">Discord</a> for help</sub><br>
14
+ </td>
15
+ </tbody>
16
+ </table>
17
+ </p>
18
+
19
+ ## Features
20
+
21
+ - 🌐 **Global Skill DB** - Centralized, searchable skills for any NPM package
22
+ - 📚 **Live Docs** - Fetches from `llms.txt` or crawls documentation sites
23
+ - 🔍 **Vector Search** - SQLite-vec powered semantic search with transformers embeddings
24
+ - ✂️ **Smart Chunking** - Markdown-aware recursive text splitting (LangChain-style)
25
+ - 🚀 **Zero Config** - Point at a URL, get a searchable skill
26
+
27
+ ## How It Works
28
+
29
+ ```
30
+ Package name → Resolve docs → Fetch → Install to agent directories
31
+ ```
32
+
33
+ 1. **Resolve** - Looks up npm registry for homepage, repository URL
34
+ 2. **Fetch** - Tries llms.txt → docs site → GitHub README (via ungh)
35
+ 3. **Install** - Writes SKILL.md to each detected agent's skill directory
36
+
37
+ Supported agents: Claude Code, Cursor, Windsurf, Cline, Codex, GitHub Copilot, Gemini CLI, Goose, Amp, OpenCode, Roo Code
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pnpm add -g skilld
43
+ ```
44
+
45
+ ## CLI Usage
46
+
47
+ ```bash
48
+ # Auto-discover from package.json dependencies
49
+ skilld
50
+
51
+ # Generate skill from specific package name
52
+ skilld vueuse
53
+ skilld @nuxt/kit
54
+
55
+ # Generate skill from URL
56
+ skilld https://nuxt.com/docs
57
+
58
+ # Custom output directory
59
+ skilld -o ./my-skills
60
+
61
+ # Concurrent processing (default: 3)
62
+ skilld -c 5
63
+
64
+ # Skip llms.txt and always crawl
65
+ skilld --crawl
66
+
67
+ # Limit pages fetched per package
68
+ skilld -m 50
69
+ ```
70
+
71
+ ### CLI Options
72
+
73
+ | Option | Alias | Default | Description |
74
+ |--------|-------|---------|-------------|
75
+ | `--output` | `-o` | `.skilld` | Output directory |
76
+ | `--maxPages` | `-m` | `100` | Max pages to fetch |
77
+ | `--chunkSize` | | `1000` | Chunk size in characters |
78
+ | `--model` | | `Xenova/bge-small-en-v1.5` | Embedding model |
79
+ | `--crawl` | | `false` | Skip llms.txt, always crawl |
80
+ | `--concurrency` | `-c` | `3` | Concurrent package processing |
81
+
82
+ ## Programmatic Usage
83
+
84
+ ```ts
85
+ import { generateSkill } from 'skilld'
86
+
87
+ const result = await generateSkill({
88
+ url: 'https://nuxt.com/docs',
89
+ outputDir: '.skilld',
90
+ maxPages: 100,
91
+ chunkSize: 1000,
92
+ chunkOverlap: 200,
93
+ }, ({ url, count, phase }) => {
94
+ console.log(`[${phase}] ${count}: ${url}`)
95
+ })
96
+
97
+ console.log(result)
98
+ // {
99
+ // siteName: 'nuxt.com',
100
+ // skillPath: '.skilld/nuxt.com/SKILL.md',
101
+ // referencesDir: '.skilld/nuxt.com/references',
102
+ // dbPath: '.skilld/nuxt.com/search.db',
103
+ // chunkCount: 847
104
+ // }
105
+ ```
106
+
107
+ ## Output Structure
108
+
109
+ Skills are installed directly to each agent's skill directory:
110
+
111
+ ```
112
+ .claude/skills/
113
+ └── vueuse/
114
+ └── SKILL.md # Package documentation
115
+
116
+ .cursor/skills/
117
+ └── vueuse/
118
+ └── SKILL.md # Same content, separate copy
119
+ ```
120
+
121
+ Each SKILL.md includes frontmatter for agent discovery:
122
+
123
+ ```yaml
124
+ ---
125
+ name: vueuse
126
+ description: Collection of Vue Composition Utilities
127
+ ---
128
+
129
+ # VueUse
130
+ ...README content...
131
+ ```
132
+
133
+ ## Package.json Auto-Discovery
134
+
135
+ Run `skilld` without arguments to generate skills for all dependencies:
136
+
137
+ ```bash
138
+ cd my-project
139
+ pnpx skilld
140
+ ```
141
+
142
+ This will:
143
+ 1. Read `package.json` dependencies and devDependencies
144
+ 2. Resolve documentation URL for each package (llms.txt → homepage → GitHub README)
145
+ 3. Generate searchable skills in `.skilld/`
146
+
147
+ Skips `@types/*` and common dev tools (typescript, eslint, vitest, etc).
148
+
149
+ ## NPM Package Skills
150
+
151
+ Generate skills for specific packages by name or URL:
152
+
153
+ ```bash
154
+ # By package name (auto-resolves docs)
155
+ skilld vueuse
156
+ skilld @vueuse/core
157
+ skilld defu
158
+
159
+ # By URL
160
+ skilld https://vueuse.org
161
+ skilld https://nuxt.com # Uses /llms.txt automatically
162
+ ```
163
+
164
+ ## Related
165
+
166
+ - [mdream](https://github.com/harlan-zw/mdream) - HTML to Markdown converter used for crawling
167
+ - [retriv](https://github.com/harlan-zw/retriv) - Vector database abstraction layer
168
+
169
+ ## License
170
+
171
+ Licensed under the [MIT license](https://github.com/harlan-zw/skilld/blob/main/LICENSE.md).
@@ -0,0 +1,56 @@
1
+ //#region src/agents.d.ts
2
+ /**
3
+ * Agent detection and skill installation
4
+ * Writes directly to agent skill directories in the project
5
+ */
6
+ type AgentType = 'claude-code' | 'cursor' | 'windsurf' | 'cline' | 'codex' | 'github-copilot' | 'gemini-cli' | 'goose' | 'amp' | 'opencode' | 'roo';
7
+ interface AgentConfig {
8
+ name: AgentType;
9
+ displayName: string;
10
+ /** Project-level skills directory (e.g., .claude/skills) */
11
+ skillsDir: string;
12
+ /** Global skills directory (e.g., ~/.claude/skills) */
13
+ globalSkillsDir: string | undefined;
14
+ /** Check if agent is installed on the system */
15
+ detectInstalled: () => boolean;
16
+ }
17
+ declare const agents: Record<AgentType, AgentConfig>;
18
+ /**
19
+ * Detect which agents are installed on the system
20
+ */
21
+ declare function detectInstalledAgents(): AgentType[];
22
+ /**
23
+ * Detect which agent is currently running this command
24
+ * Returns the active agent based on environment variables and context
25
+ */
26
+ declare function detectCurrentAgent(): AgentType | null;
27
+ /**
28
+ * Sanitize skill name for filesystem
29
+ */
30
+ declare function sanitizeName(name: string): string;
31
+ /**
32
+ * Install a skill directly to agent skill directories
33
+ * Writes to each agent's skill folder in the project (e.g., .claude/skills/package-name/)
34
+ */
35
+ declare function installSkillForAgents(skillName: string, skillContent: string, options?: {
36
+ global?: boolean;
37
+ cwd?: string;
38
+ agents?: AgentType[]; /** Additional files to write (filename -> content) */
39
+ files?: Record<string, string>;
40
+ }): {
41
+ installed: AgentType[];
42
+ paths: string[];
43
+ };
44
+ interface SkillMetadata {
45
+ name: string;
46
+ version?: string;
47
+ description?: string;
48
+ }
49
+ /**
50
+ * Generate SKILL.md frontmatter content
51
+ * The description tells the agent when to use this skill
52
+ */
53
+ declare function generateSkillMd(meta: SkillMetadata, body: string): string;
54
+ //#endregion
55
+ export { AgentConfig, AgentType, SkillMetadata, agents, detectCurrentAgent, detectInstalledAgents, generateSkillMd, installSkillForAgents, sanitizeName };
56
+ //# sourceMappingURL=agents.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.mts","names":[],"sources":["../src/agents.ts"],"mappings":";;AAcA;;;KAAY,SAAA;AAAA,UAaK,WAAA;EACf,IAAA,EAAM,SAAA;EACN,WAAA;;EAEA,SAAA;EAHA;EAKA,eAAA;EAJA;EAMA,eAAA;AAAA;AAAA,cAGW,MAAA,EAAQ,MAAA,CAAO,SAAA,EAAW,WAAA;;;AAAvC;iBAmFgB,qBAAA,CAAA,GAAyB,SAAA;;;;;iBAUzB,kBAAA,CAAA,GAAsB,SAAA;;;;iBAyDtB,YAAA,CAAa,IAAA;;;AAnE7B;;iBA+EgB,qBAAA,CACd,SAAA,UACA,YAAA,UACA,OAAA;EACE,MAAA;EACA,GAAA;EACA,MAAA,GAAS,SAAA,IA3EqB;EA6E9B,KAAA,GAAQ,MAAA;AAAA;EAEP,SAAA,EAAW,SAAA;EAAa,KAAA;AAAA;AAAA,UAuCZ,aAAA;EACf,IAAA;EACA,OAAA;EACA,WAAA;AAAA;;;;;iBAOc,eAAA,CACd,IAAA,EAAM,aAAA,EACN,IAAA"}
@@ -0,0 +1,148 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ const home = homedir();
5
+ const configHome = process.env.XDG_CONFIG_HOME || join(home, ".config");
6
+ const claudeHome = process.env.CLAUDE_CONFIG_DIR || join(home, ".claude");
7
+ const codexHome = process.env.CODEX_HOME || join(home, ".codex");
8
+ const agents = {
9
+ "claude-code": {
10
+ name: "claude-code",
11
+ displayName: "Claude Code",
12
+ skillsDir: ".claude/skills",
13
+ globalSkillsDir: join(claudeHome, "skills"),
14
+ detectInstalled: () => existsSync(claudeHome)
15
+ },
16
+ cursor: {
17
+ name: "cursor",
18
+ displayName: "Cursor",
19
+ skillsDir: ".cursor/skills",
20
+ globalSkillsDir: join(home, ".cursor/skills"),
21
+ detectInstalled: () => existsSync(join(home, ".cursor"))
22
+ },
23
+ windsurf: {
24
+ name: "windsurf",
25
+ displayName: "Windsurf",
26
+ skillsDir: ".windsurf/skills",
27
+ globalSkillsDir: join(home, ".codeium/windsurf/skills"),
28
+ detectInstalled: () => existsSync(join(home, ".codeium/windsurf"))
29
+ },
30
+ cline: {
31
+ name: "cline",
32
+ displayName: "Cline",
33
+ skillsDir: ".cline/skills",
34
+ globalSkillsDir: join(home, ".cline/skills"),
35
+ detectInstalled: () => existsSync(join(home, ".cline"))
36
+ },
37
+ codex: {
38
+ name: "codex",
39
+ displayName: "Codex",
40
+ skillsDir: ".codex/skills",
41
+ globalSkillsDir: join(codexHome, "skills"),
42
+ detectInstalled: () => existsSync(codexHome)
43
+ },
44
+ "github-copilot": {
45
+ name: "github-copilot",
46
+ displayName: "GitHub Copilot",
47
+ skillsDir: ".github/skills",
48
+ globalSkillsDir: join(home, ".copilot/skills"),
49
+ detectInstalled: () => existsSync(join(home, ".copilot"))
50
+ },
51
+ "gemini-cli": {
52
+ name: "gemini-cli",
53
+ displayName: "Gemini CLI",
54
+ skillsDir: ".gemini/skills",
55
+ globalSkillsDir: join(home, ".gemini/skills"),
56
+ detectInstalled: () => existsSync(join(home, ".gemini"))
57
+ },
58
+ goose: {
59
+ name: "goose",
60
+ displayName: "Goose",
61
+ skillsDir: ".goose/skills",
62
+ globalSkillsDir: join(configHome, "goose/skills"),
63
+ detectInstalled: () => existsSync(join(configHome, "goose"))
64
+ },
65
+ amp: {
66
+ name: "amp",
67
+ displayName: "Amp",
68
+ skillsDir: ".agents/skills",
69
+ globalSkillsDir: join(configHome, "agents/skills"),
70
+ detectInstalled: () => existsSync(join(configHome, "amp"))
71
+ },
72
+ opencode: {
73
+ name: "opencode",
74
+ displayName: "OpenCode",
75
+ skillsDir: ".opencode/skills",
76
+ globalSkillsDir: join(configHome, "opencode/skills"),
77
+ detectInstalled: () => existsSync(join(configHome, "opencode"))
78
+ },
79
+ roo: {
80
+ name: "roo",
81
+ displayName: "Roo Code",
82
+ skillsDir: ".roo/skills",
83
+ globalSkillsDir: join(home, ".roo/skills"),
84
+ detectInstalled: () => existsSync(join(home, ".roo"))
85
+ }
86
+ };
87
+ function detectInstalledAgents() {
88
+ return Object.entries(agents).filter(([_, config]) => config.detectInstalled()).map(([type]) => type);
89
+ }
90
+ function detectCurrentAgent() {
91
+ if (process.env.CLAUDE_CODE || process.env.CLAUDE_CONFIG_DIR) return "claude-code";
92
+ if (process.env.CURSOR_SESSION || process.env.CURSOR_TRACE_ID) return "cursor";
93
+ if (process.env.WINDSURF_SESSION) return "windsurf";
94
+ if (process.env.CLINE_TASK_ID) return "cline";
95
+ if (process.env.CODEX_HOME || process.env.CODEX_SESSION) return "codex";
96
+ if (process.env.GITHUB_COPILOT_SESSION) return "github-copilot";
97
+ if (process.env.GEMINI_API_KEY && process.env.GEMINI_SESSION) return "gemini-cli";
98
+ if (process.env.GOOSE_SESSION) return "goose";
99
+ if (process.env.AMP_SESSION) return "amp";
100
+ if (process.env.OPENCODE_SESSION) return "opencode";
101
+ if (process.env.ROO_SESSION) return "roo";
102
+ const cwd = process.cwd();
103
+ if (existsSync(join(cwd, ".claude"))) return "claude-code";
104
+ if (existsSync(join(cwd, ".cursor"))) return "cursor";
105
+ if (existsSync(join(cwd, ".windsurf"))) return "windsurf";
106
+ if (existsSync(join(cwd, ".cline"))) return "cline";
107
+ return null;
108
+ }
109
+ function sanitizeName(name) {
110
+ return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 255) || "unnamed-skill";
111
+ }
112
+ function installSkillForAgents(skillName, skillContent, options = {}) {
113
+ const isGlobal = options.global ?? false;
114
+ const cwd = options.cwd || process.cwd();
115
+ const sanitized = sanitizeName(skillName);
116
+ const targetAgents = options.agents || detectInstalledAgents();
117
+ const installed = [];
118
+ const paths = [];
119
+ for (const agentType of targetAgents) {
120
+ const agent = agents[agentType];
121
+ if (isGlobal && !agent.globalSkillsDir) continue;
122
+ const skillDir = join(isGlobal ? agent.globalSkillsDir : join(cwd, agent.skillsDir), sanitized);
123
+ mkdirSync(skillDir, { recursive: true });
124
+ writeFileSync(join(skillDir, "SKILL.md"), skillContent);
125
+ if (options.files) for (const [filename, content] of Object.entries(options.files)) writeFileSync(join(skillDir, filename), content);
126
+ installed.push(agentType);
127
+ paths.push(skillDir);
128
+ }
129
+ return {
130
+ installed,
131
+ paths
132
+ };
133
+ }
134
+ function generateSkillMd(meta, body) {
135
+ const { name, version, description: packageDescription } = meta;
136
+ const description = packageDescription ? `${packageDescription} Use this skill when working with ${name}, importing from "${name}", or when the user asks about ${name} features, API, or usage.` : `Documentation for ${name}. Use this skill when working with ${name} or importing from "${name}".`;
137
+ const frontmatter = [
138
+ "---",
139
+ `name: ${name}`,
140
+ `description: ${description}`
141
+ ];
142
+ if (version) frontmatter.push(`version: "${version}"`);
143
+ frontmatter.push("---");
144
+ return frontmatter.join("\n") + "\n\n" + body;
145
+ }
146
+ export { agents, detectCurrentAgent, detectInstalledAgents, generateSkillMd, installSkillForAgents, sanitizeName };
147
+
148
+ //# sourceMappingURL=agents.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.mjs","names":[],"sources":["../src/agents.ts"],"sourcesContent":["/**\n * Agent detection and skill installation\n * Writes directly to agent skill directories in the project\n */\n\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nconst home = homedir()\nconst configHome = process.env.XDG_CONFIG_HOME || join(home, '.config')\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR || join(home, '.claude')\nconst codexHome = process.env.CODEX_HOME || join(home, '.codex')\n\nexport type AgentType =\n | 'claude-code'\n | 'cursor'\n | 'windsurf'\n | 'cline'\n | 'codex'\n | 'github-copilot'\n | 'gemini-cli'\n | 'goose'\n | 'amp'\n | 'opencode'\n | 'roo'\n\nexport interface AgentConfig {\n name: AgentType\n displayName: string\n /** Project-level skills directory (e.g., .claude/skills) */\n skillsDir: string\n /** Global skills directory (e.g., ~/.claude/skills) */\n globalSkillsDir: string | undefined\n /** Check if agent is installed on the system */\n detectInstalled: () => boolean\n}\n\nexport const agents: Record<AgentType, AgentConfig> = {\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n skillsDir: '.claude/skills',\n globalSkillsDir: join(claudeHome, 'skills'),\n detectInstalled: () => existsSync(claudeHome),\n },\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectInstalled: () => existsSync(join(home, '.cursor')),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectInstalled: () => existsSync(join(home, '.cline')),\n },\n codex: {\n name: 'codex',\n displayName: 'Codex',\n skillsDir: '.codex/skills',\n globalSkillsDir: join(codexHome, 'skills'),\n detectInstalled: () => existsSync(codexHome),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n detectInstalled: () => existsSync(join(home, '.copilot')),\n },\n 'gemini-cli': {\n name: 'gemini-cli',\n displayName: 'Gemini CLI',\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n detectInstalled: () => existsSync(join(home, '.gemini')),\n },\n goose: {\n name: 'goose',\n displayName: 'Goose',\n skillsDir: '.goose/skills',\n globalSkillsDir: join(configHome, 'goose/skills'),\n detectInstalled: () => existsSync(join(configHome, 'goose')),\n },\n amp: {\n name: 'amp',\n displayName: 'Amp',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n detectInstalled: () => existsSync(join(configHome, 'amp')),\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(configHome, 'opencode/skills'),\n detectInstalled: () => existsSync(join(configHome, 'opencode')),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectInstalled: () => existsSync(join(home, '.roo')),\n },\n}\n\n/**\n * Detect which agents are installed on the system\n */\nexport function detectInstalledAgents(): AgentType[] {\n return Object.entries(agents)\n .filter(([_, config]) => config.detectInstalled())\n .map(([type]) => type as AgentType)\n}\n\n/**\n * Detect which agent is currently running this command\n * Returns the active agent based on environment variables and context\n */\nexport function detectCurrentAgent(): AgentType | null {\n // Check environment variables set by agents\n if (process.env.CLAUDE_CODE || process.env.CLAUDE_CONFIG_DIR) {\n return 'claude-code'\n }\n if (process.env.CURSOR_SESSION || process.env.CURSOR_TRACE_ID) {\n return 'cursor'\n }\n if (process.env.WINDSURF_SESSION) {\n return 'windsurf'\n }\n if (process.env.CLINE_TASK_ID) {\n return 'cline'\n }\n if (process.env.CODEX_HOME || process.env.CODEX_SESSION) {\n return 'codex'\n }\n if (process.env.GITHUB_COPILOT_SESSION) {\n return 'github-copilot'\n }\n if (process.env.GEMINI_API_KEY && process.env.GEMINI_SESSION) {\n return 'gemini-cli'\n }\n if (process.env.GOOSE_SESSION) {\n return 'goose'\n }\n if (process.env.AMP_SESSION) {\n return 'amp'\n }\n if (process.env.OPENCODE_SESSION) {\n return 'opencode'\n }\n if (process.env.ROO_SESSION) {\n return 'roo'\n }\n\n // Check for project-level agent config directories\n const cwd = process.cwd()\n if (existsSync(join(cwd, '.claude'))) {\n return 'claude-code'\n }\n if (existsSync(join(cwd, '.cursor'))) {\n return 'cursor'\n }\n if (existsSync(join(cwd, '.windsurf'))) {\n return 'windsurf'\n }\n if (existsSync(join(cwd, '.cline'))) {\n return 'cline'\n }\n\n return null\n}\n\n/**\n * Sanitize skill name for filesystem\n */\nexport function sanitizeName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9._]+/g, '-')\n .replace(/^[.\\-]+|[.\\-]+$/g, '')\n .slice(0, 255) || 'unnamed-skill'\n}\n\n/**\n * Install a skill directly to agent skill directories\n * Writes to each agent's skill folder in the project (e.g., .claude/skills/package-name/)\n */\nexport function installSkillForAgents(\n skillName: string,\n skillContent: string,\n options: {\n global?: boolean\n cwd?: string\n agents?: AgentType[]\n /** Additional files to write (filename -> content) */\n files?: Record<string, string>\n } = {},\n): { installed: AgentType[], paths: string[] } {\n const isGlobal = options.global ?? false\n const cwd = options.cwd || process.cwd()\n const sanitized = sanitizeName(skillName)\n\n // Use specified agents or detect installed\n const targetAgents = options.agents || detectInstalledAgents()\n\n const installed: AgentType[] = []\n const paths: string[] = []\n\n for (const agentType of targetAgents) {\n const agent = agents[agentType]\n\n // Skip if agent doesn't support global installation\n if (isGlobal && !agent.globalSkillsDir) continue\n\n // Determine target directory\n const baseDir = isGlobal ? agent.globalSkillsDir! : join(cwd, agent.skillsDir)\n const skillDir = join(baseDir, sanitized)\n\n // Create directory and write files\n mkdirSync(skillDir, { recursive: true })\n writeFileSync(join(skillDir, 'SKILL.md'), skillContent)\n\n // Write additional files\n if (options.files) {\n for (const [filename, content] of Object.entries(options.files)) {\n writeFileSync(join(skillDir, filename), content)\n }\n }\n\n installed.push(agentType)\n paths.push(skillDir)\n }\n\n return { installed, paths }\n}\n\nexport interface SkillMetadata {\n name: string\n version?: string\n description?: string\n}\n\n/**\n * Generate SKILL.md frontmatter content\n * The description tells the agent when to use this skill\n */\nexport function generateSkillMd(\n meta: SkillMetadata,\n body: string,\n): string {\n const { name, version, description: packageDescription } = meta\n\n // Create an actionable description that tells the agent when to use this skill\n const description = packageDescription\n ? `${packageDescription} Use this skill when working with ${name}, importing from \"${name}\", or when the user asks about ${name} features, API, or usage.`\n : `Documentation for ${name}. Use this skill when working with ${name} or importing from \"${name}\".`\n\n const frontmatter = [\n '---',\n `name: ${name}`,\n `description: ${description}`,\n ]\n\n if (version) {\n frontmatter.push(`version: \"${version}\"`)\n }\n\n frontmatter.push('---')\n\n return frontmatter.join('\\n') + '\\n\\n' + body\n}\n"],"mappings":";;;AASA,MAAM,OAAO,SAAS;AACtB,MAAM,aAAa,QAAQ,IAAI,mBAAmB,KAAK,MAAM,UAAU;AACvE,MAAM,aAAa,QAAQ,IAAI,qBAAqB,KAAK,MAAM,UAAU;AACzE,MAAM,YAAY,QAAQ,IAAI,cAAc,KAAK,MAAM,SAAS;AA0BhE,MAAa,SAAyC;CACpD,eAAe;EACb,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,YAAY,SAAS;EAC3C,uBAAuB,WAAW,WAAW;EAC9C;CACD,QAAQ;EACN,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,iBAAiB;EAC7C,uBAAuB,WAAW,KAAK,MAAM,UAAU,CAAC;EACzD;CACD,UAAU;EACR,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,2BAA2B;EACvD,uBAAuB,WAAW,KAAK,MAAM,oBAAoB,CAAC;EACnE;CACD,OAAO;EACL,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,gBAAgB;EAC5C,uBAAuB,WAAW,KAAK,MAAM,SAAS,CAAC;EACxD;CACD,OAAO;EACL,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,WAAW,SAAS;EAC1C,uBAAuB,WAAW,UAAU;EAC7C;CACD,kBAAkB;EAChB,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,kBAAkB;EAC9C,uBAAuB,WAAW,KAAK,MAAM,WAAW,CAAC;EAC1D;CACD,cAAc;EACZ,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,iBAAiB;EAC7C,uBAAuB,WAAW,KAAK,MAAM,UAAU,CAAC;EACzD;CACD,OAAO;EACL,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,YAAY,eAAe;EACjD,uBAAuB,WAAW,KAAK,YAAY,QAAQ,CAAC;EAC7D;CACD,KAAK;EACH,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,YAAY,gBAAgB;EAClD,uBAAuB,WAAW,KAAK,YAAY,MAAM,CAAC;EAC3D;CACD,UAAU;EACR,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,YAAY,kBAAkB;EACpD,uBAAuB,WAAW,KAAK,YAAY,WAAW,CAAC;EAChE;CACD,KAAK;EACH,MAAM;EACN,aAAa;EACb,WAAW;EACX,iBAAiB,KAAK,MAAM,cAAc;EAC1C,uBAAuB,WAAW,KAAK,MAAM,OAAO,CAAC;EACtD;CACF;AAKD,SAAgB,wBAAqC;AACnD,QAAO,OAAO,QAAQ,OAAO,CAC1B,QAAQ,CAAC,GAAG,YAAY,OAAO,iBAAiB,CAAC,CACjD,KAAK,CAAC,UAAU,KAAkB;;AAOvC,SAAgB,qBAAuC;AAErD,KAAI,QAAQ,IAAI,eAAe,QAAQ,IAAI,kBACzC,QAAO;AAET,KAAI,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,gBAC5C,QAAO;AAET,KAAI,QAAQ,IAAI,iBACd,QAAO;AAET,KAAI,QAAQ,IAAI,cACd,QAAO;AAET,KAAI,QAAQ,IAAI,cAAc,QAAQ,IAAI,cACxC,QAAO;AAET,KAAI,QAAQ,IAAI,uBACd,QAAO;AAET,KAAI,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,eAC5C,QAAO;AAET,KAAI,QAAQ,IAAI,cACd,QAAO;AAET,KAAI,QAAQ,IAAI,YACd,QAAO;AAET,KAAI,QAAQ,IAAI,iBACd,QAAO;AAET,KAAI,QAAQ,IAAI,YACd,QAAO;CAIT,MAAM,MAAM,QAAQ,KAAK;AACzB,KAAI,WAAW,KAAK,KAAK,UAAU,CAAC,CAClC,QAAO;AAET,KAAI,WAAW,KAAK,KAAK,UAAU,CAAC,CAClC,QAAO;AAET,KAAI,WAAW,KAAK,KAAK,YAAY,CAAC,CACpC,QAAO;AAET,KAAI,WAAW,KAAK,KAAK,SAAS,CAAC,CACjC,QAAO;AAGT,QAAO;;AAMT,SAAgB,aAAa,MAAsB;AACjD,QAAO,KACJ,aAAa,CACb,QAAQ,iBAAiB,IAAI,CAC7B,QAAQ,oBAAoB,GAAG,CAC/B,MAAM,GAAG,IAAI,IAAI;;AAOtB,SAAgB,sBACd,WACA,cACA,UAMI,EAAE,EACuC;CAC7C,MAAM,WAAW,QAAQ,UAAU;CACnC,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,MAAM,YAAY,aAAa,UAAU;CAGzC,MAAM,eAAe,QAAQ,UAAU,uBAAuB;CAE9D,MAAM,YAAyB,EAAE;CACjC,MAAM,QAAkB,EAAE;AAE1B,MAAK,MAAM,aAAa,cAAc;EACpC,MAAM,QAAQ,OAAO;AAGrB,MAAI,YAAY,CAAC,MAAM,gBAAiB;EAIxC,MAAM,WAAW,KADD,WAAW,MAAM,kBAAmB,KAAK,KAAK,MAAM,UAAU,EAC/C,UAAU;AAGzC,YAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AACxC,gBAAc,KAAK,UAAU,WAAW,EAAE,aAAa;AAGvD,MAAI,QAAQ,MACV,MAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAAQ,QAAQ,MAAM,CAC7D,eAAc,KAAK,UAAU,SAAS,EAAE,QAAQ;AAIpD,YAAU,KAAK,UAAU;AACzB,QAAM,KAAK,SAAS;;AAGtB,QAAO;EAAE;EAAW;EAAO;;AAa7B,SAAgB,gBACd,MACA,MACQ;CACR,MAAM,EAAE,MAAM,SAAS,aAAa,uBAAuB;CAG3D,MAAM,cAAc,qBAChB,GAAG,mBAAmB,oCAAoC,KAAK,oBAAoB,KAAK,iCAAiC,KAAK,6BAC9H,qBAAqB,KAAK,qCAAqC,KAAK,sBAAsB,KAAK;CAEnG,MAAM,cAAc;EAClB;EACA,SAAS;EACT,gBAAgB;EACjB;AAED,KAAI,QACF,aAAY,KAAK,aAAa,QAAQ,GAAG;AAG3C,aAAY,KAAK,MAAM;AAEvB,QAAO,YAAY,KAAK,KAAK,GAAG,SAAS"}
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };