dk-frontend-skills 1.1.0 → 1.1.2

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": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "dk-engineer - 幽默沉稳靠谱的前端开发助手 Claude Skills 配置包,一键注入 .claude/ 技能目录和 CLAUDE.md 人设配置",
5
5
  "author": "XiaoMa",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const { spawn } = require("child_process");
3
+ const { execSync, spawn } = require("child_process");
4
4
 
5
5
  // 获取用户项目根目录
6
6
  const projectRoot = path.resolve(__dirname, "..", "..", "..");
@@ -45,34 +45,43 @@ function appendLog(level, message) {
45
45
  }
46
46
 
47
47
  /**
48
- * 备份已有目录
49
- * 将 dir 复制为 dir.bak.<timestamp>
48
+ * 备份已有目录到 .claude/backups/<timestamp>/
50
49
  * 清理超过 3 份的旧备份
51
50
  */
52
51
  function backupDir(dir) {
53
52
  if (!fs.existsSync(dir)) return null;
54
53
 
55
- const parent = path.dirname(dir);
56
- const base = path.basename(dir);
57
- const bakName = `${base}.bak.${backupTimestamp()}`;
58
- const bakPath = path.join(parent, bakName);
54
+ const backupsDir = path.join(dir, "backups");
55
+ if (!fs.existsSync(backupsDir)) {
56
+ fs.mkdirSync(backupsDir, { recursive: true });
57
+ }
58
+
59
+ const ts = backupTimestamp();
60
+ const bakPath = path.join(backupsDir, ts);
59
61
 
60
62
  fs.cpSync(dir, bakPath, { recursive: true });
61
- appendLog("BACKUP", `${base}/ → ${bakName}/`);
62
- console.log(` 💾 备份 ${base}/ → ${bakName}/`);
63
+
64
+ // 删掉 backups 目录自身的递归副本
65
+ const selfBak = path.join(bakPath, "backups");
66
+ if (fs.existsSync(selfBak)) {
67
+ fs.rmSync(selfBak, { recursive: true, force: true });
68
+ }
69
+
70
+ appendLog("BACKUP", `backups/${ts}/ created`);
71
+ console.log(` 💾 备份 → .claude/backups/${ts}/`);
63
72
 
64
73
  // 清理旧备份,只保留最近 3 份
65
74
  const backups = fs
66
- .readdirSync(parent)
67
- .filter((name) => name.startsWith(`${base}.bak.`))
75
+ .readdirSync(backupsDir)
76
+ .filter((name) => /^\d{8}\.\d{6}$/.test(name))
68
77
  .sort()
69
78
  .reverse();
70
79
 
71
80
  if (backups.length > 3) {
72
81
  for (const old of backups.slice(3)) {
73
- const oldPath = path.join(parent, old);
82
+ const oldPath = path.join(backupsDir, old);
74
83
  fs.rmSync(oldPath, { recursive: true, force: true });
75
- appendLog("CLEAN", `清除旧备份 ${old}/`);
84
+ appendLog("CLEAN", `清除旧备份 backups/${old}/`);
76
85
  }
77
86
  }
78
87
 
@@ -246,11 +255,15 @@ if (fs.existsSync(mdSource)) {
246
255
  fs.copyFileSync(mdSource, mdDest);
247
256
  appendLog("INFO", "CLAUDE.md installed");
248
257
  } else {
249
- // 仅备份用户版本,方便查阅
250
- const bakName = `CLAUDE.md.bak.${backupTimestamp()}`;
251
- const bakPath = path.join(projectRoot, bakName);
258
+ // 仅备份用户版本到 .claude/backups/,方便查阅
259
+ const backupsDir = path.join(claudeDest, "backups");
260
+ if (!fs.existsSync(backupsDir)) {
261
+ fs.mkdirSync(backupsDir, { recursive: true });
262
+ }
263
+ const bakName = `CLAUDE.md.${backupTimestamp()}`;
264
+ const bakPath = path.join(backupsDir, bakName);
252
265
  fs.copyFileSync(mdDest, bakPath);
253
- appendLog("BACKUP", `CLAUDE.md → ${bakName} (user version preserved)`);
266
+ appendLog("BACKUP", `backups/${bakName} (CLAUDE.md user version preserved)`);
254
267
  }
255
268
  }
256
269
 
@@ -269,31 +282,24 @@ if (fs.existsSync(logFile)) {
269
282
  }
270
283
 
271
284
  // 自动卸载
272
- console.log("🧹 清理安装包...");
273
-
274
- const spawnOptions = {
285
+ // 用 detached 子进程延迟卸载,避免在 npm 生命周期中自卸导致冲突
286
+ console.log("🧹 自动卸载安装包...");
287
+
288
+ const uninstallCmd = `
289
+ const { execSync } = require("child_process");
290
+ setTimeout(() => {
291
+ execSync("npm uninstall dk-frontend-skills", {
292
+ cwd: ${JSON.stringify(projectRoot)},
293
+ windowsHide: true,
294
+ stdio: "ignore",
295
+ });
296
+ }, 500);
297
+ `;
298
+
299
+ const child = spawn(process.execPath, ["-e", uninstallCmd], {
275
300
  cwd: projectRoot,
301
+ detached: true,
276
302
  stdio: "ignore",
277
- };
278
- spawnOptions.detached = true;
279
- if (process.platform === "win32") {
280
- spawnOptions.windowsHide = true;
281
- }
282
-
283
- const child = spawn(
284
- process.execPath,
285
- [
286
- "-e",
287
- `
288
- const { execSync } = require("child_process");
289
- setTimeout(() => {
290
- execSync("npm uninstall dk-frontend-skills", {
291
- cwd: ${JSON.stringify(projectRoot)},
292
- windowsHide: true,
293
- });
294
- }, 300);
295
- `,
296
- ],
297
- spawnOptions,
298
- );
303
+ windowsHide: process.platform === "win32",
304
+ });
299
305
  child.unref();