kld-sdd 2.4.12 → 2.4.13

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/README.md CHANGED
@@ -136,16 +136,19 @@ propose → spec → design → task → check
136
136
 
137
137
  ---
138
138
 
139
- ## 预置技能:`kld-sdd`
139
+ ## 预置技能
140
140
 
141
- 初始化后,SDD 全套技能会统一打包部署到 `.*/skills/kld-sdd/`(与 `gitnexus/` 目录模式一致),包含 `opsx-propose`、`opsx-spec`、`opsx-design`、`opsx-task`、`opsx-check`、`opsx-apply`、`opsx-test`、`opsx-archive`、`opsx-explore`、`opsx-knowledge` 等子技能。
141
+ 初始化后,SDD 全套 skill 部署为 **扁平一层**(Claude Code 识别规则):
142
142
 
143
- 激活后,AI 会化身 **SDD 工作流专家**,检测当前项目的文档状态,引导你从当前进度继续:
143
+ ```
144
+ .claude/skills/opsx-propose/SKILL.md → /opsx-propose
145
+ .claude/skills/opsx-spec/SKILL.md → /opsx-spec
146
+ ...
147
+ ```
148
+
149
+ 模板源码组织在 `kld-sdd/templates/skills/kld-sdd/`(仅用于打包维护,不是 Claude 的识别路径)。
144
150
 
145
- > "当前项目变更:
146
- > - `add-user-auth`:propose✓ spec✓ design○ task○(建议下一步:design)
147
- >
148
- > 请选择:A. 继续 / B. 创建新变更 / C. 质量检查"
151
+ > Claude Code 只识别 `.claude/skills/<skill-name>/SKILL.md` 这一层。嵌套在 `skills/kld-sdd/opsx-*` 下不会被 `/` 菜单发现。GitNexus 能识别是因为 `npx gitnexus analyze` 同时安装了 `~/.claude/skills/gitnexus-*/` 扁平 skill。
149
152
 
150
153
  ---
151
154
 
@@ -190,19 +193,16 @@ your-project/
190
193
  │ └── task.md
191
194
  ├── .cursor/
192
195
  │ ├── commands/opsx/ # opsx 命令(9个)
193
- │ └── skills/kld-sdd/ # SDD 技能统一目录
194
- │ ├── opsx-propose/
195
- │ ├── opsx-spec/
196
- │ └── ... # 其他 opsx-* 子技能
196
+ │ └── skills/opsx-*/ # SDD skills(扁平一层)
197
197
  ├── .claude/
198
198
  │ ├── commands/opsx/ # opsx 命令(9个)
199
- │ └── skills/kld-sdd/ # SDD 技能统一目录
199
+ │ └── skills/opsx-*/ # SDD skills(扁平一层)
200
200
  ├── .codebuddy/
201
201
  │ ├── commands/opsx/ # opsx 命令(9个)
202
- │ └── skills/kld-sdd/ # SDD 技能统一目录
202
+ │ └── skills/opsx-*/ # SDD skills(扁平一层)
203
203
  └── .agents/
204
204
  ├── commands/opsx/ # Codex opsx 命令(9个)
205
- └── skills/kld-sdd/ # Codex 项目级技能
205
+ └── skills/opsx-*/ # Codex 项目级 skills
206
206
  ```
207
207
 
208
208
  ---
package/lib/init.js CHANGED
@@ -504,43 +504,40 @@ function overrideOpsxCommands(selectedTools = Object.keys(TOOL_CONFIGS)) {
504
504
  }
505
505
 
506
506
  /**
507
- * 清理旧版扁平 opsx-* skills(迁移到 skills/kld-sdd/ 统一目录)
507
+ * 清理旧版嵌套 bundle(skills/kld-sdd/opsx-*)
508
+ * Claude Code 只识别 skills/<skill-name>/SKILL.md 一层,嵌套 bundle 无法被 / 菜单发现
508
509
  * @param {string[]} selectedTools - 用户选择的编辑器列表
509
510
  */
510
- function cleanupLegacyFlatOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
511
- console.log('🧹 正在清理旧版扁平 opsx-* skills...');
511
+ function cleanupLegacyBundledOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
512
+ console.log('🧹 正在清理旧版嵌套 skills/kld-sdd/ bundle...');
512
513
 
513
514
  const cwd = process.cwd();
514
- const legacySkillDirs = [...OPSX_SKILL_DIRS, 'opsx-sdd'];
515
515
 
516
516
  for (const toolKey of selectedTools) {
517
517
  const config = TOOL_CONFIGS[toolKey];
518
518
  if (!config || !config.skillsDir) continue;
519
519
 
520
- const skillsDir = path.join(cwd, config.skillsDir);
521
- if (!fs.existsSync(skillsDir)) continue;
522
-
523
- let removed = 0;
524
- for (const legacySkill of legacySkillDirs) {
525
- const legacySkillDir = path.join(skillsDir, legacySkill);
526
- if (fs.existsSync(legacySkillDir)) {
527
- fs.rmSync(legacySkillDir, { recursive: true, force: true });
528
- removed++;
529
- }
520
+ const bundledDir = path.join(cwd, config.skillsDir, SKILLS_BUNDLE_NAME);
521
+ if (fs.existsSync(bundledDir)) {
522
+ fs.rmSync(bundledDir, { recursive: true, force: true });
523
+ console.log(` 🗑 ${config.name}: 删除嵌套 bundle ${SKILLS_BUNDLE_NAME}/`);
530
524
  }
531
525
 
532
- if (removed > 0) {
533
- console.log(` 🗑 ${config.name}: 删除 ${removed} 个旧版扁平 opsx skills`);
526
+ const legacySdd = path.join(cwd, config.skillsDir, 'opsx-sdd');
527
+ if (fs.existsSync(legacySdd)) {
528
+ fs.rmSync(legacySdd, { recursive: true, force: true });
529
+ console.log(` 🗑 ${config.name}: 删除旧版 opsx-sdd/`);
534
530
  }
535
531
  }
536
532
 
537
- console.log('✅ 旧版扁平 opsx skills 清理完成');
533
+ console.log('✅ 旧版嵌套 bundle 清理完成');
538
534
  return true;
539
535
  }
540
536
 
541
537
  /**
542
538
  * 部署 SDD opsx skills
543
- * templates/skills/kld-sdd/ 复制到各编辑器的 skills/kld-sdd/ 目录
539
+ * 模板源:templates/skills/kld-sdd/(源码组织)
540
+ * 部署目标:.claude/skills/opsx-<name>/SKILL.md(扁平一层,Claude Code 可识别)
544
541
  * @param {string[]} selectedTools - 用户选择的编辑器列表
545
542
  */
546
543
  function deployOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
@@ -571,21 +568,17 @@ function deployOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
571
568
  if (!config || !config.skillsDir) continue;
572
569
 
573
570
  const targetSkillsDir = path.join(cwd, config.skillsDir);
574
- const targetBundleDir = path.join(targetSkillsDir, SKILLS_BUNDLE_NAME);
575
571
 
576
572
  // 确保 skills 目录存在
577
573
  if (!fs.existsSync(targetSkillsDir)) {
578
574
  fs.mkdirSync(targetSkillsDir, { recursive: true });
579
575
  }
580
- if (!fs.existsSync(targetBundleDir)) {
581
- fs.mkdirSync(targetBundleDir, { recursive: true });
582
- }
583
576
 
584
- console.log(` 部署 ${config.name} 的 ${SKILLS_BUNDLE_NAME} skills(${skillDirs.length} 个)...`);
577
+ console.log(` 部署 ${config.name} 的 opsx skills(${skillDirs.length} 个,扁平到 ${config.skillsDir}/)...`);
585
578
 
586
579
  for (const skillDir of skillDirs) {
587
580
  const sourceDir = path.join(skillsTemplatePath, skillDir);
588
- const targetDir = path.join(targetBundleDir, skillDir);
581
+ const targetDir = path.join(targetSkillsDir, skillDir);
589
582
 
590
583
  if (!fs.existsSync(targetDir)) {
591
584
  fs.mkdirSync(targetDir, { recursive: true });
@@ -593,18 +586,9 @@ function deployOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
593
586
 
594
587
  if (fs.existsSync(sourceDir)) {
595
588
  copyDirRendered(sourceDir, targetDir, config, toolKey);
596
- console.log(` ✓ ${SKILLS_BUNDLE_NAME}/${skillDir}`);
589
+ console.log(` ✓ ${skillDir}/`);
597
590
  }
598
591
  }
599
-
600
- // 复制 bundle 根目录说明文件(如 SKILLS.md)
601
- for (const file of fs.readdirSync(skillsTemplatePath)) {
602
- const sourceFile = path.join(skillsTemplatePath, file);
603
- if (!fs.statSync(sourceFile).isFile()) continue;
604
- const rendered = renderTemplate(fs.readFileSync(sourceFile, 'utf8'), config, toolKey);
605
- fs.writeFileSync(path.join(targetBundleDir, file), rendered, 'utf8');
606
- console.log(` ✓ ${SKILLS_BUNDLE_NAME}/${file}`);
607
- }
608
592
  }
609
593
 
610
594
  console.log('✅ opsx skills 部署完成');
@@ -1066,10 +1050,10 @@ async function main() {
1066
1050
  // 3. 部署 SDD opsx 命令(根据编辑器类型使用不同模板)
1067
1051
  overrideOpsxCommands(selectedTools);
1068
1052
 
1069
- // 4. 清理旧版扁平 opsx-* skills(迁移到 skills/kld-sdd/)
1070
- cleanupLegacyFlatOpsxSkills(selectedTools);
1053
+ // 4. 清理旧版嵌套 skills/kld-sdd/ bundle(Claude Code 无法识别二层目录)
1054
+ cleanupLegacyBundledOpsxSkills(selectedTools);
1071
1055
 
1072
- // 4.1 部署 SDD opsx skills(统一打包到 skills/kld-sdd/)
1056
+ // 4.1 部署 SDD opsx skills(扁平到 .claude/skills/opsx-*/)
1073
1057
  deployOpsxSkills(selectedTools);
1074
1058
 
1075
1059
  // 4.2 清理原生 openspec-* skills(防止残留)
@@ -18,11 +18,9 @@ const OPSX_SKILL_DIRS = [
18
18
  ];
19
19
 
20
20
  function renderTemplate(content, config, toolKey) {
21
- const skillsBundlePath = `${config.skillsDir}/${SKILLS_BUNDLE_NAME}`;
22
21
  return content
23
22
  .replace(/^\uFEFF/, '')
24
- .replace(/<Agent(?:\u7c7b\u578b|\u7eeb\u8bf2\u7037)>/g, config.agentType || toolKey)
25
- .replace(/<SkillsBundlePath>/g, skillsBundlePath);
23
+ .replace(/<Agent(?:\u7c7b\u578b|\u7eeb\u8bf2\u7037)>/g, config.agentType || toolKey);
26
24
  }
27
25
 
28
26
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kld-sdd",
3
- "version": "2.4.12",
3
+ "version": "2.4.13",
4
4
  "description": "KLD SDD OpenSpec 项目初始化工具 - 内置模版一键初始化",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -10,12 +10,20 @@ function readArg(name) {
10
10
  return found ? found.slice(prefix.length) : '';
11
11
  }
12
12
 
13
+ function resolveLogCli(projectRoot) {
14
+ const logCjs = path.join(projectRoot, 'skywalk-sdd', 'log.cjs');
15
+ if (fs.existsSync(logCjs)) {
16
+ return logCjs;
17
+ }
18
+ return null;
19
+ }
20
+
13
21
  function main() {
14
22
  const projectRoot = path.resolve(readArg('project') || process.env.SDD_PROJECT || process.cwd());
15
23
  const changeName = readArg('change') || process.env.SDD_CHANGE || process.env.OPENSPEC_CHANGE || '';
16
- const logCli = path.join(projectRoot, 'skywalk-sdd', 'log.js');
24
+ const logCli = resolveLogCli(projectRoot);
17
25
 
18
- if (!fs.existsSync(logCli)) {
26
+ if (!logCli) {
19
27
  console.log('SDD pre-push: skywalk-sdd/log.cjs not found; doctor gate skipped.');
20
28
  return;
21
29
  }
@@ -123,7 +123,7 @@ openspec list --json
123
123
  ```
124
124
 
125
125
  **【可选】业务知识库检索**:
126
- 编码中遇到不明业务名词时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)辅助理解。
126
+ 编码中遇到不明业务名词时,可调用 **opsx-knowledge** skill 辅助理解。
127
127
  不得因知识库建议偏离 tasks/spec;查询失败时继续实施。
128
128
 
129
129
  ### 3. 解析 DAG 任务拓扑
@@ -95,7 +95,7 @@ openspec list
95
95
  | 数据库 Schema | 了解数据模型约束 | 纳入数据设计章节 |
96
96
 
97
97
  **【可选】业务知识库检索**:
98
- 设计涉及 MM/CO 领域概念且 spec 未充分定义时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)。
98
+ 设计涉及 MM/CO 领域概念且 spec 未充分定义时,可调用 **opsx-knowledge** skill
99
99
  仅作背景参考,不得覆盖 spec;内网不可达时跳过并继续 design。
100
100
 
101
101
  ### 3. 渐进式上下文加载
@@ -72,22 +72,20 @@ RAGFLOW_API_KEY=ragflow-6xxy9RUUtRiE9N6gzpTLfQbY00tnGGKWsEuBR53zp0U
72
72
 
73
73
  ### 2. 调用检索脚本
74
74
 
75
- 在项目根目录执行(路径由初始化时注入,统一在 `<SkillsBundlePath>/` 下):
75
+ 在项目根目录执行(使用 skill 目录变量,与 gitnexus 子 skill 脚本引用方式一致):
76
76
 
77
77
  ```bash
78
- node <SkillsBundlePath>/opsx-knowledge/scripts/retrieve.cjs --question="物料凭证是什么" --module=mm
79
- node <SkillsBundlePath>/opsx-knowledge/scripts/retrieve.cjs --question="成本中心与利润中心的区别" --module=co
80
- node <SkillsBundlePath>/opsx-knowledge/scripts/retrieve.cjs --question="..." --module=auto
78
+ node ${CLAUDE_SKILL_DIR}/scripts/retrieve.cjs --question="物料凭证是什么" --module=mm
79
+ node ${CLAUDE_SKILL_DIR}/scripts/retrieve.cjs --question="成本中心与利润中心的区别" --module=co
80
+ node ${CLAUDE_SKILL_DIR}/scripts/retrieve.cjs --question="..." --module=auto
81
81
  ```
82
82
 
83
+ `${CLAUDE_SKILL_DIR}` 由 Claude Code 注入,指向本 skill 目录(如 `.claude/skills/opsx-knowledge/`)。
84
+
83
85
  `--module` 取值:
84
86
  - `mm` / `co`:指定模块
85
87
  - `auto`:按 question 关键词自动匹配(默认)
86
88
 
87
- 部署后示例:
88
- - Claude Code:`.claude/skills/kld-sdd/opsx-knowledge/scripts/retrieve.cjs`
89
- - Cursor:`.cursor/skills/kld-sdd/opsx-knowledge/scripts/retrieve.cjs`
90
-
91
89
  ### 3. 处理结果
92
90
 
93
91
  **成功(`ok: true`)**:读取 `chunks`,提炼 1-3 条建议,标注来源模块。
@@ -89,7 +89,7 @@ allowed-tools:
89
89
  - API 文档 → 了解接口约束、数据模型
90
90
 
91
91
  **【可选】业务知识库检索**:
92
- 遇到不明 MM/CO 业务名词时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)查询 RAGFlow 知识库。
92
+ 遇到不明 MM/CO 业务名词时,可调用 **opsx-knowledge** skill 查询 RAGFlow 知识库。
93
93
  结果仅作 `📚 知识库建议`,不得写入 proposal 强制约束;查询失败时继续主流程。
94
94
 
95
95
  ### 3. 创建变更目录
@@ -99,7 +99,7 @@ openspec list
99
99
  | API 文档 | 接口规范参考 | 对齐数据契约和接口格式 |
100
100
 
101
101
  **【可选】业务知识库检索**:
102
- 术语含义不清且可能影响 spec 准确性时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)。
102
+ 术语含义不清且可能影响 spec 准确性时,可调用 **opsx-knowledge** skill
103
103
  知识库结果仅供参考,spec 契约以用户确认和 proposal 为准;失败时不阻塞。
104
104
 
105
105
  ### 4. 【关键步骤】读取本地模板文件
@@ -1,28 +0,0 @@
1
- # KLD SDD Skills Bundle
2
-
3
- 所有 SDD 技能统一打包在本目录,部署到 `<SkillsBundlePath>/`(如 `.claude/skills/kld-sdd/`)。
4
-
5
- ## 子技能索引
6
-
7
- | 技能 name | 路径 | 用途 |
8
- |-----------|------|------|
9
- | `opsx-propose` | `opsx-propose/SKILL.md` | 业务意图文档 |
10
- | `opsx-spec` | `opsx-spec/SKILL.md` | 技术契约 |
11
- | `opsx-design` | `opsx-design/SKILL.md` | 技术方案 |
12
- | `opsx-task` | `opsx-task/SKILL.md` | 任务拆解 |
13
- | `opsx-check` | `opsx-check/SKILL.md` | 质量门禁 |
14
- | `opsx-apply` | `opsx-apply/SKILL.md` | 变更实施 |
15
- | `opsx-test` | `opsx-test/SKILL.md` | 单元测试 |
16
- | `opsx-archive` | `opsx-archive/SKILL.md` | 变更归档 |
17
- | `opsx-explore` | `opsx-explore/SKILL.md` | 变更浏览 |
18
- | `opsx-knowledge` | `opsx-knowledge/SKILL.md` | RAGFlow 业务知识库(可选) |
19
-
20
- ## 路径约定
21
-
22
- - 子 skill 内相对引用:如 `references/modules.md`、`scripts/retrieve.cjs`(相对于该 skill 目录)
23
- - 跨 skill 引用:使用 frontmatter 中的 `name`(如 `opsx-knowledge`),或 bundle 路径 `<SkillsBundlePath>/opsx-knowledge/`
24
- - 知识库脚本:`<SkillsBundlePath>/opsx-knowledge/scripts/retrieve.cjs`
25
-
26
- ## 与 /opsx:* 命令的关系
27
-
28
- 命令定义在 `.*/commands/opsx/*.md`;本 bundle 提供对应阶段的 skill 详细工作流。两者通过相同的 `name`(如 `opsx-propose`)关联,**不依赖扁平的 `skills/opsx-*` 顶层目录**。