kld-sdd 2.4.9 → 2.4.11
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 +9 -6
- package/lib/init.js +76 -21
- package/lib/skills-bundle.js +32 -0
- package/package.json +3 -3
- package/skywalk-sdd/{index.js → index.cjs} +31 -25
- package/templates/ci/github-actions-sdd.yml +3 -3
- package/templates/ci/gitlab-ci-sdd.yml +3 -3
- package/templates/git-hooks/{pre-push-sdd-check.js → pre-push-sdd-check.cjs} +1 -1
- package/templates/hooks/claude/hooks/{sdd-prompt.js → sdd-prompt.cjs} +2 -2
- package/templates/hooks/claude/hooks/{sdd-stop.js → sdd-stop.cjs} +1 -1
- package/templates/hooks/claude/settings.json +4 -4
- package/templates/opsx-commands/apply.md +11 -9
- package/templates/opsx-commands/archive.md +8 -8
- package/templates/opsx-commands/check.md +8 -8
- package/templates/opsx-commands/design.md +3 -3
- package/templates/opsx-commands/explore.md +3 -3
- package/templates/opsx-commands/propose.md +3 -3
- package/templates/opsx-commands/spec.md +3 -3
- package/templates/opsx-commands/task.md +3 -3
- package/templates/opsx-commands/test.md +5 -5
- package/templates/skills/kld-sdd/SKILLS.md +28 -0
- package/templates/skills/{opsx-apply → kld-sdd/opsx-apply}/SKILL.md +12 -4
- package/templates/skills/{opsx-archive → kld-sdd/opsx-archive}/SKILL.md +8 -8
- package/templates/skills/{opsx-check → kld-sdd/opsx-check}/SKILL.md +6 -6
- package/templates/skills/{opsx-design → kld-sdd/opsx-design}/SKILL.md +6 -2
- package/templates/skills/{opsx-explore → kld-sdd/opsx-explore}/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-knowledge/SKILL.md +132 -0
- package/templates/skills/kld-sdd/opsx-knowledge/references/modules.md +26 -0
- package/templates/skills/kld-sdd/opsx-knowledge/scripts/config.json +39 -0
- package/templates/skills/kld-sdd/opsx-knowledge/scripts/retrieve.cjs +199 -0
- package/templates/skills/{opsx-propose → kld-sdd/opsx-propose}/SKILL.md +6 -2
- package/templates/skills/{opsx-spec → kld-sdd/opsx-spec}/SKILL.md +6 -2
- package/templates/skills/{opsx-task → kld-sdd/opsx-task}/SKILL.md +2 -2
- package/templates/skills/{opsx-test → kld-sdd/opsx-test}/SKILL.md +2 -2
- /package/templates/git-hooks/{pre-commit-sdd-check.js → pre-commit-sdd-check.cjs} +0 -0
- /package/templates/hooks/claude/hooks/{sdd-post-tool.js → sdd-post-tool.cjs} +0 -0
- /package/templates/hooks/claude/hooks/{sdd-pre-tool.js → sdd-pre-tool.cjs} +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opsx-knowledge
|
|
3
|
+
description: "Queries RAGFlow business knowledge base for MM/CO domain terms during SDD workflows. Use when encountering unclear business nouns, internal ERP terminology, MM/CO module concepts, or domain rules in propose/spec/design/apply. Results are advisory only and must not override SDD documents or user input."
|
|
4
|
+
argument-hint: "[question] [--module=mm|co|auto]"
|
|
5
|
+
license: MIT
|
|
6
|
+
metadata:
|
|
7
|
+
author: sdd-team
|
|
8
|
+
version: "1.0"
|
|
9
|
+
allowed-tools:
|
|
10
|
+
- Bash
|
|
11
|
+
- Read
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# SDD 业务知识库检索(RAGFlow)
|
|
15
|
+
|
|
16
|
+
为 SDD 工作流提供 **MM / CO 模块** 的业务知识检索。检索结果 **只做建议参考**,不得作为强制约束写入 spec 红线。
|
|
17
|
+
|
|
18
|
+
## RAGFlow 知识库配置
|
|
19
|
+
|
|
20
|
+
```env
|
|
21
|
+
RAGFLOW_BASE_URL=http://10.29.219.26:9380
|
|
22
|
+
RAGFLOW_API_KEY=ragflow-6xxy9RUUtRiE9N6gzpTLfQbY00tnGGKWsEuBR53zp0U
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| 模块 | dataset_id |
|
|
26
|
+
|------|------------|
|
|
27
|
+
| MM模块 | `12eda67a4ffb11f19cb713ede57b176f` |
|
|
28
|
+
| CO模块 | `02841d1e4ffb11f19cb713ede57b176f` |
|
|
29
|
+
|
|
30
|
+
配置已写死在 `scripts/config.json`,脚本会自动读取。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 使用原则(强制)
|
|
35
|
+
|
|
36
|
+
1. **可选**:仅当业务名词/领域含义不清时才查询
|
|
37
|
+
2. **非强制**:不得因知识库结果覆盖 proposal / spec / design / 用户确认内容
|
|
38
|
+
3. **冲突处理**:与用户输入、现有代码、openspec 文档冲突时,以用户 / 文档 / 代码为准
|
|
39
|
+
4. **引用格式**:输出中标注 `📚 知识库建议:...`,禁止写成“必须 / 规定 / 红线”
|
|
40
|
+
5. **失败降级**:内网不可达、超时、无结果时 **继续 SDD 主流程**,仅提示“未查询到知识库”
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 何时查询
|
|
45
|
+
|
|
46
|
+
**适合查询:**
|
|
47
|
+
- 不明业务名词(如“物料凭证”“评估类”“成本中心”)
|
|
48
|
+
- MM / CO 模块内部术语
|
|
49
|
+
- propose / spec / design 阶段需要补充领域背景
|
|
50
|
+
|
|
51
|
+
**不必查询:**
|
|
52
|
+
- 通用技术概念
|
|
53
|
+
- 文档已明确定义
|
|
54
|
+
- 用户已给出权威解释
|
|
55
|
+
|
|
56
|
+
模块判断细则见 [references/modules.md](references/modules.md)。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 执行步骤
|
|
61
|
+
|
|
62
|
+
### 1. 判断模块
|
|
63
|
+
|
|
64
|
+
按上下文自行判断查询 **MM**、**CO**,或两者都查:
|
|
65
|
+
|
|
66
|
+
| 信号 | 倾向模块 |
|
|
67
|
+
|------|----------|
|
|
68
|
+
| 物料、库存、采购、MRP、BOM、仓库 | MM |
|
|
69
|
+
| 成本、费用、预算、核算、CO-PA、成本中心 | CO |
|
|
70
|
+
| proposal/spec 的 capability 名称或路径 | 按模块归属 |
|
|
71
|
+
| 无法判断 | 跳过查询,不阻塞主流程 |
|
|
72
|
+
|
|
73
|
+
### 2. 调用检索脚本
|
|
74
|
+
|
|
75
|
+
在项目根目录执行(路径由初始化时注入,统一在 `<SkillsBundlePath>/` 下):
|
|
76
|
+
|
|
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
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`--module` 取值:
|
|
84
|
+
- `mm` / `co`:指定模块
|
|
85
|
+
- `auto`:按 question 关键词自动匹配(默认)
|
|
86
|
+
|
|
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
|
+
### 3. 处理结果
|
|
92
|
+
|
|
93
|
+
**成功(`ok: true`)**:读取 `chunks`,提炼 1-3 条建议,标注来源模块。
|
|
94
|
+
|
|
95
|
+
**失败(`ok: false`)**:不 retry 阻塞主流程,继续原有 SDD 步骤。
|
|
96
|
+
|
|
97
|
+
输出模板:
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
📚 知识库建议(MM模块,仅供参考):
|
|
101
|
+
- ...
|
|
102
|
+
- ...
|
|
103
|
+
|
|
104
|
+
说明:以上来自 RAGFlow 知识库,不作为 SDD 契约;如与 spec / 用户输入冲突,以 spec / 用户输入为准。
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## API 参考
|
|
110
|
+
|
|
111
|
+
内网 RAGFlow retrieval 接口:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
curl --request POST \
|
|
115
|
+
--url http://10.29.219.26:9380/api/v1/retrieval \
|
|
116
|
+
--header 'Content-Type: application/json' \
|
|
117
|
+
--header 'Authorization: Bearer ragflow-6xxy9RUUtRiE9N6gzpTLfQbY00tnGGKWsEuBR53zp0U' \
|
|
118
|
+
--data '{
|
|
119
|
+
"question": "What is advantage of ragflow?",
|
|
120
|
+
"dataset_ids": ["12eda67a4ffb11f19cb713ede57b176f"]
|
|
121
|
+
}'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
日常优先使用 `scripts/retrieve.cjs`,不要手写 curl。
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 与其他 SDD Skill 的关系
|
|
129
|
+
|
|
130
|
+
- **opsx-propose / opsx-spec / opsx-design / opsx-apply**:遇到业务名词时可 **可选** 调用本 skill
|
|
131
|
+
- **opsx-check**:不得把知识库内容当作质量红线依据
|
|
132
|
+
- 本 skill **不修改** 任何 openspec 文档,只提供参考信息
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 模块知识库映射
|
|
2
|
+
|
|
3
|
+
| 模块 | dataset_id | 典型场景 |
|
|
4
|
+
|------|------------|----------|
|
|
5
|
+
| MM | `12eda67a4ffb11f19cb713ede57b176f` | 物料、库存、采购、MRP、BOM、仓库、批次 |
|
|
6
|
+
| CO | `02841d1e4ffb11f19cb713ede57b176f` | 成本、费用、预算、核算、CO-PA、成本中心 |
|
|
7
|
+
|
|
8
|
+
## 模块选择规则
|
|
9
|
+
|
|
10
|
+
1. 优先看 **proposal/spec 中的 Capability 名称与描述**
|
|
11
|
+
2. 再看 **用户输入中的业务名词**
|
|
12
|
+
3. 再看 **代码路径/包名**(如含 `mm`、`co`、`material`、`cost`)
|
|
13
|
+
4. 若 MM 与 CO 都相关,可分别查询两个模块后合并为建议
|
|
14
|
+
5. 若无法判断模块,**跳过查询**,不要阻塞 SDD 主流程
|
|
15
|
+
|
|
16
|
+
## 查询时机
|
|
17
|
+
|
|
18
|
+
**适合查询:**
|
|
19
|
+
- 业务名词含义不明(如“物料凭证”“成本中心”“评估类”)
|
|
20
|
+
- 内部术语可能有多种解释
|
|
21
|
+
- 需要补充领域背景以写 propose/spec/design
|
|
22
|
+
|
|
23
|
+
**不必查询:**
|
|
24
|
+
- 通用技术概念(HTTP、JWT、Redis)
|
|
25
|
+
- proposal/spec/design 已明确定义
|
|
26
|
+
- 用户已给出权威定义
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"baseUrl": "http://10.29.219.26:9380",
|
|
3
|
+
"apiKey": "ragflow-6xxy9RUUtRiE9N6gzpTLfQbY00tnGGKWsEuBR53zp0U",
|
|
4
|
+
"timeoutMs": 8000,
|
|
5
|
+
"modules": {
|
|
6
|
+
"mm": {
|
|
7
|
+
"datasetId": "12eda67a4ffb11f19cb713ede57b176f",
|
|
8
|
+
"label": "MM模块",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"MM",
|
|
11
|
+
"物料",
|
|
12
|
+
"库存",
|
|
13
|
+
"采购",
|
|
14
|
+
"MRP",
|
|
15
|
+
"BOM",
|
|
16
|
+
"仓库",
|
|
17
|
+
"入库",
|
|
18
|
+
"出库",
|
|
19
|
+
"批次",
|
|
20
|
+
"Material"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"co": {
|
|
24
|
+
"datasetId": "02841d1e4ffb11f19cb713ede57b176f",
|
|
25
|
+
"label": "CO模块",
|
|
26
|
+
"keywords": [
|
|
27
|
+
"CO",
|
|
28
|
+
"成本",
|
|
29
|
+
"费用",
|
|
30
|
+
"预算",
|
|
31
|
+
"核算",
|
|
32
|
+
"CO-PA",
|
|
33
|
+
"利润中心",
|
|
34
|
+
"成本中心",
|
|
35
|
+
"Controlling"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* RAGFlow 知识库检索 CLI(SDD opsx-knowledge 专用)
|
|
4
|
+
*
|
|
5
|
+
* 用法:
|
|
6
|
+
* node scripts/retrieve.cjs --question="什么是物料凭证" --module=mm
|
|
7
|
+
* node scripts/retrieve.cjs --question="成本中心是什么" --module=co
|
|
8
|
+
* node scripts/retrieve.cjs --question="..." --module=auto
|
|
9
|
+
*
|
|
10
|
+
* 失败时 exit 0 并返回 ok:false,不阻断 SDD 主流程。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const http = require('http');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { URL } = require('url');
|
|
17
|
+
|
|
18
|
+
const CONFIG_PATH = path.join(__dirname, 'config.json');
|
|
19
|
+
|
|
20
|
+
function readConfig() {
|
|
21
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const args = {};
|
|
26
|
+
for (const item of argv.slice(2)) {
|
|
27
|
+
if (!item.startsWith('--')) continue;
|
|
28
|
+
const eq = item.indexOf('=');
|
|
29
|
+
if (eq === -1) {
|
|
30
|
+
args[item.slice(2)] = true;
|
|
31
|
+
} else {
|
|
32
|
+
args[item.slice(2, eq)] = item.slice(eq + 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return args;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function scoreModule(question, moduleConfig) {
|
|
39
|
+
const text = String(question || '').toLowerCase();
|
|
40
|
+
let score = 0;
|
|
41
|
+
for (const keyword of moduleConfig.keywords || []) {
|
|
42
|
+
if (text.includes(String(keyword).toLowerCase())) {
|
|
43
|
+
score += 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return score;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function resolveModules(question, moduleArg, config) {
|
|
50
|
+
const modules = config.modules || {};
|
|
51
|
+
if (moduleArg && moduleArg !== 'auto' && modules[moduleArg]) {
|
|
52
|
+
return [moduleArg];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const ranked = Object.entries(modules)
|
|
56
|
+
.map(([key, value]) => ({ key, score: scoreModule(question, value) }))
|
|
57
|
+
.filter(item => item.score > 0)
|
|
58
|
+
.sort((a, b) => b.score - a.score);
|
|
59
|
+
|
|
60
|
+
if (ranked.length === 0) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const topScore = ranked[0].score;
|
|
65
|
+
return ranked.filter(item => item.score === topScore).map(item => item.key);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function postRetrieval(config, question, datasetIds) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const endpoint = new URL('/api/v1/retrieval', config.baseUrl);
|
|
71
|
+
const payload = JSON.stringify({
|
|
72
|
+
question,
|
|
73
|
+
dataset_ids: datasetIds
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const req = http.request(
|
|
77
|
+
{
|
|
78
|
+
hostname: endpoint.hostname,
|
|
79
|
+
port: endpoint.port || 80,
|
|
80
|
+
path: endpoint.pathname,
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: {
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
85
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
86
|
+
},
|
|
87
|
+
timeout: config.timeoutMs || 8000
|
|
88
|
+
},
|
|
89
|
+
res => {
|
|
90
|
+
let body = '';
|
|
91
|
+
res.on('data', chunk => {
|
|
92
|
+
body += chunk;
|
|
93
|
+
});
|
|
94
|
+
res.on('end', () => {
|
|
95
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
96
|
+
reject(new Error(`HTTP ${res.statusCode}: ${body.slice(0, 500)}`));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
resolve(JSON.parse(body));
|
|
101
|
+
} catch (error) {
|
|
102
|
+
reject(new Error(`Invalid JSON response: ${error.message}`));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
req.on('timeout', () => {
|
|
109
|
+
req.destroy(new Error(`Request timeout after ${config.timeoutMs || 8000}ms`));
|
|
110
|
+
});
|
|
111
|
+
req.on('error', reject);
|
|
112
|
+
req.write(payload);
|
|
113
|
+
req.end();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function normalizeChunks(response) {
|
|
118
|
+
const chunks = response?.data?.chunks || response?.chunks || [];
|
|
119
|
+
return chunks.map((chunk, index) => ({
|
|
120
|
+
index: index + 1,
|
|
121
|
+
content: chunk.content || chunk.text || '',
|
|
122
|
+
document_name: chunk.document_name || chunk.doc_name || chunk.document_id || '',
|
|
123
|
+
similarity: chunk.similarity ?? chunk.score ?? null
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function failOutput(error, extra = {}) {
|
|
128
|
+
return {
|
|
129
|
+
ok: false,
|
|
130
|
+
advisory: true,
|
|
131
|
+
error: String(error?.message || error),
|
|
132
|
+
chunks: [],
|
|
133
|
+
...extra
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function main() {
|
|
138
|
+
const args = parseArgs(process.argv);
|
|
139
|
+
const question = String(args.question || '').trim();
|
|
140
|
+
const moduleArg = String(args.module || 'auto').trim().toLowerCase();
|
|
141
|
+
|
|
142
|
+
if (!question) {
|
|
143
|
+
console.log(JSON.stringify(failOutput(new Error('Missing required --question=')), null, 2));
|
|
144
|
+
process.exit(0);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let config;
|
|
149
|
+
try {
|
|
150
|
+
config = readConfig();
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.log(JSON.stringify(failOutput(error)), null, 2);
|
|
153
|
+
process.exit(0);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const selectedModules = resolveModules(question, moduleArg, config);
|
|
158
|
+
if (selectedModules.length === 0) {
|
|
159
|
+
console.log(JSON.stringify({
|
|
160
|
+
ok: false,
|
|
161
|
+
advisory: true,
|
|
162
|
+
skipped: true,
|
|
163
|
+
reason: 'No matching module for question; specify --module=mm or --module=co',
|
|
164
|
+
question,
|
|
165
|
+
chunks: []
|
|
166
|
+
}, null, 2));
|
|
167
|
+
process.exit(0);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const datasetIds = selectedModules.map(key => config.modules[key].datasetId);
|
|
172
|
+
const moduleLabels = selectedModules.map(key => config.modules[key].label);
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const response = await postRetrieval(config, question, datasetIds);
|
|
176
|
+
const chunks = normalizeChunks(response);
|
|
177
|
+
console.log(JSON.stringify({
|
|
178
|
+
ok: true,
|
|
179
|
+
advisory: true,
|
|
180
|
+
question,
|
|
181
|
+
modules: selectedModules,
|
|
182
|
+
module_labels: moduleLabels,
|
|
183
|
+
dataset_ids: datasetIds,
|
|
184
|
+
chunk_count: chunks.length,
|
|
185
|
+
chunks
|
|
186
|
+
}, null, 2));
|
|
187
|
+
process.exit(0);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.log(JSON.stringify(failOutput(error, {
|
|
190
|
+
question,
|
|
191
|
+
modules: selectedModules,
|
|
192
|
+
module_labels: moduleLabels,
|
|
193
|
+
dataset_ids: datasetIds
|
|
194
|
+
}), null, 2));
|
|
195
|
+
process.exit(0);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
main();
|
|
@@ -34,8 +34,8 @@ allowed-tools:
|
|
|
34
34
|
> - 在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径(如 `D:\project\demo`);如必须使用绝对路径,请写成正斜杠路径或加引号。
|
|
35
35
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
36
36
|
> **📊 Telemetry(必做,不得跳过)**
|
|
37
|
-
> - 阶段开始:`node skywalk-sdd/log.
|
|
38
|
-
> - 阶段结束:`node skywalk-sdd/log.
|
|
37
|
+
> - 阶段开始:`node skywalk-sdd/log.cjs start --command=propose --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID>`(保存 event_id)
|
|
38
|
+
> - 阶段结束:`node skywalk-sdd/log.cjs end --event-id=<event_id> --command=propose --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success|failure --summary="摘要"`
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
@@ -88,6 +88,10 @@ allowed-tools:
|
|
|
88
88
|
- 代码文件 → 分析现有实现,识别修改点
|
|
89
89
|
- API 文档 → 了解接口约束、数据模型
|
|
90
90
|
|
|
91
|
+
**【可选】业务知识库检索**:
|
|
92
|
+
遇到不明 MM/CO 业务名词时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)查询 RAGFlow 知识库。
|
|
93
|
+
结果仅作 `📚 知识库建议`,不得写入 proposal 强制约束;查询失败时继续主流程。
|
|
94
|
+
|
|
91
95
|
### 3. 创建变更目录
|
|
92
96
|
|
|
93
97
|
```bash
|
|
@@ -34,8 +34,8 @@ allowed-tools:
|
|
|
34
34
|
> - 在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径(如 `D:\project\demo`);如必须使用绝对路径,请写成正斜杠路径或加引号。
|
|
35
35
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
36
36
|
> **📊 Telemetry(必做,不得跳过)**
|
|
37
|
-
> - 阶段开始:`node skywalk-sdd/log.
|
|
38
|
-
> - 阶段结束:`node skywalk-sdd/log.
|
|
37
|
+
> - 阶段开始:`node skywalk-sdd/log.cjs start --command=spec --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID>`(保存 event_id)
|
|
38
|
+
> - 阶段结束:`node skywalk-sdd/log.cjs end --event-id=<event_id> --command=spec --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success|failure --summary="摘要"`
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
@@ -98,6 +98,10 @@ openspec list
|
|
|
98
98
|
| 代码文件 | 了解现有实现约束 | 纳入技术契约和约束条件 |
|
|
99
99
|
| API 文档 | 接口规范参考 | 对齐数据契约和接口格式 |
|
|
100
100
|
|
|
101
|
+
**【可选】业务知识库检索**:
|
|
102
|
+
术语含义不清且可能影响 spec 准确性时,可调用 **opsx-knowledge** skill(`<SkillsBundlePath>/opsx-knowledge/`)。
|
|
103
|
+
知识库结果仅供参考,spec 契约以用户确认和 proposal 为准;失败时不阻塞。
|
|
104
|
+
|
|
101
105
|
### 4. 【关键步骤】读取本地模板文件
|
|
102
106
|
|
|
103
107
|
**必须先读取** `openspec-templates/spec.md` 作为文档结构模板:
|
|
@@ -41,8 +41,8 @@ allowed-tools:
|
|
|
41
41
|
> - 在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径(如 `D:\project\demo`);如必须使用绝对路径,请写成正斜杠路径或加引号。
|
|
42
42
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
43
43
|
> **📊 Telemetry(必做,不得跳过)**
|
|
44
|
-
> - 阶段开始:`node skywalk-sdd/log.
|
|
45
|
-
> - 阶段结束:`node skywalk-sdd/log.
|
|
44
|
+
> - 阶段开始:`node skywalk-sdd/log.cjs start --command=task --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID>`(保存 event_id)
|
|
45
|
+
> - 阶段结束:`node skywalk-sdd/log.cjs end --event-id=<event_id> --command=task --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success|failure --summary="摘要"`
|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
@@ -29,8 +29,8 @@ allowed-tools:
|
|
|
29
29
|
> - 在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径(如 `D:\project\demo`);如必须使用绝对路径,请写成正斜杠路径或加引号。
|
|
30
30
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
31
31
|
> **📊 Telemetry(必做,不得跳过)**
|
|
32
|
-
> - 阶段开始:`node skywalk-sdd/log.
|
|
33
|
-
> - 阶段结束:`node skywalk-sdd/log.
|
|
32
|
+
> - 阶段开始:`node skywalk-sdd/log.cjs start --command=test --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID>`(保存 event_id)
|
|
33
|
+
> - 阶段结束:`node skywalk-sdd/log.cjs end --event-id=<event_id> --command=test --project=. --change=<变更名称> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success|failure --summary="摘要"`
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|