kld-sdd 2.5.0 → 2.5.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.
Files changed (48) hide show
  1. package/README.md +95 -8
  2. package/kld-sdd-guide.html +1109 -0
  3. package/lib/command-bridge.js +156 -0
  4. package/lib/deploy-codebuddy-hooks.js +99 -0
  5. package/lib/hook-gate-core.js +333 -0
  6. package/lib/init.js +137 -82
  7. package/lib/settings-merge.js +85 -0
  8. package/lib/skills-bundle.js +142 -5
  9. package/lib/tool-profiles.js +270 -0
  10. package/package.json +4 -2
  11. package/skywalk-sdd/index.cjs +329 -24
  12. package/skywalk-sdd/ontology/artifact-observer.cjs +91 -0
  13. package/skywalk-sdd/ontology/artifact-parser.cjs +621 -0
  14. package/skywalk-sdd/ontology/change-lock.cjs +126 -0
  15. package/skywalk-sdd/ontology/cli.cjs +146 -0
  16. package/skywalk-sdd/ontology/effective-graph.cjs +158 -0
  17. package/skywalk-sdd/ontology/id.cjs +126 -0
  18. package/skywalk-sdd/ontology/identity-index.cjs +262 -0
  19. package/skywalk-sdd/ontology/normalizer.cjs +107 -0
  20. package/skywalk-sdd/ontology/runtime.cjs +341 -0
  21. package/skywalk-sdd/ontology/schema.cjs +139 -0
  22. package/skywalk-sdd/ontology/structural-identity.cjs +77 -0
  23. package/skywalk-sdd/ontology/traceability-validator.cjs +610 -0
  24. package/templates/commands/kunlunzhima/skill-bridge.md +23 -0
  25. package/templates/hooks/codebuddy/hooks/sdd-apply-gate.cjs +16 -0
  26. package/templates/hooks/codebuddy/hooks/sdd-apply-test-gate.cjs +395 -0
  27. package/templates/hooks/codebuddy/hooks/sdd-post-tool.cjs +123 -0
  28. package/templates/hooks/codebuddy/hooks/sdd-pre-tool.cjs +16 -0
  29. package/templates/hooks/codebuddy/hooks/sdd-prompt.cjs +48 -0
  30. package/templates/hooks/codebuddy/hooks/sdd-skill-apply-gate.cjs +16 -0
  31. package/templates/hooks/codebuddy/hooks/sdd-stop.cjs +70 -0
  32. package/templates/hooks/codebuddy/settings.json +72 -0
  33. package/templates/openspec/design.md +18 -0
  34. package/templates/openspec/proposal.md +19 -6
  35. package/templates/openspec/spec.md +62 -8
  36. package/templates/openspec/tasks.md +28 -6
  37. package/templates/skills/kld-sdd/opsx-apply/SKILL.md +5 -5
  38. package/templates/skills/kld-sdd/opsx-archive/SKILL.md +9 -0
  39. package/templates/skills/kld-sdd/opsx-check/SKILL.md +17 -1
  40. package/templates/skills/kld-sdd/opsx-design/SKILL.md +10 -1
  41. package/templates/skills/kld-sdd/opsx-explore/SKILL.md +1 -1
  42. package/templates/skills/kld-sdd/opsx-propose/SKILL.md +11 -1
  43. package/templates/skills/kld-sdd/opsx-rules/SKILL.md +131 -0
  44. package/templates/skills/kld-sdd/opsx-rules/checklist.md +27 -0
  45. package/templates/skills/kld-sdd/opsx-rules/reference.md +124 -0
  46. package/templates/skills/kld-sdd/opsx-spec/SKILL.md +12 -1
  47. package/templates/skills/kld-sdd/opsx-task/SKILL.md +10 -1
  48. package/templates/skills/kld-sdd/opsx-test/SKILL.md +1 -1
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Agent capability profiles for KLD SDD init deployment.
3
+ * Single source of truth for per-agent paths and capabilities.
4
+ */
5
+
6
+ const path = require('path');
7
+
8
+ const TOOL_PROFILES = Object.freeze({
9
+ cursor: {
10
+ id: 'cursor',
11
+ agentType: 'cursor',
12
+ surface: 'ide',
13
+ configDir: '.cursor',
14
+ skillsDir: '.cursor/skills',
15
+ commandsDir: '.cursor/commands',
16
+ opsxCommandsDir: '.cursor/commands/opsx',
17
+ projectContextFile: null,
18
+ requiresCommandBridge: false,
19
+ hookProvider: 'none',
20
+ rulesDir: '.cursor/rules',
21
+ rulesFormat: 'mdc',
22
+ rulesWiring: 'none',
23
+ templateVariables: {
24
+ SKILL_RUNTIME_DIR: '.cursor/skills',
25
+ HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
26
+ SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
27
+ },
28
+ },
29
+ claude: {
30
+ id: 'claude',
31
+ agentType: 'claude-code',
32
+ surface: 'cli',
33
+ configDir: '.claude',
34
+ skillsDir: '.claude/skills',
35
+ commandsDir: '.claude/commands',
36
+ opsxCommandsDir: '.claude/commands/opsx',
37
+ projectContextFile: 'CLAUDE.md',
38
+ requiresCommandBridge: false,
39
+ hookProvider: 'claude',
40
+ rulesDir: '.claude/rules',
41
+ rulesFormat: 'md',
42
+ rulesWiring: 'none',
43
+ templateVariables: {
44
+ SKILL_RUNTIME_DIR: '.claude/skills',
45
+ HOOK_GATE_DESCRIPTION: 'Claude Code 已部署 SDD Hook Pack(.claude/hooks + settings.json),自动门禁与遥测增强已启用。',
46
+ SHELL_GUIDANCE: '在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径;如必须使用绝对路径,请写成正斜杠路径或加引号。',
47
+ },
48
+ },
49
+ codebuddy: {
50
+ id: 'codebuddy',
51
+ agentType: 'codebuddy',
52
+ surface: 'cli',
53
+ configDir: '.codebuddy',
54
+ skillsDir: '.codebuddy/skills',
55
+ commandsDir: '.codebuddy/commands',
56
+ opsxCommandsDir: '.codebuddy/commands/opsx',
57
+ projectContextFile: 'CODEBUDDY.md',
58
+ requiresCommandBridge: false,
59
+ hookProvider: 'codebuddy',
60
+ rulesDir: '.codebuddy/rules',
61
+ rulesFormat: 'md',
62
+ rulesWiring: 'none',
63
+ templateVariables: {
64
+ SKILL_RUNTIME_DIR: '.codebuddy/skills',
65
+ HOOK_GATE_DESCRIPTION: 'CodeBuddy CLI 已部署 SDD Hook Pack(.codebuddy/hooks + settings.json),初始化后自动生效。',
66
+ SHELL_GUIDANCE: 'CodeBuddy Hooks 在 Windows 上通过 Git Bash 执行;命令使用 node "$CODEBUDDY_PROJECT_DIR/..." 引用项目路径。',
67
+ },
68
+ },
69
+ qoder: {
70
+ id: 'qoder',
71
+ agentType: 'qoder',
72
+ surface: 'ide',
73
+ configDir: '.qoder',
74
+ skillsDir: '.qoder/skills',
75
+ commandsDir: '.qoder/commands',
76
+ opsxCommandsDir: '.qoder/commands/opsx',
77
+ projectContextFile: null,
78
+ requiresCommandBridge: false,
79
+ hookProvider: 'none',
80
+ rulesDir: '.qoder/rules',
81
+ rulesFormat: 'md',
82
+ rulesWiring: 'none',
83
+ templateVariables: {
84
+ SKILL_RUNTIME_DIR: '.qoder/skills',
85
+ HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
86
+ SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
87
+ },
88
+ },
89
+ opencode: {
90
+ id: 'opencode',
91
+ agentType: 'opencode',
92
+ surface: 'cli',
93
+ configDir: '.opencode',
94
+ skillsDir: '.opencode/skills',
95
+ commandsDir: '.opencode/commands',
96
+ // opsxCommandsDir: schema 对齐用;OpenCode 不部署嵌套 command bridge(skill 即斜杠命令)
97
+ opsxCommandsDir: '.opencode/commands/opsx',
98
+ // nativeCommandDir: legacy OpenSpec 单数 command/ 目录清理
99
+ nativeCommandDir: '.opencode/command',
100
+ projectContextFile: null,
101
+ requiresCommandBridge: false,
102
+ hookProvider: 'none',
103
+ rulesDir: null,
104
+ rulesFormat: 'md',
105
+ rulesWiring: 'opencode-config',
106
+ templateVariables: {
107
+ SKILL_RUNTIME_DIR: '.opencode/skills',
108
+ HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
109
+ SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;OpenCode 可通过环境变量 OPENCODE_GIT_BASH_PATH 指定 Git Bash;如需 Bash 请使用 Git Bash。',
110
+ },
111
+ },
112
+ kunlunzhima: {
113
+ id: 'kunlunzhima',
114
+ agentType: 'kunlunzhima',
115
+ surface: 'ide',
116
+ configDir: '.kunlunzhima',
117
+ skillsDir: '.kunlunzhima/skills',
118
+ commandsDir: '.kunlunzhima/commands',
119
+ opsxCommandsDir: '.kunlunzhima/commands/opsx',
120
+ projectContextFile: 'KunLunZhiMa.md',
121
+ requiresCommandBridge: true,
122
+ hookProvider: 'none',
123
+ rulesDir: '.kunlunzhima/.rules',
124
+ rulesFormat: 'mdc-kunlun',
125
+ rulesWiring: 'none',
126
+ templateVariables: {
127
+ SKILL_RUNTIME_DIR: '.kunlunzhima/skills',
128
+ HOOK_GATE_DESCRIPTION: 'KunlunZhima IDE 不支持自动 Hook 门禁;请通过 Skill 自检、commands 入口与 CI/Git 证据门禁保障质量。',
129
+ SHELL_GUIDANCE: 'KunlunZhima IDE 通过 commands/skills 入口使用 SDD;相对引用以 Skill 目录解析。',
130
+ },
131
+ },
132
+ workbuddy: {
133
+ id: 'workbuddy',
134
+ agentType: 'workbuddy',
135
+ surface: 'ide',
136
+ configDir: '.workbuddy',
137
+ skillsDir: '.workbuddy/skills',
138
+ commandsDir: '.workbuddy/commands',
139
+ opsxCommandsDir: '.workbuddy/commands/opsx',
140
+ projectContextFile: null,
141
+ requiresCommandBridge: false,
142
+ hookProvider: 'none',
143
+ rulesDir: '.workbuddy/rules',
144
+ rulesFormat: 'md',
145
+ rulesWiring: 'context-file',
146
+ templateVariables: {
147
+ SKILL_RUNTIME_DIR: '.workbuddy/skills',
148
+ HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
149
+ SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
150
+ },
151
+ },
152
+ codex: {
153
+ id: 'codex',
154
+ agentType: 'codex',
155
+ surface: 'cli',
156
+ configDir: '.agents',
157
+ skillsDir: '.agents/skills',
158
+ commandsDir: '.agents/commands',
159
+ opsxCommandsDir: '.agents/commands/opsx',
160
+ projectContextFile: null,
161
+ requiresCommandBridge: false,
162
+ hookProvider: 'none',
163
+ rulesDir: null,
164
+ rulesFormat: 'md',
165
+ rulesWiring: 'agents-md',
166
+ templateVariables: {
167
+ SKILL_RUNTIME_DIR: '.agents/skills',
168
+ HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
169
+ SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
170
+ },
171
+ },
172
+ });
173
+
174
+ const PATH_FIELDS = ['configDir', 'skillsDir', 'commandsDir', 'opsxCommandsDir', 'nativeCommandDir', 'rulesDir'];
175
+ const VALID_RULES_FORMATS = ['md', 'mdc', 'mdc-kunlun'];
176
+ const VALID_RULES_WIRING = ['none', 'opencode-config', 'agents-md', 'context-file'];
177
+
178
+ function isSafeRelativePath(value) {
179
+ if (typeof value !== 'string' || value.length === 0) return false;
180
+ if (path.isAbsolute(value)) return false;
181
+ if (value.includes('..')) return false;
182
+ return !/[\\]/.test(value);
183
+ }
184
+
185
+ function validateToolProfiles() {
186
+ const errors = [];
187
+ for (const [id, profile] of Object.entries(TOOL_PROFILES)) {
188
+ if (profile.id !== id) {
189
+ errors.push(`${id}: profile.id mismatch (${profile.id})`);
190
+ }
191
+ for (const field of PATH_FIELDS) {
192
+ if (profile[field] == null) continue;
193
+ if (!isSafeRelativePath(profile[field])) {
194
+ errors.push(`${id}: invalid path in ${field} (${profile[field]})`);
195
+ }
196
+ }
197
+ if (!['cli', 'ide'].includes(profile.surface)) {
198
+ errors.push(`${id}: invalid surface (${profile.surface})`);
199
+ }
200
+ if (!['claude', 'codebuddy', 'none'].includes(profile.hookProvider)) {
201
+ errors.push(`${id}: invalid hookProvider (${profile.hookProvider})`);
202
+ }
203
+ if (typeof profile.requiresCommandBridge !== 'boolean') {
204
+ errors.push(`${id}: requiresCommandBridge must be boolean`);
205
+ }
206
+ if (!VALID_RULES_FORMATS.includes(profile.rulesFormat)) {
207
+ errors.push(`${id}: invalid rulesFormat (${profile.rulesFormat})`);
208
+ }
209
+ if (!VALID_RULES_WIRING.includes(profile.rulesWiring)) {
210
+ errors.push(`${id}: invalid rulesWiring (${profile.rulesWiring})`);
211
+ }
212
+ }
213
+ return errors;
214
+ }
215
+
216
+ function getToolProfile(id) {
217
+ if (!id || typeof id !== 'string') {
218
+ throw new Error('缺少 tool id');
219
+ }
220
+ const profile = TOOL_PROFILES[id];
221
+ if (!profile) {
222
+ throw new Error(`不支持的编辑器: ${id}`);
223
+ }
224
+ return profile;
225
+ }
226
+
227
+ function listToolProfileIds() {
228
+ return Object.keys(TOOL_PROFILES);
229
+ }
230
+
231
+ const DEFAULT_TOOL_DISPLAY_NAMES = {
232
+ cursor: 'Cursor',
233
+ claude: 'Claude Code',
234
+ codebuddy: 'CodeBuddy',
235
+ qoder: 'Qoder',
236
+ opencode: 'OpenCode',
237
+ kunlunzhima: 'KunlunZhima',
238
+ workbuddy: 'WorkBuddy',
239
+ codex: 'Codex',
240
+ };
241
+
242
+ function buildToolConfigs(displayNames = DEFAULT_TOOL_DISPLAY_NAMES) {
243
+ const configs = {};
244
+ for (const id of listToolProfileIds()) {
245
+ const profile = TOOL_PROFILES[id];
246
+ const entry = {
247
+ name: displayNames[id] || id,
248
+ configDir: profile.configDir,
249
+ commandsDir: profile.commandsDir,
250
+ opsxDir: profile.opsxCommandsDir,
251
+ skillsDir: profile.skillsDir,
252
+ agentType: profile.agentType,
253
+ };
254
+ if (profile.nativeCommandDir) {
255
+ entry.nativeCommandDir = profile.nativeCommandDir;
256
+ }
257
+ configs[id] = entry;
258
+ }
259
+ return configs;
260
+ }
261
+
262
+ module.exports = {
263
+ TOOL_PROFILES,
264
+ getToolProfile,
265
+ listToolProfileIds,
266
+ validateToolProfiles,
267
+ isSafeRelativePath,
268
+ buildToolConfigs,
269
+ DEFAULT_TOOL_DISPLAY_NAMES,
270
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kld-sdd",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "KLD SDD OpenSpec 项目初始化工具 - 一键部署 SDD skills",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,7 +8,7 @@
8
8
  "kld-sdd-init": "bin/kld-sdd-init.js"
9
9
  },
10
10
  "scripts": {
11
- "test": "node test/validate-skills-bundle.cjs"
11
+ "test": "node test/ontology-release-blockers.cjs && node test/ontology-semantic-core.cjs && node test/ontology-identity-versioning.cjs && node test/ontology-state-transaction.cjs && node test/ontology-process-concurrency.cjs && node test/ontology-observer-convergence.cjs && node test/ontology-working-runtime.cjs && node test/ontology-template-contract.cjs && node test/ontology-cli-archive.cjs && node test/validate-skills-bundle.cjs && node test/tool-profiles.cjs && node test/settings-merge.cjs && node test/command-bridge.cjs && node test/codebuddy-hooks.cjs && node test/skill-content-contract.cjs && node test/init-agent-profiles.cjs"
12
12
  },
13
13
  "keywords": [
14
14
  "kld",
@@ -30,7 +30,9 @@
30
30
  "bin/",
31
31
  "lib/",
32
32
  "templates/",
33
+ "kld-sdd-guide.html",
33
34
  "skywalk-sdd/index.cjs",
35
+ "skywalk-sdd/ontology/",
34
36
  "skywalk-sdd/apply-worktree-finish.cjs",
35
37
  "README.md"
36
38
  ]