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 +1 -1
- package/scripts/cli.js +11 -16
- package/scripts/core.js +0 -9
package/package.json
CHANGED
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
|