@qilitt-mickey/vue3-temp-skill 1.0.9 → 1.0.12

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.
Files changed (3) hide show
  1. package/README.md +18 -5
  2. package/bin/cli.js +96 -34
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -75,18 +75,16 @@ AI 接收到请求后会自动完成:
75
75
 
76
76
  ### 安装到指定 AI 工具
77
77
 
78
- 包已发布在 **npmjs.org**,直接安装即可,**无需** GitHub Token / 额外 registry 配置。
79
-
80
78
  ```bash
81
79
  # 通过 npx(推荐,自动使用最新版本)
82
80
  npx @qilitt-mickey/vue3-temp-skill@latest install cursor # Cursor
83
81
  npx @qilitt-mickey/vue3-temp-skill@latest install qoder # Qoder
84
- npx @qilitt-mickey/vue3-temp-skill@latest install copilot # GitHub Copilot
82
+ npx @qilitt-mickey/vue3-temp-skill@latest install copilot # GitHub Copilot(项目级)
85
83
  npx @qilitt-mickey/vue3-temp-skill@latest install windsurf # Windsurf
86
- npx @qilitt-mickey/vue3-temp-skill@latest install gemini # Gemini CLI
84
+ npx @qilitt-mickey/vue3-temp-skill@latest install gemini # Gemini CLI(项目级)
87
85
  npx @qilitt-mickey/vue3-temp-skill@latest install trae # Trae
88
86
  npx @qilitt-mickey/vue3-temp-skill@latest install claude # Claude Code
89
- npx @qilitt-mickey/vue3-temp-skill@latest install universal # 通用标准
87
+ npx @qilitt-mickey/vue3-temp-skill@latest install universal # 通用标准 ~/.agents/skills
90
88
  npx @qilitt-mickey/vue3-temp-skill@latest install all # 安装到所有工具
91
89
 
92
90
  # 通过 pnpm
@@ -97,6 +95,21 @@ npm install -g @qilitt-mickey/vue3-temp-skill
97
95
  vue3-temp-skill install cursor
98
96
  ```
99
97
 
98
+ ### 安装位置说明
99
+
100
+ | 目标 | 全局安装路径 | 项目安装(`--project`) |
101
+ |------|-------------|------------------------|
102
+ | cursor | `~/.cursor/skills/vue3-temp-skill/` | `<项目>/.cursor/skills/vue3-temp-skill/` |
103
+ | claude | `~/.claude/skills/vue3-temp-skill/` | `<项目>/.claude/skills/vue3-temp-skill/` |
104
+ | universal | `~/.agents/skills/vue3-temp-skill/` | `<项目>/.agents/skills/vue3-temp-skill/` |
105
+ | qoder | `~/.qoderworkcn/skills/vue3-temp-skill/` | `<项目>/.qoder/skills/vue3-temp-skill/` |
106
+ | windsurf | `~/.windsurf/rules/vue3-temp-skill.md` | `<项目>/.windsurf/rules/vue3-temp-skill.md` |
107
+ | trae | `~/.trae/rules/vue3-temp-skill.md` | `<项目>/.trae/rules/vue3-temp-skill.md` |
108
+ | copilot | 当前目录 `.github/copilot-instructions.md`(建议加 `--project`) | `<项目>/.github/copilot-instructions.md` |
109
+ | gemini | 当前目录 `GEMINI.md`(建议加 `--project`) | `<项目>/GEMINI.md` |
110
+
111
+ > **注意**:`install all` 默认写入用户主目录下的技能目录。Copilot / Gemini 是项目级配置,未加 `--project` 时会写到**你执行命令时的当前目录**,容易误以为「没装上」。
112
+
100
113
  > 若本机曾经配置过 `@qilitt:registry=https://npm.pkg.github.com`,请删除该配置,否则仍会走旧源并 401:
101
114
  > `npm config delete @qilitt:registry`
102
115
  > 并检查 `~/.npmrc` 中是否还有 `npm.pkg.github.com` 相关行。
package/bin/cli.js CHANGED
@@ -40,8 +40,12 @@ const PKG_VERSION = require(path.join(SKILL_DIR, "package.json")).version;
40
40
  const TARGETS = {
41
41
  cursor: {
42
42
  name: "Cursor",
43
- dir: (p) => (p ? path.join(p, ".cursor/rules") : path.join(HOME, ".cursor/rules")),
44
- type: "rules",
43
+ // Cursor 技能目录:个人 ~/.cursor/skills,项目 .cursor/skills
44
+ dir: (p) => (p ? path.join(p, ".cursor/skills") : path.join(HOME, ".cursor/skills")),
45
+ type: "skills",
46
+ // 旧版曾安装到 .cursor/rules/*.mdc,安装/卸载时一并清理
47
+ legacyRulesFile: (p) =>
48
+ path.join(p ? path.join(p, ".cursor/rules") : path.join(HOME, ".cursor/rules"), `${SKILL_NAME}.mdc`),
45
49
  },
46
50
  qoder: {
47
51
  name: "Qoder",
@@ -50,8 +54,10 @@ const TARGETS = {
50
54
  },
51
55
  copilot: {
52
56
  name: "GitHub Copilot",
53
- file: (p) => path.join(p || ".", ".github/copilot-instructions.md"),
57
+ // 仅项目级:必须指定 --project,否则相对当前工作目录
58
+ file: (p) => path.join(p || process.cwd(), ".github/copilot-instructions.md"),
54
59
  type: "merge",
60
+ projectOnly: true,
55
61
  },
56
62
  windsurf: {
57
63
  name: "Windsurf",
@@ -60,8 +66,10 @@ const TARGETS = {
60
66
  },
61
67
  gemini: {
62
68
  name: "Gemini CLI",
63
- file: (p) => path.join(p || ".", "GEMINI.md"),
69
+ // 仅项目级:必须指定 --project,否则相对当前工作目录
70
+ file: (p) => path.join(p || process.cwd(), "GEMINI.md"),
64
71
  type: "merge",
72
+ projectOnly: true,
65
73
  },
66
74
  trae: {
67
75
  name: "Trae",
@@ -74,12 +82,23 @@ const TARGETS = {
74
82
  type: "skills",
75
83
  },
76
84
  universal: {
77
- name: "Universal",
78
- dir: (p) => path.join(p || ".", ".agents/skills"),
85
+ name: "Universal (.agents)",
86
+ // 全局 ~/.agents/skills;项目 <project>/.agents/skills
87
+ dir: (p) => (p ? path.join(p, ".agents/skills") : path.join(HOME, ".agents/skills")),
79
88
  type: "skills",
80
89
  },
81
90
  };
82
91
 
92
+ /**
93
+ * 解析安装目标的可读路径(用于日志)
94
+ */
95
+ function resolveTargetPath(targetKey, projectDir) {
96
+ const cfg = TARGETS[targetKey];
97
+ if (cfg.type === "merge") return cfg.file(projectDir);
98
+ if (cfg.type === "rules") return path.join(cfg.dir(projectDir), `${SKILL_NAME}.md`);
99
+ return path.join(cfg.dir(projectDir), SKILL_NAME);
100
+ }
101
+
83
102
  // ============================================================
84
103
  // 样式
85
104
  // ============================================================
@@ -197,7 +216,7 @@ function recordUninstall(targetKey, projectDir) {
197
216
  // ============================================================
198
217
 
199
218
  /**
200
- * rules 类型:Cursor / Windsurf / Trae
219
+ * rules 类型:Windsurf / Trae
201
220
  */
202
221
  function installRules(targetKey, projectDir) {
203
222
  const cfg = TARGETS[targetKey];
@@ -205,19 +224,12 @@ function installRules(targetKey, projectDir) {
205
224
  ensureDir(targetDir);
206
225
 
207
226
  const content = readFullSkill();
208
- const ext = targetKey === "cursor" ? ".mdc" : ".md";
209
-
210
- const ruleContent =
211
- targetKey === "cursor"
212
- ? `---\ndescription: ${SKILL_NAME}\nglobs: **/*.vue,**/*.ts,**/*.js,**/*.tsx,**/*.jsx\nalwaysApply: true\n---\n\n${content}\n`
213
- : content;
214
-
215
- const file = path.join(targetDir, `${SKILL_NAME}${ext}`);
216
- fs.writeFileSync(file, ruleContent, "utf-8");
227
+ const file = path.join(targetDir, `${SKILL_NAME}.md`);
228
+ fs.writeFileSync(file, content, "utf-8");
217
229
  }
218
230
 
219
231
  /**
220
- * skills 类型:Qoder / Claude / Universal
232
+ * skills 类型:Cursor / Qoder / Claude / Universal
221
233
  */
222
234
  function installSkills(targetKey, projectDir) {
223
235
  const cfg = TARGETS[targetKey];
@@ -238,6 +250,18 @@ function installSkills(targetKey, projectDir) {
238
250
  if (fs.existsSync(refsSrc)) {
239
251
  copyDir(refsSrc, path.join(dest, "references"));
240
252
  }
253
+
254
+ // Cursor:清理旧版 rules/*.mdc,避免与 skills 重复
255
+ if (cfg.legacyRulesFile) {
256
+ const legacy = cfg.legacyRulesFile(projectDir);
257
+ if (fs.existsSync(legacy)) {
258
+ try {
259
+ fs.unlinkSync(legacy);
260
+ } catch {
261
+ // 忽略清理失败
262
+ }
263
+ }
264
+ }
241
265
  }
242
266
 
243
267
  /**
@@ -259,6 +283,7 @@ function installTarget(targetKey, projectDir) {
259
283
  else if (cfg.type === "merge") installMerge(targetKey, projectDir);
260
284
 
261
285
  recordInstall(targetKey, projectDir);
286
+ return resolveTargetPath(targetKey, projectDir);
262
287
  }
263
288
 
264
289
  // ============================================================
@@ -270,13 +295,23 @@ function uninstallTarget(targetKey, projectDir) {
270
295
 
271
296
  if (cfg.type === "rules") {
272
297
  const targetDir = cfg.dir(projectDir);
273
- const ext = targetKey === "cursor" ? ".mdc" : ".md";
274
- const file = path.join(targetDir, `${SKILL_NAME}${ext}`);
298
+ const file = path.join(targetDir, `${SKILL_NAME}.md`);
275
299
  if (fs.existsSync(file)) fs.unlinkSync(file);
276
300
  } else if (cfg.type === "skills") {
277
301
  const targetDir = cfg.dir(projectDir);
278
302
  const dest = path.join(targetDir, SKILL_NAME);
279
303
  if (fs.existsSync(dest)) removeDir(dest);
304
+ // 同时清理 Cursor 旧版 rules
305
+ if (cfg.legacyRulesFile) {
306
+ const legacy = cfg.legacyRulesFile(projectDir);
307
+ if (fs.existsSync(legacy)) {
308
+ try {
309
+ fs.unlinkSync(legacy);
310
+ } catch {
311
+ // 忽略
312
+ }
313
+ }
314
+ }
280
315
  } else if (cfg.type === "merge") {
281
316
  const targetFile = cfg.file(projectDir);
282
317
  if (fs.existsSync(targetFile)) fs.unlinkSync(targetFile);
@@ -304,27 +339,30 @@ ${bold("命令:")}
304
339
  list 查看已安装的目标和版本
305
340
 
306
341
  ${bold("目标 (target):")}
307
- cursor → Cursor
308
- qoder → Qoder
309
- copilot → GitHub Copilot
310
- windsurf → Windsurf
311
- gemini → Gemini CLI
312
- trae → Trae
313
- claude → Claude Code
314
- universal → 通用标准 (.agents/skills/)
342
+ cursor → Cursor ~/.cursor/skills/
343
+ qoder → Qoder ~/.qoderworkcn/skills/
344
+ copilot → GitHub Copilot <项目>/.github/copilot-instructions.md(项目级)
345
+ windsurf → Windsurf ~/.windsurf/rules/
346
+ gemini → Gemini CLI <项目>/GEMINI.md(项目级)
347
+ trae → Trae ~/.trae/rules/
348
+ claude → Claude Code ~/.claude/skills/
349
+ universal → 通用标准 ~/.agents/skills/
315
350
  all → 安装到所有支持的工具
316
351
 
317
352
  ${bold("选项:")}
318
- --project <dir> 安装到指定项目目录(默认全局安装)
353
+ --project <dir> 安装到指定项目目录(默认全局安装到用户主目录)
319
354
  --help, -h 显示帮助
320
355
  --version, -v 显示版本号
321
356
 
322
357
  ${bold("示例:")}
323
- ${dim("# 安装到 Cursor")}
358
+ ${dim("# 安装到 Cursor(全局技能)")}
324
359
  npx @qilitt-mickey/vue3-temp-skill install cursor
325
360
 
326
- ${dim("# 安装到 Qoder(指定项目)")}
327
- npx @qilitt-mickey/vue3-temp-skill install qoder --project ./my-app
361
+ ${dim("# 安装到所有工具(全局)+ 当前目录的 Copilot/Gemini 项目文件")}
362
+ npx @qilitt-mickey/vue3-temp-skill install all
363
+
364
+ ${dim("# 安装到指定项目(含 .agents / Copilot / Gemini)")}
365
+ npx @qilitt-mickey/vue3-temp-skill install all --project ./my-app
328
366
 
329
367
  ${dim("# 更新所有已安装的目标(搭配 @latest 拉取最新版)")}
330
368
  npx @qilitt-mickey/vue3-temp-skill@latest update
@@ -341,6 +379,18 @@ function showVersion() {
341
379
  console.log(PKG_VERSION);
342
380
  }
343
381
 
382
+ function warnProjectOnly(targetKey, projectDir) {
383
+ const cfg = TARGETS[targetKey];
384
+ if (cfg.projectOnly && !projectDir) {
385
+ console.log(
386
+ yellow(
387
+ ` ! ${cfg.name} 为项目级配置,已写入当前目录: ${resolveTargetPath(targetKey, null)}`
388
+ )
389
+ );
390
+ console.log(dim(` 建议: vue3-temp-skill install ${targetKey} --project <项目路径>`));
391
+ }
392
+ }
393
+
344
394
  function cmdInstall(target, projectDir) {
345
395
  if (!target) {
346
396
  console.error(red("✗ 请指定安装目标,例如: vue3-temp-skill install cursor"));
@@ -352,14 +402,20 @@ function cmdInstall(target, projectDir) {
352
402
  const total = Object.keys(TARGETS).length;
353
403
  let success = 0;
354
404
  const failed = [];
405
+ console.log(bold(`\n安装 vue3-temp-skill v${PKG_VERSION} → 全部工具\n`));
355
406
  for (const key of Object.keys(TARGETS)) {
356
407
  try {
357
- installTarget(key, projectDir);
408
+ const dest = installTarget(key, projectDir);
358
409
  success++;
410
+ console.log(green(` ✓ ${TARGETS[key].name}`));
411
+ console.log(dim(` → ${dest}`));
412
+ warnProjectOnly(key, projectDir);
359
413
  } catch (err) {
360
414
  failed.push(TARGETS[key].name);
415
+ console.log(red(` ✗ ${TARGETS[key].name}: ${err.message}`));
361
416
  }
362
417
  }
418
+ console.log("");
363
419
  if (failed.length === 0) {
364
420
  console.log(green(`✓ 已安装到全部 ${total} 个工具 (v${PKG_VERSION})`));
365
421
  } else {
@@ -368,8 +424,10 @@ function cmdInstall(target, projectDir) {
368
424
  }
369
425
  } else if (TARGETS[target]) {
370
426
  try {
371
- installTarget(target, projectDir);
427
+ const dest = installTarget(target, projectDir);
372
428
  console.log(green(`✓ 已安装到 ${TARGETS[target].name} (v${PKG_VERSION})`));
429
+ console.log(dim(` → ${dest}`));
430
+ warnProjectOnly(target, projectDir);
373
431
  } catch (err) {
374
432
  console.error(red(`✗ 安装失败: ${err.message}`));
375
433
  process.exit(1);
@@ -521,7 +579,11 @@ function cmdList() {
521
579
  const cfg = TARGETS[targetKey];
522
580
  const name = cfg ? cfg.name : targetKey;
523
581
  const scope = projDir ? ` (项目: ${projDir})` : " (全局)";
524
- console.log(` ${green("")} ${name}${scope}`);
582
+ const dest = cfg ? resolveTargetPath(targetKey, projDir) : "";
583
+ const exists = dest && fs.existsSync(dest);
584
+ const mark = exists ? green("•") : yellow("!");
585
+ console.log(` ${mark} ${name}${scope}`);
586
+ if (dest) console.log(dim(` ${dest}${exists ? "" : " (文件不存在)"}`));
525
587
  }
526
588
 
527
589
  if (track.updatedAt) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qilitt-mickey/vue3-temp-skill",
3
- "version": "1.0.9",
3
+ "version": "1.0.12",
4
4
  "description": "Vue 3 企业级中后台项目开发规范技能包 — 让 AI 编程助手按照团队规范生成代码,并自动审查代码质量",
5
5
  "bin": {
6
6
  "vue3-temp-skill": "./bin/cli.js"