@dragonbot-skills/cli 0.1.0 → 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.
- package/README.md +53 -29
- package/dist/cli.js +153 -48
- package/dist/cli.js.map +1 -1
- package/dist/install.js +107 -68
- package/dist/install.js.map +1 -1
- package/dist/platforms.js +138 -0
- package/dist/platforms.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
# @dragonbot-skills/cli
|
|
2
2
|
|
|
3
|
-
Install
|
|
4
|
-
|
|
3
|
+
Install Claude skills from the DragonBot catalog into every AI coding
|
|
4
|
+
tool you use, with one command:
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npx @dragonbot-skills/cli install amazon-kw-research
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
That
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
That auto-detects every AI coding platform installed on your machine
|
|
11
|
+
(Claude Code, Cursor, Codex CLI, GitHub Copilot, Windsurf, Cline,
|
|
12
|
+
OpenCode, Continue, Gemini CLI, Roo, Zed) and drops the skill folder
|
|
13
|
+
into each one's skills directory. Install once, available everywhere.
|
|
14
14
|
|
|
15
15
|
## Commands
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
# What
|
|
18
|
+
# What skills are in the catalog?
|
|
19
19
|
dragonbot-skills list
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# What platforms am I targeting?
|
|
22
|
+
dragonbot-skills list-platforms
|
|
23
|
+
|
|
24
|
+
# Install (auto-detects every supported platform)
|
|
22
25
|
dragonbot-skills install amazon-kw-research
|
|
23
26
|
|
|
24
|
-
#
|
|
25
|
-
dragonbot-skills install amazon-kw-research --
|
|
27
|
+
# Scope to specific platforms
|
|
28
|
+
dragonbot-skills install amazon-kw-research --target claude-code,cursor
|
|
29
|
+
|
|
30
|
+
# Install to a raw directory (useful for clients we don't recognize yet)
|
|
31
|
+
dragonbot-skills install amazon-kw-research --dir ./.claude/skills
|
|
26
32
|
|
|
27
|
-
#
|
|
28
|
-
dragonbot-skills install amazon-kw-research --
|
|
33
|
+
# Preview what would happen, write nothing
|
|
34
|
+
dragonbot-skills install amazon-kw-research --dry-run
|
|
29
35
|
|
|
30
36
|
# Reinstall over an existing copy
|
|
31
37
|
dragonbot-skills install amazon-kw-research --force
|
|
32
38
|
|
|
33
|
-
# Remove
|
|
39
|
+
# Remove (also multi-platform by default)
|
|
34
40
|
dragonbot-skills uninstall amazon-kw-research
|
|
35
41
|
```
|
|
36
42
|
|
|
@@ -42,33 +48,44 @@ dragonbot-skills uninstall amazon-kw-research
|
|
|
42
48
|
|---|---|
|
|
43
49
|
| `amazon-kw-research` | Amazon keyword research → workbook + PPC setup (uses Keepa + Jungle Scout via the DragonBot MCP). |
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
after upgrading.
|
|
51
|
+
Catalog grows over time — run `dragonbot-skills list` after upgrading.
|
|
47
52
|
|
|
48
53
|
## Where it installs
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|---|---|---|
|
|
52
|
-
| `user` *(default)* | `~/.claude/skills/<slug>/` | one install, every project on this machine sees it |
|
|
53
|
-
| `--project` | `<cwd>/.claude/skills/<slug>/` | this repo only |
|
|
54
|
-
| `--target <dir>` | `<dir>/<slug>/` | custom — for clients that use a different skills directory |
|
|
55
|
+
Default behavior: install to **every detected platform**. The registry:
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
| Platform id | Install path | Detected by |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `claude-code` | `~/.claude/skills/<slug>/` | `~/.claude` exists |
|
|
60
|
+
| `cursor` | `~/.cursor/skills/<slug>/` | `~/.cursor` exists |
|
|
61
|
+
| `codex` | `~/.codex/skills/<slug>/` | `~/.codex` exists |
|
|
62
|
+
| `copilot` | `<cwd>/.github/copilot/skills/<slug>/` | `.github/copilot/` or `.github/copilot-instructions.md` |
|
|
63
|
+
| `windsurf` | `~/.windsurf/skills/<slug>/` | `~/.windsurf` or `.windsurfrules` |
|
|
64
|
+
| `cline` | `~/.cline/skills/<slug>/` | `~/.cline` or `.clinerules` |
|
|
65
|
+
| `opencode` | `~/.opencode/skills/<slug>/` | `~/.opencode` exists |
|
|
66
|
+
| `continue` | `~/.continue/skills/<slug>/` | `~/.continue` exists |
|
|
67
|
+
| `gemini` | `~/.gemini/skills/<slug>/` | `~/.gemini` exists |
|
|
68
|
+
| `roo` | `~/.roo/skills/<slug>/` | `~/.roo` or `.roorules` |
|
|
69
|
+
| `zed` | `~/Library/Application Support/Zed/skills/<slug>/` (macOS) | parent dir exists |
|
|
70
|
+
|
|
71
|
+
Some paths are best-effort (the platform hasn't documented a canonical
|
|
72
|
+
skills directory). They're marked in the source — open an issue if
|
|
73
|
+
you know better.
|
|
74
|
+
|
|
75
|
+
Run `dragonbot-skills list-platforms` on your machine to see what's
|
|
76
|
+
detected and where each install would land.
|
|
60
77
|
|
|
61
78
|
## Updating
|
|
62
79
|
|
|
63
|
-
Skills are bundled with this package, so
|
|
64
|
-
latest
|
|
80
|
+
Skills are bundled with this package, so upgrading is just re-running
|
|
81
|
+
`npx` with `@latest`:
|
|
65
82
|
|
|
66
83
|
```bash
|
|
67
84
|
npx @dragonbot-skills/cli@latest install amazon-kw-research --force
|
|
68
85
|
```
|
|
69
86
|
|
|
70
87
|
`--force` is needed because we won't silently overwrite an existing
|
|
71
|
-
install.
|
|
88
|
+
install.
|
|
72
89
|
|
|
73
90
|
## Development
|
|
74
91
|
|
|
@@ -77,15 +94,22 @@ npm install
|
|
|
77
94
|
npm run typecheck
|
|
78
95
|
npm test
|
|
79
96
|
npm run build # → dist/cli.js (chmod +x)
|
|
80
|
-
node dist/cli.js list
|
|
97
|
+
node dist/cli.js list-platforms
|
|
81
98
|
```
|
|
82
99
|
|
|
83
100
|
Skills live in `skills/<slug>/SKILL.md` at the package root. Adding a
|
|
84
|
-
new skill = adding a
|
|
101
|
+
new skill = adding a folder there with a `SKILL.md` containing
|
|
85
102
|
frontmatter (`name:`, `description:`) and a markdown body. The
|
|
86
103
|
`bundledRoot` test override pattern in `src/install.test.ts` lets you
|
|
87
104
|
unit-test against synthetic skills without touching the real catalog.
|
|
88
105
|
|
|
106
|
+
## Credits
|
|
107
|
+
|
|
108
|
+
The auto-detect-and-install-everywhere pattern is adapted from
|
|
109
|
+
[skills-hub.ai](https://skills-hub.ai)'s
|
|
110
|
+
[@skills-hub-ai/cli](https://www.npmjs.com/package/@skills-hub-ai/cli)
|
|
111
|
+
(MIT). They pioneered this UX for Claude-style skills.
|
|
112
|
+
|
|
89
113
|
## License
|
|
90
114
|
|
|
91
115
|
MIT — see [LICENSE](LICENSE).
|
package/dist/cli.js
CHANGED
|
@@ -1,36 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @dragonbot-skills/cli — installer for DragonBot's Claude skills.
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// Default install behavior: auto-detect every AI coding platform
|
|
5
|
+
// installed on this machine (Claude Code, Cursor, Codex, Copilot,
|
|
6
|
+
// Windsurf, ...) and drop the skill into each one. Match the
|
|
7
|
+
// "install once, works everywhere" UX from other skills hubs.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// reach for one.
|
|
9
|
+
// Override with `--target claude-code,cursor` (specific platforms)
|
|
10
|
+
// or `--dir <path>` (raw directory).
|
|
12
11
|
import { listBundledSkills } from "./skills.js";
|
|
13
|
-
import { install, uninstall } from "./install.js";
|
|
12
|
+
import { install, uninstall, resolveDestinations, parsePlatformIds, detectAllPlatforms, } from "./install.js";
|
|
13
|
+
import { PLATFORM_REGISTRY, realEnv } from "./platforms.js";
|
|
14
14
|
const USAGE = `dragonbot-skills — install Claude skills from the DragonBot catalog
|
|
15
15
|
|
|
16
16
|
Usage:
|
|
17
17
|
dragonbot-skills list
|
|
18
|
-
dragonbot-skills
|
|
19
|
-
dragonbot-skills
|
|
18
|
+
dragonbot-skills list-platforms
|
|
19
|
+
dragonbot-skills install <slug> [--target IDS] [--dir DIR] [--force] [--dry-run]
|
|
20
|
+
dragonbot-skills uninstall <slug> [--target IDS] [--dir DIR]
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
--target
|
|
22
|
+
Default behavior:
|
|
23
|
+
install / uninstall auto-detects every installed AI coding platform
|
|
24
|
+
(Claude Code, Cursor, Codex, Copilot, Windsurf, Cline, ...) and
|
|
25
|
+
applies the action to ALL of them. Use --target or --dir to scope.
|
|
25
26
|
|
|
26
27
|
Flags:
|
|
27
|
-
--
|
|
28
|
-
|
|
28
|
+
--target IDS comma-separated platform ids (e.g. claude-code,cursor)
|
|
29
|
+
see \`list-platforms\` for the full set
|
|
30
|
+
--dir DIR install to <DIR>/<slug>/ instead of any detected
|
|
31
|
+
platform — useful for clients we don't recognize
|
|
32
|
+
--force overwrite an existing install
|
|
33
|
+
--dry-run show what install would do without writing anything
|
|
34
|
+
-h, --help show this help
|
|
29
35
|
|
|
30
36
|
Examples:
|
|
31
37
|
dragonbot-skills install amazon-kw-research
|
|
32
|
-
dragonbot-skills install amazon-kw-research --
|
|
33
|
-
dragonbot-skills
|
|
38
|
+
dragonbot-skills install amazon-kw-research --target claude-code,cursor
|
|
39
|
+
dragonbot-skills install amazon-kw-research --dir ./.claude/skills
|
|
40
|
+
dragonbot-skills install amazon-kw-research --dry-run
|
|
41
|
+
dragonbot-skills list-platforms
|
|
34
42
|
`;
|
|
35
43
|
function main(argv) {
|
|
36
44
|
const args = argv.slice(2);
|
|
@@ -43,6 +51,8 @@ function main(argv) {
|
|
|
43
51
|
switch (command) {
|
|
44
52
|
case "list":
|
|
45
53
|
return runList();
|
|
54
|
+
case "list-platforms":
|
|
55
|
+
return runListPlatforms();
|
|
46
56
|
case "install":
|
|
47
57
|
return runInstall(rest);
|
|
48
58
|
case "uninstall":
|
|
@@ -61,29 +71,105 @@ function runList() {
|
|
|
61
71
|
process.stdout.write(`Available skills (${skills.length}):\n\n`);
|
|
62
72
|
const slugWidth = Math.max(...skills.map((s) => s.slug.length));
|
|
63
73
|
for (const s of skills) {
|
|
64
|
-
|
|
65
|
-
process.stdout.write(` ${padded} ${s.description}\n`);
|
|
74
|
+
process.stdout.write(` ${s.slug.padEnd(slugWidth, " ")} ${s.description}\n`);
|
|
66
75
|
}
|
|
67
76
|
process.stdout.write("\nInstall one with: dragonbot-skills install <slug>\n");
|
|
68
77
|
return 0;
|
|
69
78
|
}
|
|
79
|
+
function runListPlatforms() {
|
|
80
|
+
const env = realEnv();
|
|
81
|
+
const detected = new Set(detectAllPlatforms(env).map((p) => p.id));
|
|
82
|
+
process.stdout.write("Supported platforms:\n\n");
|
|
83
|
+
const idWidth = Math.max(...PLATFORM_REGISTRY.map((p) => p.id.length));
|
|
84
|
+
for (const p of PLATFORM_REGISTRY) {
|
|
85
|
+
const tag = detected.has(p.id) ? "✓ detected" : " (not detected)";
|
|
86
|
+
process.stdout.write(` ${p.id.padEnd(idWidth, " ")} ${tag} ${p.label} → ${p.path(env)}\n`);
|
|
87
|
+
}
|
|
88
|
+
process.stdout.write("\nDefault install targets every detected platform. Override with " +
|
|
89
|
+
"--target <id>[,<id>...] or --dir <path>.\n");
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
70
92
|
function runInstall(rest) {
|
|
71
|
-
|
|
93
|
+
let parsed;
|
|
94
|
+
try {
|
|
95
|
+
parsed = parseFlags(rest);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
process.stderr.write(`${err.message}\n`);
|
|
99
|
+
return 2;
|
|
100
|
+
}
|
|
101
|
+
const { positionals, flags } = parsed;
|
|
72
102
|
const slug = positionals[0];
|
|
73
103
|
if (!slug) {
|
|
74
104
|
process.stderr.write("install: missing <slug>\n\n" + USAGE);
|
|
75
105
|
return 2;
|
|
76
106
|
}
|
|
77
|
-
|
|
107
|
+
if (flags.target && flags.dir) {
|
|
108
|
+
process.stderr.write("install: --target and --dir are mutually exclusive\n");
|
|
109
|
+
return 2;
|
|
110
|
+
}
|
|
111
|
+
// Resolve --target into known platforms; warn on typos before installing.
|
|
112
|
+
let targets;
|
|
113
|
+
if (flags.target) {
|
|
114
|
+
const { known, unknown } = parsePlatformIds(flags.target);
|
|
115
|
+
if (unknown.length > 0) {
|
|
116
|
+
process.stderr.write(`Unknown platform id(s): ${unknown.join(", ")}\n` +
|
|
117
|
+
`Run \`dragonbot-skills list-platforms\` for the full set.\n`);
|
|
118
|
+
return 2;
|
|
119
|
+
}
|
|
120
|
+
targets = known;
|
|
121
|
+
}
|
|
122
|
+
// Preview the destinations before doing the work. If nothing was
|
|
123
|
+
// detected and the user didn't override, explain it before
|
|
124
|
+
// throwing — much nicer than a wall of text from the thrown error.
|
|
125
|
+
const previewDests = resolveDestinations({ targets, dir: flags.dir });
|
|
126
|
+
if (previewDests.length === 0) {
|
|
127
|
+
process.stderr.write("No supported AI coding platforms were detected on this machine.\n" +
|
|
128
|
+
"Pass --target <id> (see `dragonbot-skills list-platforms`) or " +
|
|
129
|
+
"--dir <path> to install anyway.\n");
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
78
132
|
try {
|
|
79
133
|
const result = install({
|
|
80
134
|
slug,
|
|
81
|
-
|
|
82
|
-
|
|
135
|
+
targets,
|
|
136
|
+
dir: flags.dir,
|
|
83
137
|
force: flags.force,
|
|
138
|
+
dryRun: flags.dryRun,
|
|
84
139
|
});
|
|
85
|
-
|
|
86
|
-
|
|
140
|
+
let installed = 0;
|
|
141
|
+
let skipped = 0;
|
|
142
|
+
let errored = 0;
|
|
143
|
+
for (const entry of result.entries) {
|
|
144
|
+
const tag = entry.status === "installed"
|
|
145
|
+
? "✓"
|
|
146
|
+
: entry.status === "would-install"
|
|
147
|
+
? "·"
|
|
148
|
+
: entry.status === "skipped-exists"
|
|
149
|
+
? "⊝"
|
|
150
|
+
: "✗";
|
|
151
|
+
const trailer = entry.reason ? ` (${entry.reason})` : "";
|
|
152
|
+
process.stdout.write(`${tag} ${entry.label.padEnd(16)} → ${entry.installedTo}${trailer}\n`);
|
|
153
|
+
if (entry.status === "installed")
|
|
154
|
+
installed++;
|
|
155
|
+
else if (entry.status === "skipped-exists")
|
|
156
|
+
skipped++;
|
|
157
|
+
else if (entry.status === "error")
|
|
158
|
+
errored++;
|
|
159
|
+
}
|
|
160
|
+
if (flags.dryRun) {
|
|
161
|
+
process.stdout.write(`\n(dry run — nothing written)\n`);
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
const summary = [];
|
|
165
|
+
if (installed)
|
|
166
|
+
summary.push(`${installed} installed`);
|
|
167
|
+
if (skipped)
|
|
168
|
+
summary.push(`${skipped} skipped (use --force to overwrite)`);
|
|
169
|
+
if (errored)
|
|
170
|
+
summary.push(`${errored} failed`);
|
|
171
|
+
process.stdout.write(`\n${summary.join(", ") || "no-op"}\n`);
|
|
172
|
+
return errored > 0 ? 1 : 0;
|
|
87
173
|
}
|
|
88
174
|
catch (err) {
|
|
89
175
|
process.stderr.write(`${err.message}\n`);
|
|
@@ -91,31 +177,46 @@ function runInstall(rest) {
|
|
|
91
177
|
}
|
|
92
178
|
}
|
|
93
179
|
function runUninstall(rest) {
|
|
94
|
-
|
|
180
|
+
let parsed;
|
|
181
|
+
try {
|
|
182
|
+
parsed = parseFlags(rest);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
process.stderr.write(`${err.message}\n`);
|
|
186
|
+
return 2;
|
|
187
|
+
}
|
|
188
|
+
const { positionals, flags } = parsed;
|
|
95
189
|
const slug = positionals[0];
|
|
96
190
|
if (!slug) {
|
|
97
191
|
process.stderr.write("uninstall: missing <slug>\n\n" + USAGE);
|
|
98
192
|
return 2;
|
|
99
193
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
if (
|
|
108
|
-
process.
|
|
194
|
+
if (flags.target && flags.dir) {
|
|
195
|
+
process.stderr.write("uninstall: --target and --dir are mutually exclusive\n");
|
|
196
|
+
return 2;
|
|
197
|
+
}
|
|
198
|
+
let targets;
|
|
199
|
+
if (flags.target) {
|
|
200
|
+
const { known, unknown } = parsePlatformIds(flags.target);
|
|
201
|
+
if (unknown.length > 0) {
|
|
202
|
+
process.stderr.write(`Unknown platform id(s): ${unknown.join(", ")}\n`);
|
|
203
|
+
return 2;
|
|
204
|
+
}
|
|
205
|
+
targets = known;
|
|
206
|
+
}
|
|
207
|
+
const result = uninstall({ slug, targets, dir: flags.dir });
|
|
208
|
+
let removed = 0;
|
|
209
|
+
for (const entry of result.entries) {
|
|
210
|
+
if (entry.removed) {
|
|
211
|
+
process.stdout.write(`✓ ${entry.label.padEnd(16)} → ${entry.path}\n`);
|
|
212
|
+
removed++;
|
|
109
213
|
}
|
|
110
214
|
else {
|
|
111
|
-
process.stdout.write(
|
|
215
|
+
process.stdout.write(`· ${entry.label.padEnd(16)} → ${entry.path} (not installed)\n`);
|
|
112
216
|
}
|
|
113
|
-
return 0;
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
process.stderr.write(`${err.message}\n`);
|
|
117
|
-
return 1;
|
|
118
217
|
}
|
|
218
|
+
process.stdout.write(`\n${removed} removed\n`);
|
|
219
|
+
return 0;
|
|
119
220
|
}
|
|
120
221
|
function parseFlags(args) {
|
|
121
222
|
const positionals = [];
|
|
@@ -130,17 +231,21 @@ function parseFlags(args) {
|
|
|
130
231
|
const key = eq < 0 ? arg.slice(2) : arg.slice(2, eq);
|
|
131
232
|
const inlineValue = eq < 0 ? undefined : arg.slice(eq + 1);
|
|
132
233
|
switch (key) {
|
|
133
|
-
case "project":
|
|
134
|
-
flags.project = true;
|
|
135
|
-
break;
|
|
136
234
|
case "force":
|
|
137
235
|
flags.force = true;
|
|
138
236
|
break;
|
|
237
|
+
case "dry-run":
|
|
238
|
+
flags.dryRun = true;
|
|
239
|
+
break;
|
|
139
240
|
case "target":
|
|
140
241
|
flags.target = inlineValue ?? args[++i];
|
|
141
|
-
if (!flags.target)
|
|
142
|
-
throw new Error("--target needs a
|
|
143
|
-
|
|
242
|
+
if (!flags.target)
|
|
243
|
+
throw new Error("--target needs a value");
|
|
244
|
+
break;
|
|
245
|
+
case "dir":
|
|
246
|
+
flags.dir = inlineValue ?? args[++i];
|
|
247
|
+
if (!flags.dir)
|
|
248
|
+
throw new Error("--dir needs a directory path");
|
|
144
249
|
break;
|
|
145
250
|
default:
|
|
146
251
|
throw new Error(`Unknown flag: --${key}`);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,mEAAmE;AACnE,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/install.js
CHANGED
|
@@ -1,68 +1,127 @@
|
|
|
1
|
-
// Install / uninstall skills
|
|
2
|
-
// directory.
|
|
1
|
+
// Install / uninstall skills across one or more AI-coding platforms.
|
|
3
2
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Default behavior (no --target): auto-detect every installed
|
|
4
|
+
// platform (Claude Code, Cursor, Codex, Copilot, ...) and write the
|
|
5
|
+
// skill to each one. This matches the user's mental model from
|
|
6
|
+
// other skills hubs ("install the skill, it shows up everywhere").
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// that put their skills directory somewhere else.
|
|
8
|
+
// Override with `--target claude-code,cursor` (specific platforms)
|
|
9
|
+
// or `--dir <path>` (raw directory — useful for clients we don't
|
|
10
|
+
// have in the registry yet).
|
|
12
11
|
//
|
|
13
|
-
//
|
|
14
|
-
// destination, then rename
|
|
15
|
-
//
|
|
16
|
-
// explicit, not silent.
|
|
12
|
+
// Each install is atomic-ish: copy to a staging dir next to the
|
|
13
|
+
// destination, then rename. We refuse to overwrite an existing
|
|
14
|
+
// install without --force — silent reinstalls hide problems.
|
|
17
15
|
import fs from "node:fs";
|
|
18
|
-
import os from "node:os";
|
|
19
16
|
import path from "node:path";
|
|
20
17
|
import { findBundledSkill } from "./skills.js";
|
|
18
|
+
import { detectAllPlatforms, realEnv, } from "./platforms.js";
|
|
21
19
|
/**
|
|
22
|
-
* Resolve the
|
|
23
|
-
*
|
|
20
|
+
* Resolve the list of destinations for an install call. Single
|
|
21
|
+
* function so the CLI can show "what would I install where" in
|
|
22
|
+
* --dry-run mode without duplicating the resolution logic.
|
|
24
23
|
*/
|
|
25
|
-
export function
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
export function resolveDestinations(opts) {
|
|
25
|
+
const env = opts.env ?? realEnv();
|
|
26
|
+
if (opts.dir) {
|
|
27
|
+
return [
|
|
28
|
+
{ platform: "custom", label: "Custom directory", root: path.resolve(opts.dir) },
|
|
29
|
+
];
|
|
28
30
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return { root: path.join(home, ".claude", "skills"), scope: "user" };
|
|
31
|
+
const platforms = opts.targets ?? detectAllPlatforms(env);
|
|
32
|
+
return platforms.map((p) => ({
|
|
33
|
+
platform: p.id,
|
|
34
|
+
label: p.label,
|
|
35
|
+
root: p.path(env),
|
|
36
|
+
}));
|
|
36
37
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Copy the bundled skill folder for `slug` into the chosen skills
|
|
39
|
-
* directory. Throws when:
|
|
40
|
-
* - the slug isn't bundled in this package
|
|
41
|
-
* - the destination exists and `force` is false
|
|
42
|
-
*/
|
|
43
38
|
export function install(opts) {
|
|
44
39
|
const src = findBundledSkill(opts.slug, opts.bundledRoot);
|
|
45
40
|
if (!src) {
|
|
46
41
|
throw new Error(`Skill not found in this package: ${opts.slug}\n` +
|
|
47
42
|
`Run \`dragonbot-skills list\` to see what's available.`);
|
|
48
43
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
home: opts.home,
|
|
44
|
+
const destinations = resolveDestinations({
|
|
45
|
+
targets: opts.targets,
|
|
46
|
+
dir: opts.dir,
|
|
47
|
+
env: opts.env,
|
|
54
48
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
if (destinations.length === 0) {
|
|
50
|
+
throw new Error("No install destinations resolved. None of the supported AI " +
|
|
51
|
+
"coding platforms were detected on this machine. Pass " +
|
|
52
|
+
"--target claude-code (or another platform id, see " +
|
|
53
|
+
"`dragonbot-skills list-platforms`) or --dir <path> to " +
|
|
54
|
+
"install anyway.");
|
|
55
|
+
}
|
|
56
|
+
const entries = [];
|
|
57
|
+
for (const dest of destinations) {
|
|
58
|
+
const installedTo = path.join(dest.root, opts.slug);
|
|
59
|
+
try {
|
|
60
|
+
if (opts.dryRun) {
|
|
61
|
+
entries.push({
|
|
62
|
+
platform: dest.platform,
|
|
63
|
+
label: dest.label,
|
|
64
|
+
installedTo,
|
|
65
|
+
status: "would-install",
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (fs.existsSync(installedTo)) {
|
|
70
|
+
if (!opts.force) {
|
|
71
|
+
entries.push({
|
|
72
|
+
platform: dest.platform,
|
|
73
|
+
label: dest.label,
|
|
74
|
+
installedTo,
|
|
75
|
+
status: "skipped-exists",
|
|
76
|
+
reason: "destination exists; pass --force to overwrite",
|
|
77
|
+
});
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
fs.rmSync(installedTo, { recursive: true, force: true });
|
|
81
|
+
}
|
|
82
|
+
fs.mkdirSync(dest.root, { recursive: true });
|
|
83
|
+
copyIntoPlace(src, installedTo, opts.slug, dest.root);
|
|
84
|
+
entries.push({
|
|
85
|
+
platform: dest.platform,
|
|
86
|
+
label: dest.label,
|
|
87
|
+
installedTo,
|
|
88
|
+
status: "installed",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
entries.push({
|
|
93
|
+
platform: dest.platform,
|
|
94
|
+
label: dest.label,
|
|
95
|
+
installedTo,
|
|
96
|
+
status: "error",
|
|
97
|
+
reason: err.message,
|
|
98
|
+
});
|
|
59
99
|
}
|
|
60
|
-
fs.rmSync(dest, { recursive: true, force: true });
|
|
61
100
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
101
|
+
return { slug: opts.slug, entries };
|
|
102
|
+
}
|
|
103
|
+
export function uninstall(opts) {
|
|
104
|
+
const destinations = resolveDestinations({
|
|
105
|
+
targets: opts.targets,
|
|
106
|
+
dir: opts.dir,
|
|
107
|
+
env: opts.env,
|
|
108
|
+
});
|
|
109
|
+
const entries = [];
|
|
110
|
+
for (const dest of destinations) {
|
|
111
|
+
const target = path.join(dest.root, opts.slug);
|
|
112
|
+
if (!fs.existsSync(target)) {
|
|
113
|
+
entries.push({ platform: dest.platform, label: dest.label, path: target, removed: false });
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
117
|
+
entries.push({ platform: dest.platform, label: dest.label, path: target, removed: true });
|
|
118
|
+
}
|
|
119
|
+
return { slug: opts.slug, entries };
|
|
120
|
+
}
|
|
121
|
+
// Stage in a sibling tmp dir, then rename. Avoids leaving a half-
|
|
122
|
+
// copied skill folder behind if the copy is interrupted.
|
|
123
|
+
function copyIntoPlace(src, dest, slug, parent) {
|
|
124
|
+
const staging = fs.mkdtempSync(path.join(parent, `.${slug}-staging-`));
|
|
66
125
|
try {
|
|
67
126
|
copyDirRecursive(src, staging);
|
|
68
127
|
fs.renameSync(staging, dest);
|
|
@@ -71,29 +130,7 @@ export function install(opts) {
|
|
|
71
130
|
fs.rmSync(staging, { recursive: true, force: true });
|
|
72
131
|
throw err;
|
|
73
132
|
}
|
|
74
|
-
return { installedTo: dest, scope };
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Remove the installed skill folder. Idempotent: returns
|
|
78
|
-
* `removed: false` (no error) when the folder isn't present.
|
|
79
|
-
*/
|
|
80
|
-
export function uninstall(opts) {
|
|
81
|
-
const { root, scope } = resolveSkillsRoot({
|
|
82
|
-
scope: opts.scope,
|
|
83
|
-
targetDir: opts.targetDir,
|
|
84
|
-
cwd: opts.cwd,
|
|
85
|
-
home: opts.home,
|
|
86
|
-
});
|
|
87
|
-
const dest = path.join(root, opts.slug);
|
|
88
|
-
if (!fs.existsSync(dest)) {
|
|
89
|
-
return { removed: false, path: dest, scope };
|
|
90
|
-
}
|
|
91
|
-
fs.rmSync(dest, { recursive: true, force: true });
|
|
92
|
-
return { removed: true, path: dest, scope };
|
|
93
133
|
}
|
|
94
|
-
// Minimal recursive copy — no externals, follows directories and
|
|
95
|
-
// regular files only. Symlinks aren't expected in skills today; if
|
|
96
|
-
// we ever ship one, switch to fs.cp({ recursive: true, verbatimSymlinks: true }).
|
|
97
134
|
function copyDirRecursive(src, dest) {
|
|
98
135
|
fs.mkdirSync(dest, { recursive: true });
|
|
99
136
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
@@ -108,4 +145,6 @@ function copyDirRecursive(src, dest) {
|
|
|
108
145
|
// Symlinks + special files: skip silently.
|
|
109
146
|
}
|
|
110
147
|
}
|
|
148
|
+
/** Re-export so the CLI doesn't need to import from two modules. */
|
|
149
|
+
export { getPlatform, parsePlatformIds, detectAllPlatforms } from "./platforms.js";
|
|
111
150
|
//# sourceMappingURL=install.js.map
|
package/dist/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Registry of supported AI coding platforms — each entry knows where
|
|
2
|
+
// to drop SKILL.md and how to tell whether the platform is installed
|
|
3
|
+
// on this machine.
|
|
4
|
+
//
|
|
5
|
+
// Design adapted from skills-hub.ai's @skills-hub-ai/cli
|
|
6
|
+
// (https://www.npmjs.com/package/@skills-hub-ai/cli, MIT). They
|
|
7
|
+
// pioneered the "auto-detect installed clients + install to every
|
|
8
|
+
// one" UX for Claude-style skills; we're following their lead so a
|
|
9
|
+
// user's existing muscle memory carries over.
|
|
10
|
+
//
|
|
11
|
+
// Add a platform: append to PLATFORM_REGISTRY. Tests + the install
|
|
12
|
+
// command + the `list-platforms` command all read from this one
|
|
13
|
+
// source of truth.
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import os from "node:os";
|
|
17
|
+
export function realEnv() {
|
|
18
|
+
return { home: os.homedir(), cwd: process.cwd() };
|
|
19
|
+
}
|
|
20
|
+
const has = (...segments) => fs.existsSync(path.join(...segments));
|
|
21
|
+
export const PLATFORM_REGISTRY = [
|
|
22
|
+
{
|
|
23
|
+
id: "claude-code",
|
|
24
|
+
label: "Claude Code",
|
|
25
|
+
path: (e) => path.join(e.home, ".claude", "skills"),
|
|
26
|
+
detect: (e) => has(e.home, ".claude"),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "cursor",
|
|
30
|
+
label: "Cursor",
|
|
31
|
+
path: (e) => path.join(e.home, ".cursor", "skills"),
|
|
32
|
+
detect: (e) => has(e.home, ".cursor"),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "codex",
|
|
36
|
+
label: "Codex CLI",
|
|
37
|
+
path: (e) => path.join(e.home, ".codex", "skills"),
|
|
38
|
+
detect: (e) => has(e.home, ".codex"),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "copilot",
|
|
42
|
+
label: "GitHub Copilot",
|
|
43
|
+
// Copilot uses .github/copilot-instructions.md at workspace root;
|
|
44
|
+
// we drop per-skill folders under .github/copilot/skills/ so the
|
|
45
|
+
// user can opt them in via custom instructions without colliding
|
|
46
|
+
// with the single documented file.
|
|
47
|
+
path: (e) => path.join(e.cwd, ".github", "copilot", "skills"),
|
|
48
|
+
detect: (e) => has(e.cwd, ".github", "copilot") ||
|
|
49
|
+
has(e.cwd, ".github", "copilot-instructions.md"),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "windsurf",
|
|
53
|
+
label: "Windsurf",
|
|
54
|
+
path: (e) => path.join(e.home, ".windsurf", "skills"),
|
|
55
|
+
detect: (e) => has(e.home, ".windsurf") || has(e.cwd, ".windsurfrules"),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "cline",
|
|
59
|
+
label: "Cline",
|
|
60
|
+
path: (e) => path.join(e.home, ".cline", "skills"),
|
|
61
|
+
detect: (e) => has(e.home, ".cline") || has(e.cwd, ".clinerules"),
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "opencode",
|
|
65
|
+
label: "OpenCode",
|
|
66
|
+
path: (e) => path.join(e.home, ".opencode", "skills"),
|
|
67
|
+
detect: (e) => has(e.home, ".opencode"),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "continue",
|
|
71
|
+
label: "Continue",
|
|
72
|
+
// Best-effort: Continue uses ~/.continue/config.json; the skills
|
|
73
|
+
// subdir is not yet a documented loader location.
|
|
74
|
+
path: (e) => path.join(e.home, ".continue", "skills"),
|
|
75
|
+
detect: (e) => has(e.home, ".continue"),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "gemini",
|
|
79
|
+
label: "Gemini CLI",
|
|
80
|
+
// Best-effort: ~/.gemini is the published config root; the
|
|
81
|
+
// skills subdir is not (yet) documented.
|
|
82
|
+
path: (e) => path.join(e.home, ".gemini", "skills"),
|
|
83
|
+
detect: (e) => has(e.home, ".gemini"),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "roo",
|
|
87
|
+
label: "Roo Code",
|
|
88
|
+
path: (e) => path.join(e.home, ".roo", "skills"),
|
|
89
|
+
detect: (e) => has(e.home, ".roo") || has(e.cwd, ".roorules"),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "zed",
|
|
93
|
+
label: "Zed",
|
|
94
|
+
// macOS uses ~/Library/Application Support/Zed; Linux uses
|
|
95
|
+
// ~/.config/zed. We pick per-platform at call time.
|
|
96
|
+
path: (e) => zedPath(e.home),
|
|
97
|
+
detect: (e) => fs.existsSync(path.dirname(zedPath(e.home))),
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
function zedPath(home) {
|
|
101
|
+
if (os.platform() === "darwin") {
|
|
102
|
+
return path.join(home, "Library", "Application Support", "Zed", "skills");
|
|
103
|
+
}
|
|
104
|
+
return path.join(home, ".config", "zed", "skills");
|
|
105
|
+
}
|
|
106
|
+
export const ALL_PLATFORM_IDS = PLATFORM_REGISTRY.map((p) => p.id);
|
|
107
|
+
export function getPlatform(id) {
|
|
108
|
+
return PLATFORM_REGISTRY.find((p) => p.id === id);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Return every platform that appears to be installed on this
|
|
112
|
+
* machine. Order matches registry order, so Claude Code comes first
|
|
113
|
+
* when multiple are present.
|
|
114
|
+
*/
|
|
115
|
+
export function detectAllPlatforms(env = realEnv()) {
|
|
116
|
+
return PLATFORM_REGISTRY.filter((p) => p.detect(env));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Parse a comma-separated list of platform IDs from the CLI's
|
|
120
|
+
* --target flag. Splits into known + unknown so the caller can warn
|
|
121
|
+
* the user about typos without silently dropping them.
|
|
122
|
+
*/
|
|
123
|
+
export function parsePlatformIds(value) {
|
|
124
|
+
const known = [];
|
|
125
|
+
const unknown = [];
|
|
126
|
+
for (const raw of value.split(",")) {
|
|
127
|
+
const id = raw.trim();
|
|
128
|
+
if (!id)
|
|
129
|
+
continue;
|
|
130
|
+
const entry = getPlatform(id);
|
|
131
|
+
if (entry)
|
|
132
|
+
known.push(entry);
|
|
133
|
+
else
|
|
134
|
+
unknown.push(id);
|
|
135
|
+
}
|
|
136
|
+
return { known, unknown };
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=platforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../src/platforms.ts"],"names":[],"mappings":"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"}
|