sillyspec 3.7.6 → 3.7.8
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 +56 -15
- package/templates/execute.md +18 -0
- package/templates/skills/playwright-e2e/SKILL.md +1 -1
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
|
|
|
@@ -40,6 +40,22 @@ const MCP_TOOLS = [
|
|
|
40
40
|
args: ['chrome-devtools-mcp@latest'],
|
|
41
41
|
url: 'https://github.com/ChromeDevTools/chrome-devtools-mcp',
|
|
42
42
|
},
|
|
43
|
+
{
|
|
44
|
+
id: 'agent-browser',
|
|
45
|
+
name: 'Agent Browser (Vercel)',
|
|
46
|
+
description: 'Rust 原生浏览器 CLI,token 消耗极低,50+ 命令覆盖导航/表单/截图/网络',
|
|
47
|
+
command: 'npx',
|
|
48
|
+
args: ['@anthropic-ai/agent-browser@latest'],
|
|
49
|
+
url: 'https://github.com/vercel-labs/agent-browser',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'pinchtab',
|
|
53
|
+
name: 'PinchTab',
|
|
54
|
+
description: '12MB Go 二进制,零依赖,accessibility tree 极省 token,有 MCP 支持',
|
|
55
|
+
command: 'npx',
|
|
56
|
+
args: ['pinchtab-mcp@latest'],
|
|
57
|
+
url: 'https://github.com/pinchtab/pinchtab',
|
|
58
|
+
},
|
|
43
59
|
];
|
|
44
60
|
|
|
45
61
|
// ── 数据库 MCP 定义(需要连接信息)──
|
|
@@ -283,11 +299,20 @@ export async function cmdSetup(dir, options = {}) {
|
|
|
283
299
|
...globalChoices.length > 0 ? [{ name: chalk.bold('── 全局工具 ──'), value: '_global_header', disabled: true }] : [],
|
|
284
300
|
...globalChoices,
|
|
285
301
|
...[{ name: chalk.bold('── AI Skills(编写参考)──'), value: '_skill_header', disabled: true }],
|
|
286
|
-
...
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
302
|
+
...(() => {
|
|
303
|
+
const installed = new Set();
|
|
304
|
+
for (const { path } of availableTools) {
|
|
305
|
+
const skillDir = join(dir, dirname(path), 'skills');
|
|
306
|
+
for (const s of SKILLS) {
|
|
307
|
+
if (existsSync(join(skillDir, s.target, 'SKILL.md'))) installed.add(s.id);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return SKILLS.filter(s => !installed.has(s.id)).map(s => ({
|
|
311
|
+
name: `${s.name} — ${s.description}`,
|
|
312
|
+
value: `skill:${s.id}`,
|
|
313
|
+
checked: false,
|
|
314
|
+
}));
|
|
315
|
+
})(),
|
|
291
316
|
];
|
|
292
317
|
|
|
293
318
|
if (allChoices.length === 0) {
|
|
@@ -382,16 +407,32 @@ export async function cmdSetup(dir, options = {}) {
|
|
|
382
407
|
const selectedSkills = SKILLS.filter(s => selected.includes(`skill:${s.id}`));
|
|
383
408
|
|
|
384
409
|
if (selectedSkills.length > 0) {
|
|
410
|
+
// 跟 MCP 一样,选择安装到哪些 AI 工具
|
|
411
|
+
const skillTargets = availableTools.map(t => ({
|
|
412
|
+
name: t.tool,
|
|
413
|
+
value: t.key,
|
|
414
|
+
checked: true,
|
|
415
|
+
}));
|
|
416
|
+
|
|
417
|
+
const selectedTools = await checkbox({
|
|
418
|
+
message: 'Skill 安装到哪些 AI 工具?',
|
|
419
|
+
choices: skillTargets,
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
const targets = availableTools.filter(t => selectedTools.includes(t.key));
|
|
423
|
+
|
|
385
424
|
console.log('');
|
|
386
|
-
for (const
|
|
387
|
-
const spinner = ora(`安装 ${
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
425
|
+
for (const { tool, path } of targets) {
|
|
426
|
+
const spinner = ora(`安装 Skills 到 ${tool}...`).start();
|
|
427
|
+
for (const skill of selectedSkills) {
|
|
428
|
+
try {
|
|
429
|
+
const targetDir = join(dir, dirname(path), 'skills', skill.target);
|
|
430
|
+
mkdirSync(targetDir, { recursive: true });
|
|
431
|
+
cpSync(skill.source, targetDir, { recursive: true });
|
|
432
|
+
spinner.succeed(`${tool} → ${dirname(path)}/skills/${skill.target}/SKILL.md`);
|
|
433
|
+
} catch (err) {
|
|
434
|
+
spinner.fail(`${skill.name} 安装失败: ${err.message}`);
|
|
435
|
+
}
|
|
395
436
|
}
|
|
396
437
|
}
|
|
397
438
|
}
|
package/templates/execute.md
CHANGED
|
@@ -139,6 +139,21 @@ find tests/e2e e2e cypress/e2e __tests__ src -name "*.spec.ts" -o -name "*.test.
|
|
|
139
139
|
> **11. 参照已有测试风格:** 编写新测试时必须参照以上「测试模式参考」中的风格,包括断言方式、fixtures 使用、文件组织。不要凭记忆写测试。
|
|
140
140
|
> **12. 参考已有实现:** 写新功能前,先 grep 项目中类似功能的已有代码(`grep -r "关键词" src/`),照着项目现有的模式、风格和封装方式写,不要凭记忆编造。
|
|
141
141
|
|
|
142
|
+
**Skill 扫描(主代理执行):**
|
|
143
|
+
对每个子代理 dispatch 前,扫描项目中已安装的 skill,匹配相关 skill 注入子代理 prompt 的「本地 Skills」段。
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
for skill_dir in .claude/skills/*/SKILL.md .cursor/skills/*/SKILL.md .opencode/skills/*/SKILL.md; do
|
|
147
|
+
[ -f "$skill_dir" ] && echo "=== $skill_dir ===" && cat "$skill_dir"
|
|
148
|
+
done
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
扫描后,根据当前任务描述的关键词匹配 skill 的 name 和 description:
|
|
152
|
+
- 任务包含"E2E"/"端到端"/"测试用例" → 匹配 playwright-e2e skill
|
|
153
|
+
- 未来可扩展更多 skill
|
|
154
|
+
|
|
155
|
+
匹配到的 skill → 将 SKILL.md 全文注入子代理 prompt。未匹配则省略该段。
|
|
156
|
+
|
|
142
157
|
**MCP 能力检测(主代理执行):**
|
|
143
158
|
检查当前可用工具列表中是否存在以下类型的 MCP 工具(不要只依赖配置文件路径,不同客户端配置位置不同):
|
|
144
159
|
- Context7 / 文档查询工具
|
|
@@ -209,6 +224,9 @@ find tests/e2e e2e cypress/e2e __tests__ src -name "*.spec.ts" -o -name "*.test.
|
|
|
209
224
|
## 文档查询指引
|
|
210
225
|
{主代理根据 MCP 检测结果动态注入:有 Context7 提示用 MCP,无则提示用 web search}
|
|
211
226
|
|
|
227
|
+
## 本地 Skills(如有)
|
|
228
|
+
{主代理在 dispatch 前扫描 .claude/skills/、.cursor/skills/、.opencode/skills/ 下的 SKILL.md,根据当前任务关键词匹配相关 skill,将 SKILL.md 全文注入此段。无匹配 skill 则省略此段。}
|
|
229
|
+
|
|
212
230
|
## 数据操作
|
|
213
231
|
{主代理根据 MCP 检测结果动态注入:如检测到数据库 MCP,提示可用}
|
|
214
232
|
⛔ 任何改变现有数据的操作(DML: INSERT/UPDATE/DELETE/DML、DDL: ALTER/DROP/TRUNCATE/RENAME,以及所有非 SELECT 的数据库操作)必须暂停并报告给用户确认,不得自动执行。新建表不受此限制。
|