@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 CHANGED
@@ -1,36 +1,42 @@
1
1
  # @dragonbot-skills/cli
2
2
 
3
- Install [Claude skills](https://docs.anthropic.com/) from the DragonBot
4
- catalog into your local Claude environment.
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 single command drops `amazon-kw-research/SKILL.md` (plus any
11
- references and scripts) into `~/.claude/skills/amazon-kw-research/`,
12
- where Claude Code (and other Claude clients that follow the same
13
- convention) will pick it up automatically.
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's in the catalog?
18
+ # What skills are in the catalog?
19
19
  dragonbot-skills list
20
20
 
21
- # Install a skill (user-scope: ~/.claude/skills/<slug>/)
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
- # Install for one repo only (./.claude/skills/<slug>/)
25
- dragonbot-skills install amazon-kw-research --project
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
- # Install somewhere custom
28
- dragonbot-skills install amazon-kw-research --target ~/my-claude-skills
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
- More skills will be added here file a PR or run `dragonbot-skills list`
46
- after upgrading.
51
+ Catalog grows over time — run `dragonbot-skills list` after upgrading.
47
52
 
48
53
  ## Where it installs
49
54
 
50
- | Scope | Path | When to use |
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
- Skills installed here are picked up by Claude Code automatically. Other
57
- Claude clients (Desktop, Cowork, etc.) that follow the `.claude/skills/`
58
- convention work the same way; if yours reads from a different path, use
59
- `--target`.
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 updating is just `npx`-ing the
64
- latest version:
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. (No, we don't auto-update — installs are explicit.)
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 new folder there with a `SKILL.md` containing
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
- // Usage:
5
- // npx @dragonbot-skills/cli list
6
- // npx @dragonbot-skills/cli install <slug> [--project] [--target <dir>] [--force]
7
- // npx @dragonbot-skills/cli uninstall <slug> [--project] [--target <dir>]
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
- // Keep the dispatch dumb on purpose — three commands, flat flag
10
- // parsing, no commander/yargs dep. If we ever grow past ~5 commands,
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 install <slug> [--project] [--target <dir>] [--force]
19
- dragonbot-skills uninstall <slug> [--project] [--target <dir>]
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
- Scope:
22
- (default) install to ~/.claude/skills/<slug>/ (user-scope)
23
- --project install to ./.claude/skills/<slug>/ (current repo only)
24
- --target <dir> install to <dir>/<slug>/ (any custom path)
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
- --force overwrite an existing install
28
- -h, --help show this help
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 --project --force
33
- dragonbot-skills list
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
- const padded = s.slug.padEnd(slugWidth, " ");
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
- const { positionals, flags } = parseFlags(rest);
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
- const scope = flags.project ? "project" : "user";
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
- scope,
82
- targetDir: flags.target,
135
+ targets,
136
+ dir: flags.dir,
83
137
  force: flags.force,
138
+ dryRun: flags.dryRun,
84
139
  });
85
- process.stdout.write(`✓ Installed ${slug} → ${result.installedTo} (${result.scope}-scope)\n`);
86
- return 0;
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
- const { positionals, flags } = parseFlags(rest);
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
- const scope = flags.project ? "project" : "user";
101
- try {
102
- const result = uninstall({
103
- slug,
104
- scope,
105
- targetDir: flags.target,
106
- });
107
- if (result.removed) {
108
- process.stdout.write(`✓ Removed ${slug} from ${result.path}\n`);
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(`(no-op) ${result.path} was not installed\n`);
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 directory path");
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":"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"}
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 into the user's local Claude skills
2
- // directory.
1
+ // Install / uninstall skills across one or more AI-coding platforms.
3
2
  //
4
- // Claude Code reads skills from two locations:
5
- // user-scope ~/.claude/skills/<slug>/SKILL.md
6
- // project-scope <cwd>/.claude/skills/<slug>/SKILL.md
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
- // We default to user-scope (one install, every project sees it) and
9
- // expose `--project` for the per-repo variant. `--target <dir>`
10
- // overrides both useful for other Claude clients (Cowork, Desktop)
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
- // Install is atomic-ish: copy to a temp directory next to the
14
- // destination, then rename into place. If the destination already
15
- // exists we refuse without `--force`a real reinstall should be
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 skills directory the CLI should write into for a
23
- * given scope. Doesn't create the directory install() does that.
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 resolveSkillsRoot(opts) {
26
- if (opts.targetDir) {
27
- return { root: path.resolve(opts.targetDir), scope: "custom" };
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 scope = opts.scope ?? "user";
30
- if (scope === "project") {
31
- const cwd = opts.cwd ?? process.cwd();
32
- return { root: path.join(cwd, ".claude", "skills"), scope: "project" };
33
- }
34
- const home = opts.home ?? os.homedir();
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 { root, scope } = resolveSkillsRoot({
50
- scope: opts.scope,
51
- targetDir: opts.targetDir,
52
- cwd: opts.cwd,
53
- home: opts.home,
44
+ const destinations = resolveDestinations({
45
+ targets: opts.targets,
46
+ dir: opts.dir,
47
+ env: opts.env,
54
48
  });
55
- const dest = path.join(root, opts.slug);
56
- if (fs.existsSync(dest)) {
57
- if (!opts.force) {
58
- throw new Error(`${dest} already exists. Pass --force to overwrite.`);
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
- fs.mkdirSync(root, { recursive: true });
63
- // Stage in a sibling tmp dir, then rename. Avoids leaving a half-
64
- // copied skill folder behind if the copy is interrupted.
65
- const staging = fs.mkdtempSync(path.join(root, `.${opts.slug}-staging-`));
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
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,aAAa;AACb,EAAE;AACF,+CAA+C;AAC/C,mDAAmD;AACnD,uDAAuD;AACvD,EAAE;AACF,oEAAoE;AACpE,gEAAgE;AAChE,qEAAqE;AACrE,kDAAkD;AAClD,EAAE;AACF,8DAA8D;AAC9D,kEAAkE;AAClE,kEAAkE;AAClE,wBAAwB;AAExB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAmB/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAKjC;IACC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACjE,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACzE,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IACvC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,IAAiB;IACvC,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,CAAC,IAAI,IAAI;YAC/C,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC;QACxC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,6CAA6C,CACrD,CAAC;QACJ,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,kEAAkE;IAClE,yDAAyD;IACzD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC;QACH,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC/B,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC;AAgBD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC;QACxC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,iEAAiE;AACjE,mEAAmE;AACnE,kFAAkF;AAClF,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACjD,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,2CAA2C;IAC7C,CAAC;AACH,CAAC"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dragonbot-skills/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Install DragonBot skills (Amazon keyword research, etc.) into your local Claude environment.",
5
5
  "type": "module",
6
6
  "bin": {