mdk-skills 2.4.20 → 2.4.21
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/scripts/cli.js +104 -116
- package/scripts/core.js +131 -136
- package/scripts/web-ui/server/context.js +14 -14
- package/scripts/web-ui/server/routes/others.js +4 -4
- package/scripts/web-ui/server/routes/skills.js +17 -7
- package/scripts/web-ui/server/routes/source.js +6 -6
- package/scripts/web-ui/server/utils.js +12 -186
- package/scripts/web-ui/server.js +13 -7
package/package.json
CHANGED
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, getSkillsSource, backupDir, listSkillDirs,
|
|
5
|
+
const { getPackageSkills, getUserSkills, getSkillsSource, backupDir, listSkillDirs, copyDir } = require("./core");
|
|
6
6
|
|
|
7
7
|
// npx 运行时:process.cwd() 是用户项目目录
|
|
8
8
|
// __dirname 是包内 scripts/ 目录
|
|
@@ -14,31 +14,44 @@ const projectRoot = (() => {
|
|
|
14
14
|
return process.cwd();
|
|
15
15
|
}
|
|
16
16
|
})();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
|
|
18
|
+
let skillsSource;
|
|
19
|
+
let claudeDest;
|
|
20
|
+
let skillsDest;
|
|
21
|
+
let settingsPath;
|
|
22
|
+
let pkgSkillsSource;
|
|
23
|
+
|
|
24
|
+
async function pathExists(p) {
|
|
25
|
+
try { await fs.promises.access(p); return true; } catch { return false; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function initPaths() {
|
|
29
|
+
skillsSource = await getSkillsSource(projectRoot);
|
|
30
|
+
claudeDest = path.join(projectRoot, ".claude");
|
|
31
|
+
skillsDest = path.join(claudeDest, "skills");
|
|
32
|
+
settingsPath = path.join(claudeDest, "settings.json");
|
|
33
|
+
pkgSkillsSource = skillsSource
|
|
34
|
+
? path.join(skillsSource, ".claude", "skills")
|
|
35
|
+
: null;
|
|
36
|
+
}
|
|
24
37
|
|
|
25
38
|
// ---------- 文件写入 ----------
|
|
26
39
|
|
|
27
|
-
function readSettings() {
|
|
28
|
-
if (!
|
|
40
|
+
async function readSettings() {
|
|
41
|
+
if (!(await pathExists(settingsPath)))
|
|
29
42
|
return { skills: {}, always_apply_skills: [] };
|
|
30
43
|
try {
|
|
31
|
-
return JSON.parse(fs.
|
|
44
|
+
return JSON.parse(await fs.promises.readFile(settingsPath, "utf-8"));
|
|
32
45
|
} catch {
|
|
33
46
|
return { skills: {}, always_apply_skills: [] };
|
|
34
47
|
}
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
function writeSettings(settings) {
|
|
38
|
-
if (!
|
|
39
|
-
fs.
|
|
50
|
+
async function writeSettings(settings) {
|
|
51
|
+
if (!(await pathExists(claudeDest))) {
|
|
52
|
+
await fs.promises.mkdir(claudeDest, { recursive: true });
|
|
40
53
|
}
|
|
41
|
-
fs.
|
|
54
|
+
await fs.promises.writeFile(
|
|
42
55
|
settingsPath,
|
|
43
56
|
JSON.stringify(settings, null, 2) + "\n",
|
|
44
57
|
"utf-8",
|
|
@@ -47,38 +60,35 @@ function writeSettings(settings) {
|
|
|
47
60
|
|
|
48
61
|
// ---------- 安装勾选的技能 ----------
|
|
49
62
|
|
|
50
|
-
function installSelectedSkills(selectedNames) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
fs.mkdirSync(skillsDest, { recursive: true });
|
|
63
|
+
async function installSelectedSkills(selectedNames) {
|
|
64
|
+
if (!(await pathExists(skillsDest))) {
|
|
65
|
+
await fs.promises.mkdir(skillsDest, { recursive: true });
|
|
54
66
|
}
|
|
55
67
|
|
|
56
|
-
const allPkgSkills = listSkillDirs(pkgSkillsSource);
|
|
68
|
+
const allPkgSkills = await listSkillDirs(pkgSkillsSource);
|
|
69
|
+
let installedCount = 0;
|
|
57
70
|
|
|
58
71
|
for (const name of allPkgSkills) {
|
|
59
72
|
const src = path.join(pkgSkillsSource, name);
|
|
60
73
|
const dest = path.join(skillsDest, name);
|
|
61
74
|
|
|
62
75
|
if (selectedNames.includes(name)) {
|
|
63
|
-
|
|
64
|
-
if (!fs.existsSync(dest)) {
|
|
76
|
+
if (!(await pathExists(dest))) {
|
|
65
77
|
try {
|
|
66
|
-
|
|
78
|
+
await copyDir(src, dest);
|
|
67
79
|
installedCount++;
|
|
68
80
|
} catch (err) {
|
|
69
81
|
console.error(` ❌ 安装技能 "${name}" 失败:`, err.message);
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
84
|
} else {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
fs.rmSync(dest, { recursive: true, force: true });
|
|
85
|
+
if (await pathExists(dest)) {
|
|
86
|
+
await fs.promises.rm(dest, { recursive: true, force: true });
|
|
76
87
|
}
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
90
|
|
|
80
|
-
|
|
81
|
-
const settings = readSettings();
|
|
91
|
+
const settings = await readSettings();
|
|
82
92
|
if (!settings.skills) settings.skills = {};
|
|
83
93
|
|
|
84
94
|
for (const name of allPkgSkills) {
|
|
@@ -89,21 +99,19 @@ function installSelectedSkills(selectedNames) {
|
|
|
89
99
|
settings.skills[name].enabled = enabled;
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
writeSettings(settings);
|
|
102
|
+
await writeSettings(settings);
|
|
93
103
|
|
|
94
|
-
// 安装 CLAUDE.md(没有才装)
|
|
95
104
|
const mdSource = path.join(skillsSource, "CLAUDE.md");
|
|
96
105
|
const mdDest = path.join(projectRoot, "CLAUDE.md");
|
|
97
|
-
if (
|
|
98
|
-
fs.
|
|
106
|
+
if (await pathExists(mdSource) && !(await pathExists(mdDest))) {
|
|
107
|
+
await fs.promises.copyFile(mdSource, mdDest);
|
|
99
108
|
console.log(" 📝 CLAUDE.md 已创建\n");
|
|
100
109
|
}
|
|
101
110
|
|
|
102
|
-
// 复制 profiles.json 到项目
|
|
103
111
|
const profilesSource = path.join(skillsSource, ".claude", "profiles.json");
|
|
104
112
|
const profilesDest = path.join(claudeDest, "profiles.json");
|
|
105
|
-
if (
|
|
106
|
-
fs.
|
|
113
|
+
if (await pathExists(profilesSource) && !(await pathExists(profilesDest))) {
|
|
114
|
+
await fs.promises.copyFile(profilesSource, profilesDest);
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
return installedCount;
|
|
@@ -111,55 +119,50 @@ function installSelectedSkills(selectedNames) {
|
|
|
111
119
|
|
|
112
120
|
// ---------- 场景选择(场景 → 一键装技能) ----------
|
|
113
121
|
|
|
114
|
-
function loadProfiles() {
|
|
122
|
+
async function loadProfiles() {
|
|
115
123
|
const profilesPath = path.join(skillsSource, ".claude", "profiles.json");
|
|
116
|
-
if (!
|
|
124
|
+
if (!(await pathExists(profilesPath))) return null;
|
|
117
125
|
try {
|
|
118
|
-
return JSON.parse(fs.
|
|
126
|
+
return JSON.parse(await fs.promises.readFile(profilesPath, "utf-8")).profiles;
|
|
119
127
|
} catch {
|
|
120
128
|
return null;
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
131
|
|
|
124
|
-
function applyProfile(profile) {
|
|
125
|
-
const pkgSkills = listSkillDirs(pkgSkillsSource);
|
|
126
|
-
const settings = readSettings();
|
|
132
|
+
async function applyProfile(profile) {
|
|
133
|
+
const pkgSkills = await listSkillDirs(pkgSkillsSource);
|
|
134
|
+
const settings = await readSettings();
|
|
127
135
|
|
|
128
|
-
// 确定要启用的技能列表
|
|
129
136
|
let selected;
|
|
130
137
|
if (profile.skills === null) {
|
|
131
|
-
// null 表示"自定义",不做操作,由调用方处理
|
|
132
138
|
return;
|
|
133
139
|
} else if (profile.skills.length === 0) {
|
|
134
140
|
selected = [];
|
|
135
141
|
} else {
|
|
136
|
-
// 只取包内实际存在的技能
|
|
137
142
|
selected = profile.skills.filter((s) => pkgSkills.includes(s));
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
fs.mkdirSync(skillsDest, { recursive: true });
|
|
145
|
+
if (!(await pathExists(skillsDest))) {
|
|
146
|
+
await fs.promises.mkdir(skillsDest, { recursive: true });
|
|
143
147
|
}
|
|
144
148
|
for (const name of pkgSkills) {
|
|
145
149
|
const src = path.join(pkgSkillsSource, name);
|
|
146
150
|
const dest = path.join(skillsDest, name);
|
|
147
151
|
if (selected.includes(name)) {
|
|
148
|
-
if (!
|
|
152
|
+
if (!(await pathExists(dest))) {
|
|
149
153
|
try {
|
|
150
|
-
|
|
154
|
+
await copyDir(src, dest);
|
|
151
155
|
} catch (err) {
|
|
152
156
|
console.error(` ❌ 安装技能 "${name}" 失败:`, err.message);
|
|
153
157
|
}
|
|
154
158
|
}
|
|
155
159
|
} else {
|
|
156
|
-
if (
|
|
157
|
-
fs.
|
|
160
|
+
if (await pathExists(dest)) {
|
|
161
|
+
await fs.promises.rm(dest, { recursive: true, force: true });
|
|
158
162
|
}
|
|
159
163
|
}
|
|
160
164
|
}
|
|
161
165
|
|
|
162
|
-
// 更新 settings
|
|
163
166
|
if (!settings.skills) settings.skills = {};
|
|
164
167
|
for (const name of pkgSkills) {
|
|
165
168
|
const enabled = selected.includes(name);
|
|
@@ -167,31 +170,26 @@ function applyProfile(profile) {
|
|
|
167
170
|
settings.skills[name].enabled = enabled;
|
|
168
171
|
}
|
|
169
172
|
|
|
170
|
-
// 更新 always_apply_skills
|
|
171
173
|
if (profile.always_apply) {
|
|
172
174
|
settings.always_apply_skills = profile.always_apply;
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
// 记录当前活动场景
|
|
176
177
|
settings._active_profile = profile.id;
|
|
177
|
-
writeSettings(settings);
|
|
178
|
+
await writeSettings(settings);
|
|
178
179
|
|
|
179
|
-
// 安装 CLAUDE.md(没有才装)
|
|
180
180
|
const mdSource = path.join(skillsSource, "CLAUDE.md");
|
|
181
181
|
const mdDest = path.join(projectRoot, "CLAUDE.md");
|
|
182
|
-
if (
|
|
183
|
-
fs.
|
|
182
|
+
if (await pathExists(mdSource) && !(await pathExists(mdDest))) {
|
|
183
|
+
await fs.promises.copyFile(mdSource, mdDest);
|
|
184
184
|
console.log(" 📝 CLAUDE.md 已创建\n");
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
// 复制 profiles.json 到项目(方便在项目里修改后 sync 推回)
|
|
188
187
|
const profilesSource = path.join(skillsSource, ".claude", "profiles.json");
|
|
189
188
|
const profilesDest = path.join(claudeDest, "profiles.json");
|
|
190
|
-
if (
|
|
191
|
-
fs.
|
|
189
|
+
if (await pathExists(profilesSource)) {
|
|
190
|
+
await fs.promises.copyFile(profilesSource, profilesDest);
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
// 输出结果
|
|
195
193
|
const enabledCount = selected.length;
|
|
196
194
|
const disabledCount = pkgSkills.length - enabledCount;
|
|
197
195
|
console.log(`\n ✅ 已切换到「${profile.name}」`);
|
|
@@ -201,10 +199,10 @@ function applyProfile(profile) {
|
|
|
201
199
|
async function startSceneSelection() {
|
|
202
200
|
const { select } = await import("@inquirer/prompts");
|
|
203
201
|
const chalk = (await import("chalk")).default;
|
|
204
|
-
const profiles = loadProfiles();
|
|
205
|
-
const settings = readSettings();
|
|
202
|
+
const profiles = await loadProfiles();
|
|
203
|
+
const settings = await readSettings();
|
|
206
204
|
const activeProfile = settings._active_profile;
|
|
207
|
-
const hasExistingInstall =
|
|
205
|
+
const hasExistingInstall = await pathExists(claudeDest);
|
|
208
206
|
|
|
209
207
|
const choices = profiles.map((p) => {
|
|
210
208
|
const isActive = p.id === activeProfile;
|
|
@@ -218,7 +216,6 @@ async function startSceneSelection() {
|
|
|
218
216
|
};
|
|
219
217
|
});
|
|
220
218
|
|
|
221
|
-
// 底部加个分隔
|
|
222
219
|
choices.push(
|
|
223
220
|
{ name: chalk.dim("────────────────"), value: "__sep__", description: "" },
|
|
224
221
|
{ name: " 查看技能清单", value: "__list__", description: "列出所有技能状态" },
|
|
@@ -240,7 +237,6 @@ async function startSceneSelection() {
|
|
|
240
237
|
|
|
241
238
|
if (selectedId === "__list__") {
|
|
242
239
|
await cmdList();
|
|
243
|
-
// 看完列表再回到场景选择
|
|
244
240
|
console.log("");
|
|
245
241
|
return startSceneSelection();
|
|
246
242
|
}
|
|
@@ -248,13 +244,11 @@ async function startSceneSelection() {
|
|
|
248
244
|
const profile = profiles.find((p) => p.id === selectedId);
|
|
249
245
|
|
|
250
246
|
if (profile.skills === null) {
|
|
251
|
-
// "自定义选择" → 跳到 checkbox
|
|
252
247
|
await startInteractiveMenu();
|
|
253
248
|
return;
|
|
254
249
|
}
|
|
255
250
|
|
|
256
251
|
if (profile.id === activeProfile) {
|
|
257
|
-
// 选的已经是当前场景,问要不要微调
|
|
258
252
|
const { confirm } = await import("@inquirer/prompts");
|
|
259
253
|
const tweak = await confirm({
|
|
260
254
|
message: "已是当前场景,是否进入自定义模式微调技能?",
|
|
@@ -266,20 +260,20 @@ async function startSceneSelection() {
|
|
|
266
260
|
return;
|
|
267
261
|
}
|
|
268
262
|
|
|
269
|
-
applyProfile(profile);
|
|
263
|
+
await applyProfile(profile);
|
|
270
264
|
}
|
|
271
265
|
|
|
272
266
|
// ---------- 命令:list ----------
|
|
273
267
|
|
|
274
268
|
async function cmdList() {
|
|
275
|
-
if (!
|
|
269
|
+
if (!(await pathExists(claudeDest))) {
|
|
276
270
|
console.log("\n ⚠️ 尚未安装技能,请先运行 npx mdk-skills\n");
|
|
277
271
|
return;
|
|
278
272
|
}
|
|
279
273
|
|
|
280
274
|
const chalk = (await import("chalk")).default;
|
|
281
|
-
const pkgSkills = getPackageSkills(skillsSource);
|
|
282
|
-
const userSkills = getUserSkills(claudeDest);
|
|
275
|
+
const pkgSkills = await getPackageSkills(skillsSource);
|
|
276
|
+
const userSkills = await getUserSkills(claudeDest);
|
|
283
277
|
|
|
284
278
|
const skillMap = new Map();
|
|
285
279
|
for (const s of userSkills) skillMap.set(s.name, s);
|
|
@@ -319,27 +313,25 @@ async function cmdList() {
|
|
|
319
313
|
async function startInteractiveMenu() {
|
|
320
314
|
const { checkbox } = await import("@inquirer/prompts");
|
|
321
315
|
|
|
322
|
-
if (!
|
|
316
|
+
if (!(await pathExists(pkgSkillsSource))) {
|
|
323
317
|
console.log(" ⚠️ 包内没有找到技能文件\n");
|
|
324
318
|
return;
|
|
325
319
|
}
|
|
326
320
|
|
|
327
|
-
const pkgSkills = getPackageSkills(skillsSource);
|
|
321
|
+
const pkgSkills = await getPackageSkills(skillsSource);
|
|
328
322
|
|
|
329
323
|
if (pkgSkills.length === 0) {
|
|
330
324
|
console.log(" ⚠️ 没有可用技能\n");
|
|
331
325
|
return;
|
|
332
326
|
}
|
|
333
327
|
|
|
334
|
-
|
|
335
|
-
const userSkills = getUserSkills(claudeDest);
|
|
328
|
+
const userSkills = await getUserSkills(claudeDest);
|
|
336
329
|
const enabledSet = new Set(
|
|
337
330
|
userSkills.filter((s) => s.enabled).map((s) => s.name),
|
|
338
331
|
);
|
|
339
332
|
const installedSet = new Set(userSkills.map((s) => s.name));
|
|
340
333
|
|
|
341
|
-
|
|
342
|
-
const hasExistingInstall = fs.existsSync(claudeDest);
|
|
334
|
+
const hasExistingInstall = await pathExists(claudeDest);
|
|
343
335
|
const defaultChecked = hasExistingInstall
|
|
344
336
|
? enabledSet
|
|
345
337
|
: new Set(pkgSkills.map((s) => s.name));
|
|
@@ -364,7 +356,7 @@ async function startInteractiveMenu() {
|
|
|
364
356
|
(name) => !selected.includes(name),
|
|
365
357
|
).length;
|
|
366
358
|
|
|
367
|
-
const installed = installSelectedSkills(selected);
|
|
359
|
+
const installed = await installSelectedSkills(selected);
|
|
368
360
|
|
|
369
361
|
const parts = [];
|
|
370
362
|
if (newCount > 0) parts.push(`新装 ${newCount} 个`);
|
|
@@ -376,7 +368,7 @@ async function startInteractiveMenu() {
|
|
|
376
368
|
|
|
377
369
|
// ---------- 本地源连接管理 ----------
|
|
378
370
|
|
|
379
|
-
function cmdConnect(repoPath) {
|
|
371
|
+
async function cmdConnect(repoPath) {
|
|
380
372
|
if (!repoPath) {
|
|
381
373
|
console.log(" ⚠️ 用法:npx mdk-skills connect <仓库路径>\n");
|
|
382
374
|
return;
|
|
@@ -384,20 +376,20 @@ function cmdConnect(repoPath) {
|
|
|
384
376
|
|
|
385
377
|
repoPath = path.resolve(repoPath);
|
|
386
378
|
|
|
387
|
-
if (!
|
|
379
|
+
if (!(await pathExists(path.join(repoPath, ".claude", "skills")))) {
|
|
388
380
|
console.log(` ❌ 路径 "${repoPath}" 下没有找到 .claude/skills/\n`);
|
|
389
381
|
return;
|
|
390
382
|
}
|
|
391
383
|
|
|
392
|
-
const settings = readSettings();
|
|
384
|
+
const settings = await readSettings();
|
|
393
385
|
settings._skill_source = repoPath;
|
|
394
|
-
writeSettings(settings);
|
|
386
|
+
await writeSettings(settings);
|
|
395
387
|
|
|
396
388
|
console.log(` ✅ 技能目录已设置: ${repoPath}\n`);
|
|
397
389
|
}
|
|
398
390
|
|
|
399
|
-
function cmdSync() {
|
|
400
|
-
const settings = readSettings();
|
|
391
|
+
async function cmdSync() {
|
|
392
|
+
const settings = await readSettings();
|
|
401
393
|
const sourcePath = settings._skill_source;
|
|
402
394
|
|
|
403
395
|
if (!sourcePath) {
|
|
@@ -405,58 +397,53 @@ function cmdSync() {
|
|
|
405
397
|
return;
|
|
406
398
|
}
|
|
407
399
|
|
|
408
|
-
if (!
|
|
400
|
+
if (!(await pathExists(path.join(sourcePath, ".claude")))) {
|
|
409
401
|
console.log(` ❌ 绑定的路径 "${sourcePath}" 已失效\n`);
|
|
410
402
|
return;
|
|
411
403
|
}
|
|
412
404
|
|
|
413
|
-
// 备份仓库旧内容
|
|
414
405
|
const repoClaude = path.join(sourcePath, ".claude");
|
|
415
|
-
if (
|
|
416
|
-
backupDir(repoClaude);
|
|
406
|
+
if (await pathExists(repoClaude)) {
|
|
407
|
+
await backupDir(repoClaude);
|
|
417
408
|
}
|
|
418
409
|
|
|
419
|
-
// 技能 → 反推到仓库
|
|
420
410
|
const repoSkills = path.join(sourcePath, ".claude", "skills");
|
|
421
|
-
if (!
|
|
422
|
-
fs.
|
|
411
|
+
if (!(await pathExists(repoSkills))) {
|
|
412
|
+
await fs.promises.mkdir(repoSkills, { recursive: true });
|
|
423
413
|
}
|
|
424
|
-
for (const name of listSkillDirs(skillsDest)) {
|
|
414
|
+
for (const name of await listSkillDirs(skillsDest)) {
|
|
425
415
|
const src = path.join(skillsDest, name);
|
|
426
416
|
const dest = path.join(repoSkills, name);
|
|
427
|
-
if (
|
|
428
|
-
fs.
|
|
417
|
+
if (await pathExists(dest)) {
|
|
418
|
+
await fs.promises.rm(dest, { recursive: true, force: true });
|
|
429
419
|
}
|
|
430
|
-
|
|
420
|
+
await copyDir(src, dest);
|
|
431
421
|
}
|
|
432
422
|
|
|
433
|
-
// profiles.json → 反推
|
|
434
423
|
const projectProfiles = path.join(claudeDest, "profiles.json");
|
|
435
|
-
if (
|
|
436
|
-
fs.
|
|
424
|
+
if (await pathExists(projectProfiles)) {
|
|
425
|
+
await fs.promises.copyFile(projectProfiles, path.join(sourcePath, ".claude", "profiles.json"));
|
|
437
426
|
}
|
|
438
427
|
|
|
439
|
-
// settings.json → 反推(过滤掉 _skill_source 和 _active_profile)
|
|
440
428
|
const cleanSettings = { ...settings };
|
|
441
429
|
delete cleanSettings._skill_source;
|
|
442
430
|
delete cleanSettings._active_profile;
|
|
443
|
-
fs.
|
|
431
|
+
await fs.promises.writeFile(
|
|
444
432
|
path.join(sourcePath, ".claude", "settings.json"),
|
|
445
433
|
JSON.stringify(cleanSettings, null, 2) + "\n",
|
|
446
434
|
"utf-8",
|
|
447
435
|
);
|
|
448
436
|
|
|
449
|
-
// CLAUDE.md → 反推
|
|
450
437
|
const projectMd = path.join(projectRoot, "CLAUDE.md");
|
|
451
|
-
if (
|
|
452
|
-
fs.
|
|
438
|
+
if (await pathExists(projectMd)) {
|
|
439
|
+
await fs.promises.copyFile(projectMd, path.join(sourcePath, "CLAUDE.md"));
|
|
453
440
|
}
|
|
454
441
|
|
|
455
442
|
console.log(" ✅ 已同步到仓库\n");
|
|
456
443
|
}
|
|
457
444
|
|
|
458
|
-
function cmdClearSource() {
|
|
459
|
-
const settings = readSettings();
|
|
445
|
+
async function cmdClearSource() {
|
|
446
|
+
const settings = await readSettings();
|
|
460
447
|
if (!settings._skill_source) {
|
|
461
448
|
console.log(" ⚠️ 当前未设置任何技能目录\n");
|
|
462
449
|
return;
|
|
@@ -464,7 +451,7 @@ function cmdClearSource() {
|
|
|
464
451
|
|
|
465
452
|
const oldPath = settings._skill_source;
|
|
466
453
|
delete settings._skill_source;
|
|
467
|
-
writeSettings(settings);
|
|
454
|
+
await writeSettings(settings);
|
|
468
455
|
|
|
469
456
|
console.log(` ✅ 已清除技能目录设置: ${oldPath}\n`);
|
|
470
457
|
console.log(` 💡 运行 npx mdk-skills ui 重新设置\n`);
|
|
@@ -475,15 +462,16 @@ function cmdClearSource() {
|
|
|
475
462
|
const COMMANDS = ["list", "connect", "sync", "clear-source", "ui"];
|
|
476
463
|
|
|
477
464
|
async function main() {
|
|
465
|
+
await initPaths();
|
|
466
|
+
|
|
478
467
|
const command = process.argv[2];
|
|
479
468
|
const args = process.argv.slice(3);
|
|
480
469
|
|
|
481
470
|
if (!command) {
|
|
482
|
-
const profiles = loadProfiles();
|
|
471
|
+
const profiles = await loadProfiles();
|
|
483
472
|
if (profiles) {
|
|
484
473
|
await startSceneSelection();
|
|
485
474
|
} else {
|
|
486
|
-
// 没有 profiles.json 时回退到原来的 checkbox
|
|
487
475
|
await startInteractiveMenu();
|
|
488
476
|
}
|
|
489
477
|
} else if (command === "--help" || command === "-h") {
|
|
@@ -508,10 +496,10 @@ async function main() {
|
|
|
508
496
|
npx mdk-skills ui
|
|
509
497
|
`);
|
|
510
498
|
} else if (command === "--connect") {
|
|
511
|
-
cmdConnect(args[0]);
|
|
512
|
-
|
|
499
|
+
await cmdConnect(args[0]);
|
|
500
|
+
await initPaths();
|
|
513
501
|
if (skillsSource) {
|
|
514
|
-
const profiles = loadProfiles();
|
|
502
|
+
const profiles = await loadProfiles();
|
|
515
503
|
if (profiles) {
|
|
516
504
|
await startSceneSelection();
|
|
517
505
|
} else {
|
|
@@ -519,12 +507,12 @@ async function main() {
|
|
|
519
507
|
}
|
|
520
508
|
}
|
|
521
509
|
} else if (command === "connect") {
|
|
522
|
-
cmdConnect(args[0]);
|
|
510
|
+
await cmdConnect(args[0]);
|
|
523
511
|
} else if (command === "sync") {
|
|
524
512
|
if (!skillsSource) { console.log(" ⚠️ 未设置技能目录,请先运行 npx mdk-skills ui\n"); return; }
|
|
525
|
-
cmdSync();
|
|
513
|
+
await cmdSync();
|
|
526
514
|
} else if (command === "clear-source") {
|
|
527
|
-
cmdClearSource();
|
|
515
|
+
await cmdClearSource();
|
|
528
516
|
} else if (command === "ui") {
|
|
529
517
|
require("./web-ui/server");
|
|
530
518
|
} else {
|