mdk-skills 2.1.5 → 2.1.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.
@@ -1,49 +1,3 @@
1
- // {
2
- // "version": 1,
3
- // "profiles": [
4
- // {
5
- // "id": "vue3-frontend",
6
- // "name": "前端 Vue3 开发",
7
- // "description": "Vue 3 + 业务模式库 + 设计 + 代码审查",
8
- // "skills": ["vue", "v3-fe-biz-patterns", "frontend-design", "frontend-code-review", "ui-ux-pro-max"],
9
- // "always_apply": ["vue", "frontend-design", "frontend-code-review", "ui-ux-pro-max"]
10
- // },
11
- // {
12
- // "id": "react-frontend",
13
- // "name": "前端 React 开发",
14
- // "description": "设计 + 审查 + 通用前端能力",
15
- // "skills": ["frontend-design", "frontend-code-review", "ui-ux-pro-max"],
16
- // "always_apply": ["frontend-design", "frontend-code-review", "ui-ux-pro-max"]
17
- // },
18
- // {
19
- // "id": "backend",
20
- // "name": "java后端开发",
21
- // "description": "API 设计、数据库、java 后端技能",
22
- // "skills": [],
23
- // "always_apply": []
24
- // },
25
- // {
26
- // "id": "backend",
27
- // "name": "python后端开发",
28
- // "description": "API 设计、数据库、python 后端技能",
29
- // "skills": [],
30
- // "always_apply": []
31
- // },
32
- // {
33
- // "id": "backend",
34
- // "name": "nodeJs后端开发",
35
- // "description": "API 设计、数据库、nodeJs 后端技能",
36
- // "skills": [],
37
- // "always_apply": []
38
- // },
39
- // {
40
- // "id": "custom",
41
- // "name": "自定义选择",
42
- // "description": "按需勾选每一个技能",
43
- // "skills": null
44
- // }
45
- // ]
46
- // }
47
1
  {
48
2
  "version": 1,
49
3
  "profiles": [
@@ -56,7 +10,8 @@
56
10
  "v3-fe-biz-patterns",
57
11
  "frontend-design",
58
12
  "frontend-code-review",
59
- "ui-ux-pro-max"
13
+ "ui-ux-pro-max",
14
+ "skill-creator"
60
15
  ],
61
16
  "always_apply": [
62
17
  "vue",
@@ -69,7 +24,12 @@
69
24
  "id": "react-frontend",
70
25
  "name": "React 前端专项",
71
26
  "description": "React 技术栈 | 界面设计 | 代码评审 | 通用前端能力",
72
- "skills": ["frontend-design", "frontend-code-review", "ui-ux-pro-max"],
27
+ "skills": [
28
+ "frontend-design",
29
+ "frontend-code-review",
30
+ "ui-ux-pro-max",
31
+ "skill-creator"
32
+ ],
73
33
  "always_apply": [
74
34
  "frontend-design",
75
35
  "frontend-code-review",
@@ -80,21 +40,21 @@
80
40
  "id": "backend-java",
81
41
  "name": "Java 后端开发",
82
42
  "description": "接口架构设计 | 数据库建模 | Java 后端体系能力",
83
- "skills": [],
43
+ "skills": ["skill-creator"],
84
44
  "always_apply": []
85
45
  },
86
46
  {
87
47
  "id": "backend-python",
88
48
  "name": "Python 后端开发",
89
49
  "description": "接口架构设计 | 数据层设计 | Python 后端体系能力",
90
- "skills": [],
50
+ "skills": ["skill-creator"],
91
51
  "always_apply": []
92
52
  },
93
53
  {
94
54
  "id": "backend-node",
95
55
  "name": "Node.js 后端开发",
96
56
  "description": "接口架构设计 | 服务端架构 | Node 后端体系能力",
97
- "skills": [],
57
+ "skills": ["skill-creator"],
98
58
  "always_apply": []
99
59
  },
100
60
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdk-skills",
3
- "version": "2.1.5",
3
+ "version": "2.1.8",
4
4
  "description": "mdk-engineer - 沉稳靠谱的前端开发助手 Claude Skills 配置包,一键注入 .claude/ 技能目录和 CLAUDE.md 人设配置",
5
5
  "author": "XiaoMa",
6
6
  "license": "MIT",
package/scripts/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
- const { getPackageSkills, getUserSkills } = require("./core");
5
+ const { getPackageSkills, getUserSkills, getSkillsSource } = require("./core");
6
6
 
7
7
  // npx 运行时:process.cwd() 是用户项目目录
8
8
  // __dirname 是包内 scripts/ 目录
@@ -15,10 +15,11 @@ const projectRoot = (() => {
15
15
  }
16
16
  })();
17
17
  const packageDir = path.join(__dirname, "..");
18
+ const skillsSource = getSkillsSource(projectRoot, packageDir);
18
19
  const claudeDest = path.join(projectRoot, ".claude");
19
20
  const skillsDest = path.join(claudeDest, "skills");
20
21
  const settingsPath = path.join(claudeDest, "settings.json");
21
- const pkgSkillsSource = path.join(packageDir, ".claude", "skills");
22
+ const pkgSkillsSource = path.join(skillsSource, ".claude", "skills");
22
23
 
23
24
  // ---------- 文件写入 ----------
24
25
 
@@ -105,7 +106,7 @@ function installSelectedSkills(selectedNames) {
105
106
  writeSettings(settings);
106
107
 
107
108
  // 安装 CLAUDE.md(没有才装)
108
- const mdSource = path.join(packageDir, "CLAUDE.md");
109
+ const mdSource = path.join(skillsSource, "CLAUDE.md");
109
110
  const mdDest = path.join(projectRoot, "CLAUDE.md");
110
111
  if (fs.existsSync(mdSource) && !fs.existsSync(mdDest)) {
111
112
  fs.copyFileSync(mdSource, mdDest);
@@ -118,7 +119,7 @@ function installSelectedSkills(selectedNames) {
118
119
  // ---------- 场景选择(场景 → 一键装技能) ----------
119
120
 
120
121
  function loadProfiles() {
121
- const profilesPath = path.join(packageDir, ".claude", "profiles.json");
122
+ const profilesPath = path.join(skillsSource, ".claude", "profiles.json");
122
123
  if (!fs.existsSync(profilesPath)) return null;
123
124
  try {
124
125
  return JSON.parse(fs.readFileSync(profilesPath, "utf-8")).profiles;
@@ -183,7 +184,7 @@ function applyProfile(profile) {
183
184
  writeSettings(settings);
184
185
 
185
186
  // 安装 CLAUDE.md(没有才装)
186
- const mdSource = path.join(packageDir, "CLAUDE.md");
187
+ const mdSource = path.join(skillsSource, "CLAUDE.md");
187
188
  const mdDest = path.join(projectRoot, "CLAUDE.md");
188
189
  if (fs.existsSync(mdSource) && !fs.existsSync(mdDest)) {
189
190
  fs.copyFileSync(mdSource, mdDest);
@@ -277,7 +278,7 @@ async function cmdList() {
277
278
  }
278
279
 
279
280
  const chalk = (await import("chalk")).default;
280
- const pkgSkills = getPackageSkills(packageDir);
281
+ const pkgSkills = getPackageSkills(skillsSource);
281
282
  const userSkills = getUserSkills(claudeDest);
282
283
 
283
284
  const skillMap = new Map();
@@ -323,10 +324,10 @@ async function startInteractiveMenu() {
323
324
  return;
324
325
  }
325
326
 
326
- const pkgSkills = getPackageSkills(packageDir);
327
+ const pkgSkills = getPackageSkills(skillsSource);
327
328
 
328
329
  if (pkgSkills.length === 0) {
329
- console.log(" ⚠️ 包内没有可用技能\n");
330
+ console.log(" ⚠️ 没有可用技能\n");
330
331
  return;
331
332
  }
332
333
 
@@ -373,9 +374,94 @@ async function startInteractiveMenu() {
373
374
  console.log(`\n ✅ 技能安装完成 ${summary}\n`);
374
375
  }
375
376
 
377
+ // ---------- 本地源连接管理 ----------
378
+
379
+ function cmdConnect(repoPath) {
380
+ if (!repoPath) {
381
+ console.log(" ⚠️ 用法:npx mdk-skills connect <仓库路径>\n");
382
+ return;
383
+ }
384
+
385
+ repoPath = path.resolve(repoPath);
386
+
387
+ if (!fs.existsSync(path.join(repoPath, ".claude", "skills"))) {
388
+ console.log(` ❌ 路径 "${repoPath}" 下没有找到 .claude/skills/\n`);
389
+ return;
390
+ }
391
+
392
+ const settings = readSettings();
393
+ settings._skill_source = repoPath;
394
+ writeSettings(settings);
395
+
396
+ console.log(` ✅ 已绑定技能源: ${repoPath}\n`);
397
+ console.log(` 💡 运行 npx mdk-skills sync 同步技能\n`);
398
+ }
399
+
400
+ async function cmdSync() {
401
+ const settings = readSettings();
402
+ const sourcePath = settings._skill_source;
403
+
404
+ if (!sourcePath) {
405
+ console.log(" ⚠️ 尚未绑定技能源,请先运行 npx mdk-skills connect <路径>\n");
406
+ return;
407
+ }
408
+
409
+ if (!fs.existsSync(path.join(sourcePath, ".claude", "skills"))) {
410
+ console.log(` ❌ 绑定的路径 "${sourcePath}" 已失效或已移动\n`);
411
+ return;
412
+ }
413
+
414
+ const { backupDir, installSkills, installSettings } = require("./core");
415
+ const logFile = path.join(claudeDest, ".install.log");
416
+
417
+ if (fs.existsSync(claudeDest)) {
418
+ backupDir(claudeDest);
419
+ }
420
+
421
+ const results = installSkills(
422
+ path.join(sourcePath, ".claude", "skills"),
423
+ skillsDest,
424
+ logFile,
425
+ );
426
+
427
+ installSettings(path.join(sourcePath, ".claude"), claudeDest, logFile);
428
+
429
+ // 复制 CLAUDE.md
430
+ const mdSource = path.join(sourcePath, "CLAUDE.md");
431
+ const mdDest = path.join(projectRoot, "CLAUDE.md");
432
+ if (fs.existsSync(mdSource)) {
433
+ fs.copyFileSync(mdSource, mdDest);
434
+ }
435
+
436
+ const installed = results.filter((r) => r.action === "installed").length;
437
+ const updated = results.filter((r) => r.action === "updated").length;
438
+ const skipped = results.filter((r) => r.action === "skipped").length;
439
+
440
+ console.log(`\n ✅ 技能同步完成`);
441
+ if (installed > 0) console.log(` 新装 ${installed} 个`);
442
+ if (updated > 0) console.log(` 更新 ${updated} 个`);
443
+ if (skipped > 0) console.log(` 跳过 ${skipped} 个(无变化)`);
444
+ console.log("");
445
+ }
446
+
447
+ function cmdDisconnect() {
448
+ const settings = readSettings();
449
+ if (!settings._skill_source) {
450
+ console.log(" ⚠️ 当前未绑定任何技能源\n");
451
+ return;
452
+ }
453
+
454
+ const oldPath = settings._skill_source;
455
+ delete settings._skill_source;
456
+ writeSettings(settings);
457
+
458
+ console.log(` ✅ 已断开技能源: ${oldPath}\n`);
459
+ console.log(` 💡 恢复为使用 npm 包内置技能\n`);
460
+ }
461
+
376
462
  // ---------- 主入口 ----------
377
463
 
378
- const COMMANDS = ["list", "enable", "disable"];
464
+ const COMMANDS = ["list", "connect", "sync", "disconnect"];
379
465
 
380
466
  async function main() {
381
467
  const command = process.argv[2];
@@ -396,21 +482,29 @@ async function main() {
396
482
  用法:
397
483
  npx mdk-skills 场景选择 → 一键安装对应技能
398
484
  npx mdk-skills list 查看已安装的技能
485
+ npx mdk-skills connect 绑定本地技能源仓库路径
486
+ npx mdk-skills sync 从绑定的源同步技能
487
+ npx mdk-skills disconnect 解绑本地源,恢复使用 npm 包内置技能
399
488
  npx mdk-skills --help 显示帮助
400
489
 
401
490
  首次运行选择场景后自动配置技能和 CLAUDE.md
402
491
  再次运行可切换场景或进入自定义模式微调
403
492
 
404
493
  示例:
494
+ npx mdk-skills connect D:/dev/mdk-skills
495
+ npx mdk-skills sync
496
+ npx mdk-skills disconnect
405
497
  npx mdk-skills
406
498
  npx mdk-skills list
407
499
  `);
408
500
  } else if (command === "list") {
409
501
  await cmdList();
410
- } else if (command === "enable" || command === "disable") {
411
- console.log(
412
- ` ⚠️ 该命令已废弃,请直接运行 npx mdk-skills 使用交互菜单\n`,
413
- );
502
+ } else if (command === "connect") {
503
+ cmdConnect(args[0]);
504
+ } else if (command === "sync") {
505
+ await cmdSync();
506
+ } else if (command === "disconnect") {
507
+ cmdDisconnect();
414
508
  } else {
415
509
  console.log(` 未知命令: ${command}\n 可用: ${COMMANDS.join(", ")}\n`);
416
510
  process.exit(1);
package/scripts/core.js CHANGED
@@ -212,6 +212,22 @@ function getPackageSkills(packageDir) {
212
212
  /**
213
213
  * 获取用户已安装的技能及其 settings 中的 enabled 状态
214
214
  */
215
+ /**
216
+ * 解析技能源路径:
217
+ * 优先从 settings.json 的 _skill_source 字段读取(本地开发模式)
218
+ * 没有则回退到包目录(普通用户模式)
219
+ */
220
+ function getSkillsSource(projectRoot, fallbackDir) {
221
+ const settingsPath = path.join(projectRoot, ".claude", "settings.json");
222
+ if (fs.existsSync(settingsPath)) {
223
+ try {
224
+ const s = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
225
+ if (s._skill_source) return s._skill_source;
226
+ } catch {}
227
+ }
228
+ return fallbackDir;
229
+ }
230
+
215
231
  function getUserSkills(claudeDest) {
216
232
  const skillsDest = path.join(claudeDest, "skills");
217
233
  if (!fs.existsSync(skillsDest)) return [];
@@ -253,4 +269,5 @@ module.exports = {
253
269
  installSettings,
254
270
  getPackageSkills,
255
271
  getUserSkills,
272
+ getSkillsSource,
256
273
  };