sillyspec 3.7.6 → 3.7.7
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/package.json +1 -1
- package/src/setup.js +40 -15
package/package.json
CHANGED
package/src/setup.js
CHANGED
|
@@ -17,7 +17,7 @@ const SKILLS = [
|
|
|
17
17
|
name: 'Playwright E2E 测试参考',
|
|
18
18
|
description: 'E2E 测试编写最佳实践,AI 执行测试任务时自动读取',
|
|
19
19
|
source: join(__dirname, '..', 'templates', 'skills', 'playwright-e2e'),
|
|
20
|
-
target: '
|
|
20
|
+
target: 'playwright-e2e',
|
|
21
21
|
},
|
|
22
22
|
];
|
|
23
23
|
|
|
@@ -283,11 +283,20 @@ export async function cmdSetup(dir, options = {}) {
|
|
|
283
283
|
...globalChoices.length > 0 ? [{ name: chalk.bold('── 全局工具 ──'), value: '_global_header', disabled: true }] : [],
|
|
284
284
|
...globalChoices,
|
|
285
285
|
...[{ name: chalk.bold('── AI Skills(编写参考)──'), value: '_skill_header', disabled: true }],
|
|
286
|
-
...
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
286
|
+
...(() => {
|
|
287
|
+
const installed = new Set();
|
|
288
|
+
for (const { path } of availableTools) {
|
|
289
|
+
const skillDir = join(dir, dirname(path), 'skills');
|
|
290
|
+
for (const s of SKILLS) {
|
|
291
|
+
if (existsSync(join(skillDir, s.target, 'SKILL.md'))) installed.add(s.id);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return SKILLS.filter(s => !installed.has(s.id)).map(s => ({
|
|
295
|
+
name: `${s.name} — ${s.description}`,
|
|
296
|
+
value: `skill:${s.id}`,
|
|
297
|
+
checked: false,
|
|
298
|
+
}));
|
|
299
|
+
})(),
|
|
291
300
|
];
|
|
292
301
|
|
|
293
302
|
if (allChoices.length === 0) {
|
|
@@ -382,16 +391,32 @@ export async function cmdSetup(dir, options = {}) {
|
|
|
382
391
|
const selectedSkills = SKILLS.filter(s => selected.includes(`skill:${s.id}`));
|
|
383
392
|
|
|
384
393
|
if (selectedSkills.length > 0) {
|
|
394
|
+
// 跟 MCP 一样,选择安装到哪些 AI 工具
|
|
395
|
+
const skillTargets = availableTools.map(t => ({
|
|
396
|
+
name: t.tool,
|
|
397
|
+
value: t.key,
|
|
398
|
+
checked: true,
|
|
399
|
+
}));
|
|
400
|
+
|
|
401
|
+
const selectedTools = await checkbox({
|
|
402
|
+
message: 'Skill 安装到哪些 AI 工具?',
|
|
403
|
+
choices: skillTargets,
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
const targets = availableTools.filter(t => selectedTools.includes(t.key));
|
|
407
|
+
|
|
385
408
|
console.log('');
|
|
386
|
-
for (const
|
|
387
|
-
const spinner = ora(`安装 ${
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
409
|
+
for (const { tool, path } of targets) {
|
|
410
|
+
const spinner = ora(`安装 Skills 到 ${tool}...`).start();
|
|
411
|
+
for (const skill of selectedSkills) {
|
|
412
|
+
try {
|
|
413
|
+
const targetDir = join(dir, dirname(path), 'skills', skill.target);
|
|
414
|
+
mkdirSync(targetDir, { recursive: true });
|
|
415
|
+
cpSync(skill.source, targetDir, { recursive: true });
|
|
416
|
+
spinner.succeed(`${tool} → ${dirname(path)}/skills/${skill.target}/SKILL.md`);
|
|
417
|
+
} catch (err) {
|
|
418
|
+
spinner.fail(`${skill.name} 安装失败: ${err.message}`);
|
|
419
|
+
}
|
|
395
420
|
}
|
|
396
421
|
}
|
|
397
422
|
}
|