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 +14 -14
- package/lib/init.js +21 -37
- package/lib/skills-bundle.js +1 -3
- package/package.json +1 -1
- package/templates/git-hooks/pre-push-sdd-check.cjs +10 -2
- package/templates/skills/kld-sdd/opsx-apply/SKILL.md +1 -1
- package/templates/skills/kld-sdd/opsx-design/SKILL.md +1 -1
- package/templates/skills/kld-sdd/opsx-knowledge/SKILL.md +6 -8
- package/templates/skills/kld-sdd/opsx-propose/SKILL.md +1 -1
- package/templates/skills/kld-sdd/opsx-spec/SKILL.md +1 -1
- package/templates/skills/kld-sdd/SKILLS.md +0 -28
package/README.md
CHANGED
|
@@ -136,16 +136,19 @@ propose → spec → design → task → check
|
|
|
136
136
|
|
|
137
137
|
---
|
|
138
138
|
|
|
139
|
-
##
|
|
139
|
+
## 预置技能
|
|
140
140
|
|
|
141
|
-
初始化后,SDD
|
|
141
|
+
初始化后,SDD 全套 skill 部署为 **扁平一层**(Claude Code 识别规则):
|
|
142
142
|
|
|
143
|
-
|
|
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/
|
|
194
|
-
│ ├── opsx-propose/
|
|
195
|
-
│ ├── opsx-spec/
|
|
196
|
-
│ └── ... # 其他 opsx-* 子技能
|
|
196
|
+
│ └── skills/opsx-*/ # SDD skills(扁平一层)
|
|
197
197
|
├── .claude/
|
|
198
198
|
│ ├── commands/opsx/ # opsx 命令(9个)
|
|
199
|
-
│ └── skills/
|
|
199
|
+
│ └── skills/opsx-*/ # SDD skills(扁平一层)
|
|
200
200
|
├── .codebuddy/
|
|
201
201
|
│ ├── commands/opsx/ # opsx 命令(9个)
|
|
202
|
-
│ └── skills/
|
|
202
|
+
│ └── skills/opsx-*/ # SDD skills(扁平一层)
|
|
203
203
|
└── .agents/
|
|
204
204
|
├── commands/opsx/ # Codex opsx 命令(9个)
|
|
205
|
-
└── skills/
|
|
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
|
-
*
|
|
507
|
+
* 清理旧版嵌套 bundle(skills/kld-sdd/opsx-*)
|
|
508
|
+
* Claude Code 只识别 skills/<skill-name>/SKILL.md 一层,嵌套 bundle 无法被 / 菜单发现
|
|
508
509
|
* @param {string[]} selectedTools - 用户选择的编辑器列表
|
|
509
510
|
*/
|
|
510
|
-
function
|
|
511
|
-
console.log('🧹
|
|
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
|
|
521
|
-
if (
|
|
522
|
-
|
|
523
|
-
|
|
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
|
-
|
|
533
|
-
|
|
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('✅
|
|
533
|
+
console.log('✅ 旧版嵌套 bundle 清理完成');
|
|
538
534
|
return true;
|
|
539
535
|
}
|
|
540
536
|
|
|
541
537
|
/**
|
|
542
538
|
* 部署 SDD opsx skills
|
|
543
|
-
*
|
|
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} 的
|
|
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(
|
|
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(` ✓ ${
|
|
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.
|
|
1070
|
-
|
|
1053
|
+
// 4. 清理旧版嵌套 skills/kld-sdd/ bundle(Claude Code 无法识别二层目录)
|
|
1054
|
+
cleanupLegacyBundledOpsxSkills(selectedTools);
|
|
1071
1055
|
|
|
1072
|
-
// 4.1 部署 SDD opsx skills
|
|
1056
|
+
// 4.1 部署 SDD opsx skills(扁平到 .claude/skills/opsx-*/)
|
|
1073
1057
|
deployOpsxSkills(selectedTools);
|
|
1074
1058
|
|
|
1075
1059
|
// 4.2 清理原生 openspec-* skills(防止残留)
|
package/lib/skills-bundle.js
CHANGED
|
@@ -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
|
@@ -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 =
|
|
24
|
+
const logCli = resolveLogCli(projectRoot);
|
|
17
25
|
|
|
18
|
-
if (!
|
|
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
|
|
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
|
|
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
|
-
|
|
75
|
+
在项目根目录执行(使用 skill 目录变量,与 gitnexus 子 skill 脚本引用方式一致):
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
node
|
|
79
|
-
node
|
|
80
|
-
node
|
|
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
|
|
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
|
|
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-*` 顶层目录**。
|