dk-frontend-skills 3.0.2 → 3.0.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dk-frontend-skills",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "description": "dk-engineer - 幽默沉稳靠谱的前端开发助手 Claude Skills 配置包,一键注入 .claude/ 技能目录和 CLAUDE.md 人设配置",
5
5
  "author": "XiaoMa",
6
6
  "license": "MIT",
package/scripts/cli.js CHANGED
@@ -56,12 +56,12 @@ async function downloadAndInstallSkill(name, index) {
56
56
 
57
57
  const destDir = path.join(skillsDest, name);
58
58
 
59
- // 检查本地版本
59
+ // 已安装且版本一致则跳过
60
60
  const localMetaPath = path.join(destDir, ".meta.json");
61
61
  if (fs.existsSync(localMetaPath)) {
62
62
  try {
63
63
  const localMeta = JSON.parse(fs.readFileSync(localMetaPath, "utf-8"));
64
- if (localMeta.version === skillInfo.version) return true;
64
+ if (localMeta.version === skillInfo.version) return "skipped";
65
65
  } catch {}
66
66
  }
67
67
 
@@ -77,12 +77,11 @@ async function downloadAndInstallSkill(name, index) {
77
77
  hideCursor: true,
78
78
  }, Presets.shades_classic);
79
79
 
80
- const MAX_RETRIES = 3;
80
+ const MAX_RETRIES = 5;
81
81
 
82
82
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
83
83
  const tempFile = path.join(tempDir, skillInfo.fileName);
84
84
  try {
85
- if (attempt > 1) console.log(` ↻ ${name} 重试第 ${attempt} 次...`);
86
85
  bar.start(100, 0);
87
86
  await downloadFile(url, tempFile, (d, t) => {
88
87
  bar.setTotal(t || skillInfo.size || 100);
@@ -93,10 +92,11 @@ async function downloadAndInstallSkill(name, index) {
93
92
  if (fs.existsSync(destDir)) fs.rmSync(destDir, { recursive: true, force: true });
94
93
  fs.mkdirSync(destDir, { recursive: true });
95
94
 
96
- await tar.x({ file: tempFile, C: destDir });
95
+ await tar.x({ file: tempFile, C: destDir, strip: 1 });
97
96
 
98
97
  fs.rmSync(tempFile, { force: true });
99
- return true;
98
+ console.log(` ✓ ${name}`);
99
+ return "installed";
100
100
  } catch (err) {
101
101
  bar.stop();
102
102
  if (fs.existsSync(tempFile)) fs.rmSync(tempFile, { force: true });
@@ -111,7 +111,6 @@ async function downloadAndInstallSkill(name, index) {
111
111
  }
112
112
 
113
113
  async function installSelectedSkills(selectedNames) {
114
- // 创建目录
115
114
  if (!fs.existsSync(skillsDest)) {
116
115
  fs.mkdirSync(skillsDest, { recursive: true });
117
116
  }
@@ -129,11 +128,9 @@ async function installSelectedSkills(selectedNames) {
129
128
  const dest = path.join(skillsDest, name);
130
129
 
131
130
  if (selectedNames.includes(name)) {
132
- // 勾选了的 下载/更新
133
- const ok = await downloadAndInstallSkill(name, index);
134
- if (ok) installedCount++;
131
+ const result = await downloadAndInstallSkill(name, index);
132
+ if (result === "installed") installedCount++;
135
133
  } else {
136
- // 没勾选的 → 移除
137
134
  if (fs.existsSync(dest)) {
138
135
  fs.rmSync(dest, { recursive: true, force: true });
139
136
  }
@@ -159,7 +156,6 @@ async function installSelectedSkills(selectedNames) {
159
156
  const mdDest = path.join(projectRoot, "CLAUDE.md");
160
157
  if (fs.existsSync(mdSource) && !fs.existsSync(mdDest)) {
161
158
  fs.copyFileSync(mdSource, mdDest);
162
- console.log(" 📝 CLAUDE.md 已创建");
163
159
  }
164
160
 
165
161
  return installedCount;
@@ -249,15 +245,14 @@ async function startInteractiveMenu() {
249
245
  loop: false,
250
246
  });
251
247
 
252
- const newCount = selected.filter((name) => !installedSet.has(name)).length;
248
+ const installed = await installSelectedSkills(selected);
249
+
253
250
  const removedCount = [...installedSet].filter(
254
251
  (name) => !selected.includes(name),
255
252
  ).length;
256
253
 
257
- const installed = await installSelectedSkills(selected);
258
-
259
254
  const parts = [];
260
- if (newCount > 0) parts.push(`+${newCount}`);
255
+ if (installed > 0) parts.push(`+${installed}`);
261
256
  if (removedCount > 0) parts.push(`-${removedCount}`);
262
257
  const summary = parts.length > 0 ? ` ${parts.join(" ")}` : "";
263
258
 
package/scripts/core.js CHANGED
@@ -230,15 +230,6 @@ async function downloadFile(url, destPath, onProgress) {
230
230
  throw new Error(`HTTP ${response.status} ${response.statusText}`);
231
231
  }
232
232
 
233
- // 检查 Content-Type,如果不是 gzip 大概率是 404 页面
234
- const contentType = response.headers.get("content-type") || "";
235
- if (!contentType.includes("gzip") && !contentType.includes("octet-stream") && !contentType.includes("binary")) {
236
- const text = await response.clone().text();
237
- if (text.includes("<!doctype") || text.includes("<html")) {
238
- throw new Error("下载链接无效,请检查 GitHub Release 是否存在");
239
- }
240
- }
241
-
242
233
  const total = parseInt(response.headers.get("content-length") || "0", 10);
243
234
  let downloaded = 0;
244
235