byteplan-cli 1.3.1 → 1.3.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/README.md +46 -5
- package/package.json +1 -1
- package/src/commands/skills.js +169 -61
package/README.md
CHANGED
|
@@ -43,14 +43,55 @@ byteplan model columns <modelCode>
|
|
|
43
43
|
byteplan data query <modelCode>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
###
|
|
46
|
+
### Skills Commands
|
|
47
|
+
|
|
48
|
+
BytePlan CLI 提供了一系列 Claude Code Skills,可以安装到多个 AI CLI 平台。
|
|
49
|
+
|
|
50
|
+
### 查看可用 Skills
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
byteplan skills list
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 安装 Skills
|
|
57
|
+
|
|
58
|
+
支持多平台安装,使用 `-p` 或 `--platform` 参数指定目标平台:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 安装到 Claude Code
|
|
62
|
+
byteplan skills install byteplan-api -p claude-code
|
|
63
|
+
|
|
64
|
+
# 安装到多个平台
|
|
65
|
+
byteplan skills install -p claude-code,codex,openclaw
|
|
66
|
+
|
|
67
|
+
# 安装所有 Skills
|
|
68
|
+
byteplan skills install-all -p claude-code
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 支持的平台
|
|
72
|
+
|
|
73
|
+
| Platform | 目录 | 说明 |
|
|
74
|
+
|----------|------|------|
|
|
75
|
+
| `claude-code` (alias: `claude`) | `~/.claude/commands` | Claude Code CLI |
|
|
76
|
+
| `codex` | `~/.codex` | OpenAI Codex CLI |
|
|
77
|
+
| `openclaw` | `~/.openclaw/skills` | OpenClaw |
|
|
78
|
+
|
|
79
|
+
### 自定义目录
|
|
80
|
+
|
|
81
|
+
也可以使用 `-d` 参数指定自定义目录:
|
|
47
82
|
|
|
48
83
|
```bash
|
|
49
|
-
#
|
|
50
|
-
byteplan
|
|
84
|
+
# 向后兼容:指定自定义目录
|
|
85
|
+
byteplan skills install byteplan-api -d ~/.claude/commands
|
|
86
|
+
|
|
87
|
+
# 组合使用:覆盖平台默认目录
|
|
88
|
+
byteplan skills install byteplan-api -p claude-code -d /custom/path
|
|
89
|
+
```
|
|
51
90
|
|
|
52
|
-
|
|
53
|
-
|
|
91
|
+
### 查看已安装 Skills
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
byteplan skills installed -p claude-code
|
|
54
95
|
```
|
|
55
96
|
|
|
56
97
|
## Options
|
package/package.json
CHANGED
package/src/commands/skills.js
CHANGED
|
@@ -12,6 +12,14 @@ import { createRequire } from 'module';
|
|
|
12
12
|
|
|
13
13
|
const require = createRequire(import.meta.url);
|
|
14
14
|
|
|
15
|
+
// 平台默认目录映射
|
|
16
|
+
const PLATFORM_DIRS = {
|
|
17
|
+
'claude-code': path.join(homedir(), '.claude', 'commands'),
|
|
18
|
+
'claude': path.join(homedir(), '.claude', 'commands'), // alias
|
|
19
|
+
'codex': path.join(homedir(), '.codex'),
|
|
20
|
+
'openclaw': path.join(homedir(), '.openclaw', 'skills'),
|
|
21
|
+
};
|
|
22
|
+
|
|
15
23
|
// Skills 源目录(在 npm 包中)
|
|
16
24
|
const getSkillsSourceDir = () => {
|
|
17
25
|
// 获取当前模块所在目录,然后向上找到项目根目录
|
|
@@ -20,10 +28,47 @@ const getSkillsSourceDir = () => {
|
|
|
20
28
|
return path.join(currentDir, '..', '..', 'skills');
|
|
21
29
|
};
|
|
22
30
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
// 解析平台和目录参数,返回目标目录列表
|
|
32
|
+
function resolveTargetDirs(platformArg, dirArg) {
|
|
33
|
+
const targets = [];
|
|
34
|
+
|
|
35
|
+
if (platformArg) {
|
|
36
|
+
// 解析平台列表(逗号分隔)
|
|
37
|
+
const platforms = platformArg.split(',').map(p => p.trim());
|
|
38
|
+
|
|
39
|
+
for (const platform of platforms) {
|
|
40
|
+
const normalizedName = platform.toLowerCase();
|
|
41
|
+
const defaultDir = PLATFORM_DIRS[normalizedName];
|
|
42
|
+
|
|
43
|
+
if (!defaultDir) {
|
|
44
|
+
return {
|
|
45
|
+
error: true,
|
|
46
|
+
message: `Unknown platform: ${platform}`,
|
|
47
|
+
available: Object.keys(PLATFORM_DIRS).filter(k => !k.includes('-')),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
targets.push({
|
|
52
|
+
platform: normalizedName,
|
|
53
|
+
targetDir: dirArg || defaultDir, // 如果指定了 -d,覆盖所有平台的默认目录
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
} else if (dirArg) {
|
|
57
|
+
// 向后兼容:只指定 -d 的情况
|
|
58
|
+
targets.push({
|
|
59
|
+
platform: 'custom',
|
|
60
|
+
targetDir: dirArg,
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
// 都不指定,返回错误
|
|
64
|
+
return {
|
|
65
|
+
error: true,
|
|
66
|
+
message: 'Must specify at least one of --platform or --dir',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { targets };
|
|
71
|
+
}
|
|
27
72
|
|
|
28
73
|
function printJSON(data) {
|
|
29
74
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -108,20 +153,28 @@ function getInstalledSkills(targetDir) {
|
|
|
108
153
|
// Skills 命令
|
|
109
154
|
const skillsCmd = new Command('skills')
|
|
110
155
|
.description('Manage BytePlan Claude Code skills')
|
|
111
|
-
.
|
|
156
|
+
.option('-d, --dir <directory>', 'Target installation directory (overrides platform default)')
|
|
157
|
+
.option('-p, --platform <platforms>', 'Target platform(s): claude-code, codex, openclaw (comma-separated for multiple)')
|
|
112
158
|
.addHelpText('after', `
|
|
113
159
|
Commands:
|
|
114
160
|
skills list List all available skills
|
|
115
|
-
skills installed List installed skills (requires -d)
|
|
116
|
-
skills install [names] Install skills
|
|
117
|
-
skills install-all Install all BytePlan skills (requires -d)
|
|
161
|
+
skills installed List installed skills (requires -p or -d)
|
|
162
|
+
skills install [names] Install skills (requires -p or -d)
|
|
163
|
+
skills install-all Install all BytePlan skills (requires -p or -d)
|
|
164
|
+
|
|
165
|
+
Supported Platforms:
|
|
166
|
+
claude-code (alias: claude) → ~/.claude/commands
|
|
167
|
+
codex → ~/.codex
|
|
168
|
+
openclaw → ~/.openclaw/skills
|
|
118
169
|
|
|
119
170
|
Examples:
|
|
120
171
|
$ byteplan skills list
|
|
121
|
-
$ byteplan skills installed -
|
|
122
|
-
$ byteplan skills install byteplan-api
|
|
123
|
-
$ byteplan skills install-
|
|
124
|
-
$ byteplan skills install-all -
|
|
172
|
+
$ byteplan skills installed -p claude-code
|
|
173
|
+
$ byteplan skills install byteplan-api -p claude-code
|
|
174
|
+
$ byteplan skills install byteplan-api byteplan-analysis -p claude-code,codex
|
|
175
|
+
$ byteplan skills install-all -p claude-code,openclaw
|
|
176
|
+
$ byteplan skills install byteplan-api -d ~/.claude/commands
|
|
177
|
+
$ byteplan skills install byteplan-api -p claude-code -d /custom/path
|
|
125
178
|
`);
|
|
126
179
|
|
|
127
180
|
// skills list 子命令
|
|
@@ -151,18 +204,32 @@ skillsCmd
|
|
|
151
204
|
.description('List installed BytePlan skills in target directory')
|
|
152
205
|
.action(() => {
|
|
153
206
|
try {
|
|
154
|
-
// 获取父命令的 -d 选项(requiredOption 已确保必传)
|
|
155
207
|
const parentOptions = skillsCmd.opts();
|
|
156
|
-
const
|
|
157
|
-
const
|
|
208
|
+
const platformArg = parentOptions.platform;
|
|
209
|
+
const dirArg = parentOptions.dir;
|
|
210
|
+
|
|
211
|
+
const resolved = resolveTargetDirs(platformArg, dirArg);
|
|
212
|
+
if (resolved.error) {
|
|
213
|
+
printJSON(resolved);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const results = {};
|
|
218
|
+
for (const target of resolved.targets) {
|
|
219
|
+
const skills = getInstalledSkills(target.targetDir);
|
|
220
|
+
results[target.platform] = {
|
|
221
|
+
targetDir: target.targetDir,
|
|
222
|
+
skills: skills.map(s => ({
|
|
223
|
+
name: s.name,
|
|
224
|
+
description: s.description,
|
|
225
|
+
})),
|
|
226
|
+
count: skills.length,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
158
229
|
|
|
159
230
|
printJSON({
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
description: s.description,
|
|
163
|
-
})),
|
|
164
|
-
total: skills.length,
|
|
165
|
-
targetDir: targetDir,
|
|
231
|
+
platforms: results,
|
|
232
|
+
totalPlatforms: resolved.targets.length,
|
|
166
233
|
});
|
|
167
234
|
} catch (error) {
|
|
168
235
|
printError(error);
|
|
@@ -176,22 +243,26 @@ skillsCmd
|
|
|
176
243
|
.option('-a, --all', 'Install all BytePlan skills', false)
|
|
177
244
|
.addHelpText('after', `
|
|
178
245
|
Examples:
|
|
179
|
-
$ byteplan skills install byteplan-api
|
|
180
|
-
$ byteplan skills install
|
|
181
|
-
$ byteplan skills install
|
|
246
|
+
$ byteplan skills install byteplan-api -p claude-code
|
|
247
|
+
$ byteplan skills install byteplan-api byteplan-analysis -p claude-code,codex
|
|
248
|
+
$ byteplan skills install --all -p claude-code
|
|
249
|
+
$ byteplan skills install byteplan-api -d ~/.claude/commands
|
|
250
|
+
$ byteplan skills install byteplan-api -p claude-code -d /custom/path
|
|
182
251
|
`)
|
|
183
252
|
.action(async (names, options) => {
|
|
184
253
|
try {
|
|
185
|
-
// 获取父命令的 -d 选项(requiredOption 已确保必传)
|
|
186
254
|
const parentOptions = skillsCmd.opts();
|
|
187
|
-
const
|
|
188
|
-
const
|
|
255
|
+
const platformArg = parentOptions.platform;
|
|
256
|
+
const dirArg = parentOptions.dir;
|
|
189
257
|
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
|
|
258
|
+
const resolved = resolveTargetDirs(platformArg, dirArg);
|
|
259
|
+
if (resolved.error) {
|
|
260
|
+
printJSON(resolved);
|
|
261
|
+
process.exit(1);
|
|
193
262
|
}
|
|
194
263
|
|
|
264
|
+
const sourceDir = getSkillsSourceDir();
|
|
265
|
+
|
|
195
266
|
// 获取要安装的 skills
|
|
196
267
|
let toInstall = names || [];
|
|
197
268
|
if (options.all || toInstall.length === 0) {
|
|
@@ -213,22 +284,39 @@ Examples:
|
|
|
213
284
|
process.exit(1);
|
|
214
285
|
}
|
|
215
286
|
|
|
216
|
-
//
|
|
217
|
-
const
|
|
218
|
-
for (const
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
287
|
+
// 安装到各目标目录
|
|
288
|
+
const results = {};
|
|
289
|
+
for (const target of resolved.targets) {
|
|
290
|
+
const targetDir = target.targetDir;
|
|
291
|
+
|
|
292
|
+
// 确保目标目录存在
|
|
293
|
+
if (!existsSync(targetDir)) {
|
|
294
|
+
mkdirSync(targetDir, { recursive: true });
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 安装 skills
|
|
298
|
+
const installed = [];
|
|
299
|
+
for (const skillName of toInstall) {
|
|
300
|
+
const skillSourcePath = path.join(sourceDir, skillName);
|
|
301
|
+
const skillTargetPath = path.join(targetDir, skillName);
|
|
302
|
+
|
|
303
|
+
// 复制 skill 目录
|
|
304
|
+
cpSync(skillSourcePath, skillTargetPath, { recursive: true });
|
|
305
|
+
installed.push(skillName);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
results[target.platform] = {
|
|
309
|
+
targetDir: targetDir,
|
|
310
|
+
installed: installed,
|
|
311
|
+
count: installed.length,
|
|
312
|
+
};
|
|
225
313
|
}
|
|
226
314
|
|
|
227
315
|
printJSON({
|
|
228
316
|
success: true,
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
317
|
+
platforms: results,
|
|
318
|
+
totalPlatforms: resolved.targets.length,
|
|
319
|
+
totalSkills: toInstall.length,
|
|
232
320
|
});
|
|
233
321
|
} catch (error) {
|
|
234
322
|
printError(error);
|
|
@@ -241,35 +329,55 @@ skillsCmd
|
|
|
241
329
|
.description('Install all BytePlan skills to target directory')
|
|
242
330
|
.action(async () => {
|
|
243
331
|
try {
|
|
244
|
-
// 获取父命令的 -d 选项(requiredOption 已确保必传)
|
|
245
332
|
const parentOptions = skillsCmd.opts();
|
|
246
|
-
const
|
|
247
|
-
const
|
|
333
|
+
const platformArg = parentOptions.platform;
|
|
334
|
+
const dirArg = parentOptions.dir;
|
|
248
335
|
|
|
249
|
-
|
|
250
|
-
if (
|
|
251
|
-
|
|
336
|
+
const resolved = resolveTargetDirs(platformArg, dirArg);
|
|
337
|
+
if (resolved.error) {
|
|
338
|
+
printJSON(resolved);
|
|
339
|
+
process.exit(1);
|
|
252
340
|
}
|
|
253
341
|
|
|
342
|
+
const sourceDir = getSkillsSourceDir();
|
|
343
|
+
|
|
254
344
|
// 获取所有 skills
|
|
255
345
|
const availableSkills = getAvailableSkills();
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
|
|
265
|
-
|
|
346
|
+
const toInstall = availableSkills.map(s => s.name);
|
|
347
|
+
|
|
348
|
+
// 安装到各目标目录
|
|
349
|
+
const results = {};
|
|
350
|
+
for (const target of resolved.targets) {
|
|
351
|
+
const targetDir = target.targetDir;
|
|
352
|
+
|
|
353
|
+
// 确保目标目录存在
|
|
354
|
+
if (!existsSync(targetDir)) {
|
|
355
|
+
mkdirSync(targetDir, { recursive: true });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// 安装所有 skills
|
|
359
|
+
const installed = [];
|
|
360
|
+
for (const skillName of toInstall) {
|
|
361
|
+
const skillSourcePath = path.join(sourceDir, skillName);
|
|
362
|
+
const skillTargetPath = path.join(targetDir, skillName);
|
|
363
|
+
|
|
364
|
+
// 复制 skill 目录
|
|
365
|
+
cpSync(skillSourcePath, skillTargetPath, { recursive: true });
|
|
366
|
+
installed.push(skillName);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
results[target.platform] = {
|
|
370
|
+
targetDir: targetDir,
|
|
371
|
+
installed: installed,
|
|
372
|
+
count: installed.length,
|
|
373
|
+
};
|
|
266
374
|
}
|
|
267
375
|
|
|
268
376
|
printJSON({
|
|
269
377
|
success: true,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
378
|
+
platforms: results,
|
|
379
|
+
totalPlatforms: resolved.targets.length,
|
|
380
|
+
totalSkills: toInstall.length,
|
|
273
381
|
});
|
|
274
382
|
} catch (error) {
|
|
275
383
|
printError(error);
|