kld-sdd 2.4.18 → 2.4.19

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.
Files changed (2) hide show
  1. package/lib/init.js +47 -29
  2. package/package.json +1 -1
package/lib/init.js CHANGED
@@ -350,23 +350,40 @@ function copyDirRendered(source, target, config, toolKey) {
350
350
  }
351
351
  }
352
352
 
353
+ /** OpenSpec init 生成的 4 个官方 slash command(KLD-SDD 使用 skills,不保留 command) */
354
+ const NATIVE_OPSX_CMDS_HYPHEN = [
355
+ 'opsx-propose.md',
356
+ 'opsx-apply.md',
357
+ 'opsx-archive.md',
358
+ 'opsx-explore.md'
359
+ ];
360
+ const NATIVE_OPSX_CMDS_SLASH = ['propose.md', 'apply.md', 'archive.md', 'explore.md'];
361
+
353
362
  /**
354
- * 清理原生 openspec 命令(opsx-*.md),避免与 opsx:* 命令混淆
355
- * 同时清理 openspec 遗留的 JSON 文件
356
- *
363
+ * SDD 自定义 command 标记(init 不部署;用户手动维护时保留)
364
+ */
365
+ function isSddCustomCommand(content) {
366
+ return content.includes('# SDD') || content.includes('skywalk-sdd/log.cjs');
367
+ }
368
+
369
+ /**
370
+ * 清理原生 openspec 命令,所有编辑器与 Cursor 行为一致:初始化时删除官方 command。
371
+ * 同时清理 openspec 遗留的 JSON 文件。
372
+ *
373
+ * 覆盖 TOOL_CONFIGS 中的全部编辑器(cursor/claude/codebuddy/qoder/opencode/kunlunzhima/workbuddy/codex),
374
+ * 与 Cursor 行为一致:初始化时删除 OpenSpec 官方 command,仅保留 skills。
375
+ *
357
376
  * openspec 对不同工具生成的目录结构:
358
377
  * - Cursor: commands/opsx-*.md(根目录,连字符)
359
- * - Claude/CodeBuddy/Qoder: commands/opsx/*.md(opsx 子目录)
360
- * - OpenCode: command/opsx-*.md(command 单数目录)
361
- *
378
+ * - Claude/CodeBuddy/Qoder 等: commands/opsx/*.md(opsx 子目录)
379
+ * - OpenCode: command/opsx-*.md(command 单数目录,整目录删除)
380
+ *
362
381
  * @param {string[]} selectedTools - 用户选择的编辑器列表
363
382
  */
364
383
  function cleanupNativeOpenspecCommands(selectedTools = Object.keys(TOOL_CONFIGS)) {
365
- console.log('🗑 正在清理原生 openspec 命令(避免与 opsx:* 命令混淆)...');
384
+ console.log('🗑 正在清理原生 openspec 命令(所有编辑器与 Cursor 一致,仅保留 skills)...');
366
385
 
367
386
  const cwd = process.cwd();
368
- // 原生 openspec 根目录命令文件(使用连字符,与 opsx:* 冒号命令混淆)
369
- const nativeCmds = ['opsx-propose.md', 'opsx-apply.md', 'opsx-archive.md', 'opsx-explore.md'];
370
387
 
371
388
  for (const toolKey of selectedTools) {
372
389
  const config = TOOL_CONFIGS[toolKey];
@@ -392,40 +409,41 @@ function cleanupNativeOpenspecCommands(selectedTools = Object.keys(TOOL_CONFIGS)
392
409
  console.log(` 🗑 ${config.name}: 删除 ${deletedJson} 个 JSON 命令文件`);
393
410
  }
394
411
 
395
- // 删除 commands/ 目录下的原生 opsx-* 命令(Cursor 和其他工具都可能有)
412
+ // 删除 commands/ 根目录下的原生 opsx-* 命令(Cursor 等,与 Claude 行为一致)
396
413
  let deletedCmds = 0;
397
- for (const cmd of nativeCmds) {
398
- const filePath = path.join(commandsDir, cmd);
399
- if (fs.existsSync(filePath)) {
400
- fs.unlinkSync(filePath);
401
- deletedCmds++;
402
- }
414
+ for (const file of fs.readdirSync(commandsDir)) {
415
+ const isNativeHyphen = NATIVE_OPSX_CMDS_HYPHEN.includes(file) || /^opsx-.*\.md$/i.test(file);
416
+ if (!isNativeHyphen) continue;
417
+ const filePath = path.join(commandsDir, file);
418
+ if (!fs.statSync(filePath).isFile()) continue;
419
+ const content = fs.readFileSync(filePath, 'utf-8');
420
+ if (isSddCustomCommand(content)) continue;
421
+ fs.unlinkSync(filePath);
422
+ deletedCmds++;
403
423
  }
404
424
  if (deletedCmds > 0) {
405
425
  console.log(` ✓ ${config.name}: 删除 ${deletedCmds} 个原生 opsx-* 命令(commands/)`);
406
426
  }
407
427
 
408
- // 删除 commands/opsx/ 子目录下的原生命令(Claude/CodeBuddy/Qoder
428
+ // 删除 commands/opsx/ 子目录下的官方命令(Claude/CodeBuddy/Qoder 等,与 Cursor 一致无条件删除)
409
429
  const opsxDir = path.join(commandsDir, 'opsx');
410
430
  if (fs.existsSync(opsxDir)) {
411
- const opsxFiles = fs.readdirSync(opsxDir);
412
431
  let deletedOpsxCmds = 0;
413
- // 只删除原生的 4 个命令,保留其他可能存在的文件
414
- const nativeOpsxCmds = ['propose.md', 'apply.md', 'archive.md', 'explore.md'];
415
- for (const file of nativeOpsxCmds) {
432
+ for (const file of NATIVE_OPSX_CMDS_SLASH) {
416
433
  const filePath = path.join(opsxDir, file);
417
- if (fs.existsSync(filePath)) {
418
- // 检查是否是原生命令(不含 YAML frontmatter 中的 SDD 标记)
419
- const content = fs.readFileSync(filePath, 'utf-8');
420
- if (!content.includes('# SDD') && !content.includes('OPSX:')) {
421
- fs.unlinkSync(filePath);
422
- deletedOpsxCmds++;
423
- }
424
- }
434
+ if (!fs.existsSync(filePath)) continue;
435
+ const content = fs.readFileSync(filePath, 'utf-8');
436
+ if (isSddCustomCommand(content)) continue;
437
+ fs.unlinkSync(filePath);
438
+ deletedOpsxCmds++;
425
439
  }
426
440
  if (deletedOpsxCmds > 0) {
427
441
  console.log(` ✓ ${config.name}: 删除 ${deletedOpsxCmds} 个原生命令(commands/opsx/)`);
428
442
  }
443
+ // 子目录为空则移除
444
+ if (fs.readdirSync(opsxDir).length === 0) {
445
+ fs.rmdirSync(opsxDir);
446
+ }
429
447
  }
430
448
  }
431
449
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kld-sdd",
3
- "version": "2.4.18",
3
+ "version": "2.4.19",
4
4
  "description": "KLD SDD OpenSpec 项目初始化工具 - 一键部署 SDD skills",
5
5
  "main": "index.js",
6
6
  "bin": {