skilldotmd 0.1.0 → 0.1.2
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/bun.lock +68 -0
- package/package.json +5 -5
- package/src/index.js +84 -18
package/bun.lock
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 0,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "skilldotmd",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@clack/prompts": "^1.2.0",
|
|
9
|
+
"commander": "^12.0.0",
|
|
10
|
+
"ora": "^8.0.0",
|
|
11
|
+
"picocolors": "^1.1.1",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
"packages": {
|
|
16
|
+
"@clack/core": ["@clack/core@1.2.0", "", { "dependencies": { "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "sha512-qfxof/3T3t9DPU/Rj3OmcFyZInceqj/NVtO9rwIuJqCUgh32gwPjpFQQp/ben07qKlhpwq7GzfWpST4qdJ5Drg=="],
|
|
17
|
+
|
|
18
|
+
"@clack/prompts": ["@clack/prompts@1.2.0", "", { "dependencies": { "@clack/core": "1.2.0", "fast-string-width": "^1.1.0", "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w=="],
|
|
19
|
+
|
|
20
|
+
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
|
21
|
+
|
|
22
|
+
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
|
23
|
+
|
|
24
|
+
"cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
|
|
25
|
+
|
|
26
|
+
"cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
|
|
27
|
+
|
|
28
|
+
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
|
29
|
+
|
|
30
|
+
"emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
|
|
31
|
+
|
|
32
|
+
"fast-string-truncated-width": ["fast-string-truncated-width@1.2.1", "", {}, "sha512-Q9acT/+Uu3GwGj+5w/zsGuQjh9O1TyywhIwAxHudtWrgF09nHOPrvTLhQevPbttcxjr/SNN7mJmfOw/B1bXgow=="],
|
|
33
|
+
|
|
34
|
+
"fast-string-width": ["fast-string-width@1.1.0", "", { "dependencies": { "fast-string-truncated-width": "^1.2.0" } }, "sha512-O3fwIVIH5gKB38QNbdg+3760ZmGz0SZMgvwJbA1b2TGXceKE6A2cOlfogh1iw8lr049zPyd7YADHy+B7U4W9bQ=="],
|
|
35
|
+
|
|
36
|
+
"fast-wrap-ansi": ["fast-wrap-ansi@0.1.6", "", { "dependencies": { "fast-string-width": "^1.1.0" } }, "sha512-HlUwET7a5gqjURj70D5jl7aC3Zmy4weA1SHUfM0JFI0Ptq987NH2TwbBFLoERhfwk+E+eaq4EK3jXoT+R3yp3w=="],
|
|
37
|
+
|
|
38
|
+
"get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="],
|
|
39
|
+
|
|
40
|
+
"is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
|
|
41
|
+
|
|
42
|
+
"is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
|
|
43
|
+
|
|
44
|
+
"log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="],
|
|
45
|
+
|
|
46
|
+
"mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
|
|
47
|
+
|
|
48
|
+
"onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
|
|
49
|
+
|
|
50
|
+
"ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
|
|
51
|
+
|
|
52
|
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
|
53
|
+
|
|
54
|
+
"restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
|
|
55
|
+
|
|
56
|
+
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
|
57
|
+
|
|
58
|
+
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
|
|
59
|
+
|
|
60
|
+
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
|
|
61
|
+
|
|
62
|
+
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
|
63
|
+
|
|
64
|
+
"strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
|
65
|
+
|
|
66
|
+
"log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
|
|
67
|
+
}
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skilldotmd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Teach your AI any library. Install skills for Claude Code, Cursor, Windsurf and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"skilldotmd": "src/index.js"
|
|
7
|
+
"skilldotmd": "./src/index.js"
|
|
8
8
|
},
|
|
9
9
|
"keywords": [
|
|
10
10
|
"claude",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"author": "imPiyushkashyap",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@clack/prompts": "^
|
|
20
|
+
"@clack/prompts": "^1.2.0",
|
|
21
21
|
"commander": "^12.0.0",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
22
|
+
"ora": "^8.0.0",
|
|
23
|
+
"picocolors": "^1.1.1"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=18.0.0"
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
intro,
|
|
5
|
+
outro,
|
|
6
|
+
select,
|
|
7
|
+
text,
|
|
8
|
+
spinner,
|
|
9
|
+
isCancel,
|
|
10
|
+
cancel,
|
|
11
|
+
} from "@clack/prompts"
|
|
4
12
|
import { Command } from "commander"
|
|
5
13
|
import pc from "picocolors"
|
|
6
|
-
import { execSync } from "child_process"
|
|
7
14
|
import fs from "fs"
|
|
8
15
|
import path from "path"
|
|
9
16
|
|
|
10
|
-
const VERSION = "0.
|
|
17
|
+
const VERSION = "0.2.0"
|
|
11
18
|
|
|
12
19
|
const TOOLS = {
|
|
13
20
|
claude: { label: "Claude Code", projectPath: ".claude/skills" },
|
|
@@ -34,6 +41,34 @@ function detectTool() {
|
|
|
34
41
|
return null
|
|
35
42
|
}
|
|
36
43
|
|
|
44
|
+
function parseSkillPath(input) {
|
|
45
|
+
const parts = input.split("/")
|
|
46
|
+
if (parts.length < 3) return null
|
|
47
|
+
const owner = parts[0]
|
|
48
|
+
const repo = parts[1]
|
|
49
|
+
const skillPath = parts.slice(2).join("/")
|
|
50
|
+
const skillName = parts[parts.length - 1]
|
|
51
|
+
return { owner, repo, skillPath, skillName }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function downloadSkill(parsed) {
|
|
55
|
+
const branches = ["main", "master"]
|
|
56
|
+
for (const branch of branches) {
|
|
57
|
+
const url = `https://raw.githubusercontent.com/${parsed.owner}/${parsed.repo}/${branch}/${parsed.skillPath}/SKILL.md`
|
|
58
|
+
const res = await fetch(url)
|
|
59
|
+
if (res.ok) return await res.text()
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Skill not found at ${parsed.owner}/${parsed.repo}/${parsed.skillPath}`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function installSkill(tool, skillName, content) {
|
|
65
|
+
const cwd = process.cwd()
|
|
66
|
+
const targetDir = path.join(cwd, TOOLS[tool].projectPath, skillName)
|
|
67
|
+
fs.mkdirSync(targetDir, { recursive: true })
|
|
68
|
+
fs.writeFileSync(path.join(targetDir, "SKILL.md"), content)
|
|
69
|
+
return targetDir
|
|
70
|
+
}
|
|
71
|
+
|
|
37
72
|
const program = new Command()
|
|
38
73
|
|
|
39
74
|
program
|
|
@@ -47,26 +82,38 @@ program
|
|
|
47
82
|
.option("--for <tool>", "AI tool to install for")
|
|
48
83
|
.action(async (skill, options) => {
|
|
49
84
|
printBanner()
|
|
50
|
-
intro(pc.bold("Add
|
|
85
|
+
intro(pc.bold(pc.cyan("SkillDotMD — Add Skill")))
|
|
51
86
|
|
|
52
|
-
let
|
|
87
|
+
let skillInput = skill
|
|
53
88
|
|
|
54
|
-
if (!
|
|
55
|
-
|
|
56
|
-
message: "
|
|
57
|
-
placeholder: "
|
|
89
|
+
if (!skillInput) {
|
|
90
|
+
skillInput = await text({
|
|
91
|
+
message: "Enter skill path (GitHub)",
|
|
92
|
+
placeholder: "owner/repo/path/to/skill",
|
|
58
93
|
validate(value) {
|
|
59
94
|
if (!value) return "Please enter a skill path"
|
|
60
95
|
},
|
|
61
96
|
})
|
|
62
|
-
|
|
97
|
+
|
|
98
|
+
if (isCancel(skillInput)) {
|
|
99
|
+
cancel("Operation cancelled.")
|
|
100
|
+
process.exit(0)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const parsed = parseSkillPath(skillInput)
|
|
105
|
+
if (!parsed) {
|
|
106
|
+
outro(pc.red("✗ Invalid format\nExpected: owner/repo/path/to/skill"))
|
|
107
|
+
process.exit(1)
|
|
63
108
|
}
|
|
64
109
|
|
|
65
110
|
let tool = options.for
|
|
111
|
+
|
|
66
112
|
if (!tool) {
|
|
67
113
|
const detected = detectTool()
|
|
114
|
+
|
|
68
115
|
tool = await select({
|
|
69
|
-
message: "
|
|
116
|
+
message: "Select your AI tool",
|
|
70
117
|
options: Object.entries(TOOLS).map(([value, config]) => ({
|
|
71
118
|
value,
|
|
72
119
|
label: config.label,
|
|
@@ -74,21 +121,33 @@ program
|
|
|
74
121
|
})),
|
|
75
122
|
initialValue: detected || "claude",
|
|
76
123
|
})
|
|
77
|
-
|
|
124
|
+
|
|
125
|
+
if (isCancel(tool)) {
|
|
126
|
+
cancel("Operation cancelled.")
|
|
127
|
+
process.exit(0)
|
|
128
|
+
}
|
|
78
129
|
}
|
|
79
130
|
|
|
80
131
|
const s = spinner()
|
|
81
|
-
s.start(`
|
|
132
|
+
s.start(`Fetching ${pc.cyan(parsed.skillName)}...`)
|
|
82
133
|
|
|
83
134
|
try {
|
|
84
|
-
|
|
85
|
-
|
|
135
|
+
const content = await downloadSkill(parsed)
|
|
136
|
+
const installDir = installSkill(tool, parsed.skillName, content)
|
|
137
|
+
|
|
138
|
+
s.stop(`${pc.green("✓")} Installed ${pc.cyan(parsed.skillName)}`)
|
|
139
|
+
|
|
140
|
+
console.log("")
|
|
141
|
+
console.log(pc.bold("Next steps:"))
|
|
142
|
+
console.log(pc.dim("• Restart your editor"))
|
|
143
|
+
console.log(pc.dim("• Start using the skill"))
|
|
144
|
+
console.log(pc.dim(`• Installed at: ${installDir}`))
|
|
86
145
|
} catch (err) {
|
|
87
|
-
s.stop(`${pc.red("✗")}
|
|
146
|
+
s.stop(`${pc.red("✗")} ${err.message}`)
|
|
88
147
|
process.exit(1)
|
|
89
148
|
}
|
|
90
149
|
|
|
91
|
-
outro(
|
|
150
|
+
outro(pc.green("Done 🚀"))
|
|
92
151
|
})
|
|
93
152
|
|
|
94
153
|
program
|
|
@@ -97,14 +156,18 @@ program
|
|
|
97
156
|
.action(() => {
|
|
98
157
|
printBanner()
|
|
99
158
|
intro(pc.bold("Installed skills"))
|
|
159
|
+
|
|
100
160
|
const cwd = process.cwd()
|
|
101
161
|
let found = false
|
|
162
|
+
|
|
102
163
|
for (const [, config] of Object.entries(TOOLS)) {
|
|
103
164
|
const dir = path.join(cwd, config.projectPath)
|
|
165
|
+
|
|
104
166
|
if (fs.existsSync(dir)) {
|
|
105
167
|
const skills = fs.readdirSync(dir).filter(f =>
|
|
106
168
|
fs.statSync(path.join(dir, f)).isDirectory()
|
|
107
169
|
)
|
|
170
|
+
|
|
108
171
|
if (skills.length > 0) {
|
|
109
172
|
found = true
|
|
110
173
|
console.log(`\n ${pc.bold(config.label)}`)
|
|
@@ -112,11 +175,14 @@ program
|
|
|
112
175
|
}
|
|
113
176
|
}
|
|
114
177
|
}
|
|
178
|
+
|
|
115
179
|
if (!found) {
|
|
116
180
|
console.log(pc.dim("\n No skills installed."))
|
|
181
|
+
console.log(pc.dim(" Run `skilldotmd add` to install one."))
|
|
117
182
|
}
|
|
183
|
+
|
|
118
184
|
console.log("")
|
|
119
185
|
outro("Done")
|
|
120
186
|
})
|
|
121
187
|
|
|
122
|
-
program.parse()
|
|
188
|
+
program.parse()
|