kld-sdd 2.4.19 → 2.5.1

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 (47) hide show
  1. package/kld-sdd-guide.html +1109 -0
  2. package/lib/command-bridge.js +156 -0
  3. package/lib/deploy-codebuddy-hooks.js +99 -0
  4. package/lib/hook-gate-core.js +333 -0
  5. package/lib/init.js +136 -93
  6. package/lib/settings-merge.js +85 -0
  7. package/lib/skills-bundle.js +142 -5
  8. package/lib/tool-profiles.js +270 -0
  9. package/package.json +3 -2
  10. package/skywalk-sdd/index.cjs +1808 -129
  11. package/templates/commands/kunlunzhima/skill-bridge.md +23 -0
  12. package/templates/hooks/claude/hooks/sdd-apply-test-gate.cjs +175 -28
  13. package/templates/hooks/claude/hooks/sdd-post-tool.cjs +42 -21
  14. package/templates/hooks/codebuddy/hooks/sdd-apply-gate.cjs +16 -0
  15. package/templates/hooks/codebuddy/hooks/sdd-apply-test-gate.cjs +395 -0
  16. package/templates/hooks/codebuddy/hooks/sdd-post-tool.cjs +123 -0
  17. package/templates/hooks/codebuddy/hooks/sdd-pre-tool.cjs +16 -0
  18. package/templates/hooks/codebuddy/hooks/sdd-prompt.cjs +48 -0
  19. package/templates/hooks/codebuddy/hooks/sdd-skill-apply-gate.cjs +16 -0
  20. package/templates/hooks/codebuddy/hooks/sdd-stop.cjs +70 -0
  21. package/templates/hooks/codebuddy/settings.json +72 -0
  22. package/templates/openspec/proposal.md +0 -1
  23. package/templates/openspec/spec.md +2 -2
  24. package/templates/skills/kld-sdd/opsx-apply/SKILL.md +65 -356
  25. package/templates/skills/kld-sdd/opsx-apply/checklist.md +94 -0
  26. package/templates/skills/kld-sdd/opsx-apply/reference.md +403 -0
  27. package/templates/skills/kld-sdd/opsx-archive/SKILL.md +21 -5
  28. package/templates/skills/kld-sdd/opsx-archive/checklist.md +33 -0
  29. package/templates/skills/kld-sdd/opsx-check/SKILL.md +29 -5
  30. package/templates/skills/kld-sdd/opsx-check/checklist.md +37 -0
  31. package/templates/skills/kld-sdd/opsx-design/SKILL.md +47 -51
  32. package/templates/skills/kld-sdd/opsx-design/checklist.md +46 -0
  33. package/templates/skills/kld-sdd/opsx-design/reference.md +44 -0
  34. package/templates/skills/kld-sdd/opsx-explore/SKILL.md +1 -1
  35. package/templates/skills/kld-sdd/opsx-propose/SKILL.md +52 -96
  36. package/templates/skills/kld-sdd/opsx-propose/checklist.md +44 -0
  37. package/templates/skills/kld-sdd/opsx-propose/reference.md +94 -0
  38. package/templates/skills/kld-sdd/opsx-rules/SKILL.md +131 -0
  39. package/templates/skills/kld-sdd/opsx-rules/checklist.md +27 -0
  40. package/templates/skills/kld-sdd/opsx-rules/reference.md +124 -0
  41. package/templates/skills/kld-sdd/opsx-spec/SKILL.md +47 -51
  42. package/templates/skills/kld-sdd/opsx-spec/checklist.md +46 -0
  43. package/templates/skills/kld-sdd/opsx-spec/reference.md +49 -0
  44. package/templates/skills/kld-sdd/opsx-task/SKILL.md +43 -46
  45. package/templates/skills/kld-sdd/opsx-task/checklist.md +46 -0
  46. package/templates/skills/kld-sdd/opsx-task/reference.md +40 -0
  47. package/templates/skills/kld-sdd/opsx-test/SKILL.md +13 -1
@@ -0,0 +1,1109 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>kld-sdd · 从入门到入土 — SDD 规格驱动开发完整指南</title>
7
+ <meta name="description" content="kld-sdd 完整使用指南:从 SDD 理念、安装初始化,到 11 个 opsx 技能的完整研发工作流。">
8
+ <style>
9
+ /* ─────────────────────────────────────────────────────────
10
+ 设计令牌:Terminal × Blueprint
11
+ ───────────────────────────────────────────────────────── */
12
+ :root{
13
+ --bg:#0a0d14;
14
+ --bg-grad:radial-gradient(1200px 600px at 80% -10%, rgba(94,234,212,.06), transparent 60%),
15
+ radial-gradient(900px 500px at 0% 0%, rgba(129,140,248,.06), transparent 55%);
16
+ --surface:#10141e;
17
+ --surface-2:#161c2a;
18
+ --surface-3:#1c2436;
19
+ --border:#232c40;
20
+ --border-soft:#1a2233;
21
+ --text:#e9ecf4;
22
+ --text-2:#a6afc4;
23
+ --text-3:#6c7690;
24
+ --accent:#5eead4;
25
+ --accent-ink:#0a0d14;
26
+ --accent-2:#818cf8;
27
+ --accent-3:#c4b5fd;
28
+ --sky:#38bdf8;
29
+ --green:#4ade80;
30
+ --amber:#fbbf24;
31
+ --red:#f87171;
32
+ --glow:0 0 0 1px rgba(94,234,212,.25), 0 8px 30px -12px rgba(94,234,212,.35);
33
+ /* 旅程渐变:破晓青 → 正午天青 → 黄昏靛 → 暮色紫,编码"入门→入土" */
34
+ --journey:linear-gradient(180deg,#5eead4 0%,#38bdf8 32%,#818cf8 66%,#c084fc 100%);
35
+ --mono:"JetBrains Mono","Fira Code","Cascadia Code","SF Mono",Consolas,"Courier New",monospace;
36
+ --sans:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei","Hiragino Sans GB",system-ui,sans-serif;
37
+ --r-sm:8px; --r-md:12px; --r-lg:18px; --r-xl:24px;
38
+ --shadow:0 1px 0 rgba(255,255,255,.02), 0 12px 40px -18px rgba(0,0,0,.6);
39
+ --maxw:1080px;
40
+ }
41
+
42
+ *{box-sizing:border-box}
43
+ html{scroll-behavior:smooth}
44
+ body{
45
+ margin:0;
46
+ font-family:var(--sans);
47
+ background:var(--bg);
48
+ background-image:var(--bg-grad);
49
+ background-attachment:fixed;
50
+ color:var(--text);
51
+ line-height:1.7;
52
+ font-size:16px;
53
+ -webkit-font-smoothing:antialiased;
54
+ text-rendering:optimizeLegibility;
55
+ }
56
+ /* 极淡蓝图网格底 */
57
+ body::before{
58
+ content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
59
+ background-image:
60
+ linear-gradient(rgba(94,234,212,.025) 1px,transparent 1px),
61
+ linear-gradient(90deg,rgba(94,234,212,.025) 1px,transparent 1px);
62
+ background-size:46px 46px;
63
+ mask-image:radial-gradient(ellipse 100% 70% at 50% 0%,#000 30%,transparent 80%);
64
+ }
65
+ a{color:var(--accent);text-decoration:none}
66
+ a:hover{text-decoration:underline}
67
+ code{font-family:var(--mono);font-size:.88em}
68
+
69
+ /* ─────────────────────────────────────────────────────────
70
+ 布局骨架
71
+ ───────────────────────────────────────────────────────── */
72
+ .wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px;position:relative;z-index:1}
73
+ section{position:relative;z-index:1;padding:88px 0;border-top:1px solid var(--border-soft)}
74
+ section:first-of-type{border-top:none}
75
+ .sec-head{display:flex;align-items:baseline;gap:18px;margin-bottom:8px;flex-wrap:wrap}
76
+ .sec-num{
77
+ font-family:var(--mono);font-size:.82rem;font-weight:600;
78
+ padding:3px 10px;border-radius:999px;
79
+ background:var(--journey);color:var(--accent-ink);
80
+ letter-spacing:.05em;flex-shrink:0;
81
+ }
82
+ .sec-title{font-size:clamp(1.5rem,3.4vw,2.1rem);font-weight:700;letter-spacing:-.01em;margin:0}
83
+ .sec-sub{color:var(--text-2);max-width:680px;margin:.5rem 0 0;font-size:1.02rem}
84
+ .lead{color:var(--text-2)}
85
+
86
+ /* ── 左侧旅程进度轴(签名元素)── */
87
+ .journey-rail{
88
+ position:fixed;left:18px;top:0;height:100vh;width:3px;z-index:40;pointer-events:none;
89
+ display:flex;justify-content:center;
90
+ }
91
+ .journey-rail::before{content:"";width:2px;height:100%;background:var(--border-soft)}
92
+ .journey-rail .fill{
93
+ position:absolute;top:0;width:2px;background:var(--journey);
94
+ background-size:100% 100%;transition:height .15s linear;
95
+ box-shadow:0 0 12px rgba(94,234,212,.4);
96
+ }
97
+ .journey-dot{
98
+ position:absolute;left:50%;transform:translate(-50%,-50%);
99
+ width:11px;height:11px;border-radius:50%;
100
+ background:var(--bg);border:2px solid var(--text-3);
101
+ transition:all .3s ease;
102
+ }
103
+ .journey-dot.lit{border-color:var(--accent);box-shadow:0 0 10px rgba(94,234,212,.6)}
104
+ @media (max-width:980px){.journey-rail{display:none}}
105
+
106
+ /* ─────────────────────────────────────────────────────────
107
+ 顶部导航
108
+ ───────────────────────────────────────────────────────── */
109
+ header.nav{
110
+ position:sticky;top:0;z-index:50;
111
+ background:rgba(10,13,20,.78);
112
+ backdrop-filter:blur(14px) saturate(140%);
113
+ -webkit-backdrop-filter:blur(14px) saturate(140%);
114
+ border-bottom:1px solid var(--border-soft);
115
+ }
116
+ .nav-inner{display:flex;align-items:center;gap:22px;height:62px}
117
+ .brand{display:flex;align-items:center;gap:10px;font-weight:700;font-family:var(--mono);font-size:1rem}
118
+ .brand .dot{width:10px;height:10px;border-radius:3px;background:var(--journey);box-shadow:0 0 10px rgba(94,234,212,.6)}
119
+ .brand span{color:var(--text)}
120
+ .brand .v{color:var(--text-3);font-weight:500;font-size:.8rem;border:1px solid var(--border);padding:1px 7px;border-radius:6px}
121
+ .nav-links{display:flex;gap:4px;margin-left:14px;flex:1;flex-wrap:wrap}
122
+ .nav-links a{
123
+ color:var(--text-2);font-size:.86rem;padding:6px 11px;border-radius:8px;
124
+ font-family:var(--mono);transition:all .18s;
125
+ }
126
+ .nav-links a:hover{color:var(--text);background:var(--surface-2);text-decoration:none}
127
+ .nav-cta{
128
+ font-family:var(--mono);font-size:.82rem;padding:7px 13px;border-radius:8px;
129
+ border:1px solid var(--accent);color:var(--accent);transition:all .18s;
130
+ }
131
+ .nav-cta:hover{background:var(--accent);color:var(--accent-ink);text-decoration:none}
132
+ @media (max-width:760px){.nav-links{display:none}}
133
+
134
+ /* ─────────────────────────────────────────────────────────
135
+ Hero
136
+ ───────────────────────────────────────────────────────── */
137
+ .hero{padding:96px 0 64px;border-top:none}
138
+ .hero .tag{
139
+ display:inline-flex;align-items:center;gap:8px;
140
+ font-family:var(--mono);font-size:.78rem;color:var(--accent);
141
+ border:1px solid var(--border);background:var(--surface);
142
+ padding:5px 12px;border-radius:999px;margin-bottom:24px;
143
+ }
144
+ .hero .tag::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 8px var(--green)}
145
+ .hero h1{
146
+ font-size:clamp(2.4rem,7vw,4.2rem);line-height:1.05;letter-spacing:-.025em;
147
+ margin:0 0 18px;font-weight:800;
148
+ }
149
+ .hero h1 .grad{
150
+ background:var(--journey);-webkit-background-clip:text;background-clip:text;
151
+ -webkit-text-fill-color:transparent;
152
+ }
153
+ .hero h1 .dim{color:var(--text-3);font-weight:300}
154
+ .hero .pitch{font-size:clamp(1.05rem,2.2vw,1.3rem);color:var(--text-2);max-width:660px;margin:0 0 8px}
155
+ .hero .pitch b{color:var(--text);font-weight:600}
156
+ .hero .ctas{display:flex;gap:14px;margin-top:32px;flex-wrap:wrap}
157
+ .btn{
158
+ display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:.92rem;
159
+ padding:12px 22px;border-radius:10px;transition:all .2s;cursor:pointer;border:1px solid transparent;
160
+ }
161
+ .btn-primary{background:var(--accent);color:var(--accent-ink);font-weight:600}
162
+ .btn-primary:hover{transform:translateY(-1px);box-shadow:0 10px 30px -10px rgba(94,234,212,.6)}
163
+ .btn-ghost{border-color:var(--border);color:var(--text);background:var(--surface)}
164
+ .btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
165
+
166
+ /* hero 终端 */
167
+ .term{
168
+ margin-top:48px;background:var(--surface);border:1px solid var(--border);
169
+ border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow);
170
+ }
171
+ .term-bar{display:flex;align-items:center;gap:8px;padding:12px 16px;background:var(--surface-2);border-bottom:1px solid var(--border-soft)}
172
+ .term-bar .d{width:12px;height:12px;border-radius:50%;background:var(--surface-3)}
173
+ .term-bar .d.r{background:#ff5f57}.term-bar .d.y{background:#febc2e}.term-bar .d.g{background:#28c840}
174
+ .term-bar .tt{margin-left:10px;font-family:var(--mono);font-size:.78rem;color:var(--text-3)}
175
+ .term-body{padding:22px 24px;font-family:var(--mono);font-size:.9rem;line-height:1.85;overflow-x:auto}
176
+ .term-body .c{color:var(--text-3)} /* comment */
177
+ .term-body .p{color:var(--accent)} /* prompt */
178
+ .term-body .k{color:var(--accent-3)} /* keyword/cmd */
179
+ .term-body .o{color:var(--text-2)} /* output */
180
+ .term-body .ok{color:var(--green)}
181
+ .term-body .cursor{display:inline-block;width:9px;height:1.1em;background:var(--accent);vertical-align:-2px;animation:blink 1.1s steps(1) infinite;margin-left:2px}
182
+ @keyframes blink{50%{opacity:0}}
183
+
184
+ /* hero 统计条 */
185
+ .stats{
186
+ display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
187
+ background:var(--border-soft);border:1px solid var(--border-soft);
188
+ border-radius:var(--r-md);overflow:hidden;margin-top:36px;
189
+ }
190
+ .stat{background:var(--surface);padding:18px 20px}
191
+ .stat .n{font-family:var(--mono);font-size:1.5rem;font-weight:700;background:var(--journey);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
192
+ .stat .l{color:var(--text-3);font-size:.78rem;font-family:var(--mono);margin-top:2px}
193
+ @media (max-width:640px){.stats{grid-template-columns:repeat(2,1fr)}}
194
+
195
+ /* ─────────────────────────────────────────────────────────
196
+ 对比卡(为什么是 SDD)
197
+ ───────────────────────────────────────────────────────── */
198
+ .compare{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:36px}
199
+ .cmp{border:1px solid var(--border);border-radius:var(--r-lg);padding:26px;background:var(--surface);position:relative;overflow:hidden}
200
+ .cmp.bad{border-color:rgba(248,113,113,.3)}
201
+ .cmp.good{border-color:rgba(94,234,212,.3)}
202
+ .cmp .label{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:.78rem;font-weight:600;padding:4px 11px;border-radius:999px;margin-bottom:16px}
203
+ .cmp.bad .label{background:rgba(248,113,113,.12);color:var(--red)}
204
+ .cmp.good .label{background:rgba(94,234,212,.12);color:var(--accent)}
205
+ .cmp h4{margin:0 0 12px;font-size:1.05rem}
206
+ .cmp ul{margin:0;padding-left:18px;color:var(--text-2);font-size:.94rem}
207
+ .cmp li{margin-bottom:7px}
208
+ .cmp.good li b{color:var(--accent)}
209
+ @media (max-width:720px){.compare{grid-template-columns:1fr}}
210
+
211
+ /* ─────────────────────────────────────────────────────────
212
+ 工作流管线(签名交互元素)
213
+ ───────────────────────────────────────────────────────── */
214
+ .pipeline{
215
+ margin-top:40px;background:var(--surface);border:1px solid var(--border);
216
+ border-radius:var(--r-xl);padding:30px 26px;box-shadow:var(--shadow);
217
+ }
218
+ .pipeline-hint{font-family:var(--mono);font-size:.78rem;color:var(--text-3);margin-bottom:18px;text-align:center}
219
+ .flow{display:flex;align-items:stretch;gap:0;overflow-x:auto;padding-bottom:6px}
220
+ .stage{
221
+ flex:1 0 auto;min-width:108px;cursor:pointer;text-align:center;
222
+ padding:16px 10px;border-radius:var(--r-md);border:1px solid transparent;
223
+ transition:all .2s;position:relative;
224
+ }
225
+ .stage:hover{background:var(--surface-2);border-color:var(--border)}
226
+ .stage.active{background:var(--surface-3);border-color:var(--accent);box-shadow:var(--glow)}
227
+ .stage .ic{font-size:1.4rem;margin-bottom:6px;display:block}
228
+ .stage .nm{font-family:var(--mono);font-size:.82rem;font-weight:600;color:var(--text)}
229
+ .stage .rl{font-size:.72rem;color:var(--text-3);margin-top:2px}
230
+ .arrow{flex:0 0 auto;display:flex;align-items:center;color:var(--text-3);font-size:1.1rem;padding:0 2px}
231
+ .helpers{display:flex;gap:12px;justify-content:center;margin-top:20px;flex-wrap:wrap}
232
+ .helper{
233
+ font-family:var(--mono);font-size:.76rem;color:var(--text-2);
234
+ border:1px dashed var(--border);border-radius:999px;padding:6px 14px;
235
+ display:inline-flex;align-items:center;gap:7px;
236
+ }
237
+ .helper .ic{color:var(--accent-3)}
238
+
239
+ /* ─────────────────────────────────────────────────────────
240
+ 技能详解卡
241
+ ───────────────────────────────────────────────────────── */
242
+ .skills-grid{display:grid;grid-template-columns:1fr;gap:16px;margin-top:36px}
243
+ .skill{
244
+ border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
245
+ padding:24px 26px;scroll-margin-top:80px;transition:border-color .2s;
246
+ border-left:3px solid var(--border);position:relative;overflow:hidden;
247
+ }
248
+ .skill:hover{border-color:var(--accent)}
249
+ .skill .top{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:10px}
250
+ .skill .idx{
251
+ font-family:var(--mono);font-size:.74rem;color:var(--accent-ink);font-weight:700;
252
+ background:var(--journey);padding:3px 9px;border-radius:6px;flex-shrink:0;
253
+ }
254
+ .skill h3{margin:0;font-family:var(--mono);font-size:1.08rem;color:var(--text)}
255
+ .skill h3 .arg{color:var(--text-3);font-weight:400}
256
+ .skill .role{margin-left:auto;font-family:var(--mono);font-size:.72rem;color:var(--text-3);border:1px solid var(--border);padding:2px 9px;border-radius:6px}
257
+ .skill p{margin:8px 0;color:var(--text-2);font-size:.96rem}
258
+ .skill .red{margin-top:14px;padding:12px 14px;background:rgba(248,113,113,.06);border-left:2px solid var(--red);border-radius:0 8px 8px 0;font-size:.88rem}
259
+ .skill .red b{color:var(--red)}
260
+ .skill .out{margin-top:12px;font-family:var(--mono);font-size:.82rem;color:var(--accent)}
261
+ .skill .out::before{content:"产物 → ";color:var(--text-3)}
262
+ .skill ul.tight{margin:8px 0;padding-left:18px;color:var(--text-2);font-size:.92rem}
263
+ .skill ul.tight li{margin-bottom:4px}
264
+
265
+ /* ─────────────────────────────────────────────────────────
266
+ 通用:代码块、表格、树
267
+ ───────────────────────────────────────────────────────── */
268
+ .codeblock{
269
+ position:relative;background:var(--surface);border:1px solid var(--border);
270
+ border-radius:var(--r-md);margin-top:14px;overflow:hidden;
271
+ }
272
+ .codeblock pre{margin:0;padding:16px 18px;overflow-x:auto;font-family:var(--mono);font-size:.86rem;line-height:1.7;color:var(--text)}
273
+ .codeblock .copy{
274
+ position:absolute;top:8px;right:8px;font-family:var(--mono);font-size:.72rem;
275
+ background:var(--surface-3);color:var(--text-2);border:1px solid var(--border);
276
+ padding:4px 9px;border-radius:6px;cursor:pointer;opacity:0;transition:all .18s;
277
+ }
278
+ .codeblock:hover .copy{opacity:1}
279
+ .codeblock .copy:hover{color:var(--accent);border-color:var(--accent)}
280
+ .k-c{color:var(--text-3)} .k-p{color:var(--accent)} .k-s{color:var(--accent-3)} .k-f{color:var(--sky)} .k-o{color:var(--text-2)}
281
+
282
+ table.tbl{width:100%;border-collapse:collapse;margin-top:24px;font-size:.92rem;border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
283
+ table.tbl th,table.tbl td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--border-soft)}
284
+ table.tbl thead th{background:var(--surface-2);font-family:var(--mono);font-size:.8rem;color:var(--text-3);font-weight:600;letter-spacing:.03em}
285
+ table.tbl tbody tr:last-child td{border-bottom:none}
286
+ table.tbl tbody tr:hover{background:var(--surface)}
287
+ table.tbl .yes{color:var(--green)} table.tbl .mono{font-family:var(--mono);font-size:.84rem;color:var(--accent)}
288
+
289
+ .tree{
290
+ font-family:var(--mono);font-size:.85rem;line-height:1.9;color:var(--text-2);
291
+ background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
292
+ padding:20px 22px;margin-top:24px;overflow-x:auto;white-space:pre;
293
+ }
294
+ .tree .dir{color:var(--accent-3)} .tree .file{color:var(--text)} .tree .note{color:var(--text-3)} .tree .cmt{color:var(--text-3)}
295
+
296
+ /* 步骤行 */
297
+ .steps{margin-top:30px;display:flex;flex-direction:column;gap:14px}
298
+ .step{display:flex;gap:16px;align-items:flex-start}
299
+ .step .n{
300
+ flex:0 0 30px;height:30px;border-radius:50%;display:grid;place-items:center;
301
+ font-family:var(--mono);font-size:.84rem;font-weight:700;color:var(--accent-ink);
302
+ background:var(--journey);
303
+ }
304
+ .step .c{padding-top:4px}
305
+ .step .c b{color:var(--text)}
306
+ .step .c .d{color:var(--text-2);font-size:.94rem;margin-top:2px}
307
+ .step .c code{background:var(--surface-2);padding:1px 7px;border-radius:5px;color:var(--accent);font-size:.85rem}
308
+
309
+ /* 双栏角色 */
310
+ .roles{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:30px}
311
+ .role{border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;background:var(--surface)}
312
+ .role h4{margin:0 0 6px;font-family:var(--mono);color:var(--accent);font-size:1rem;display:flex;align-items:center;gap:8px}
313
+ .role h4 .em{color:var(--text-3);font-weight:400}
314
+ .role ol{margin:12px 0 0;padding-left:20px;color:var(--text-2);font-size:.92rem}
315
+ .role li{margin-bottom:6px}
316
+ @media (max-width:720px){.roles{grid-template-columns:1fr}}
317
+
318
+ /* 编辑器使用说明 */
319
+ .editor-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin-top:32px}
320
+ .editor-card{
321
+ border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
322
+ padding:22px 24px;scroll-margin-top:80px;
323
+ }
324
+ .editor-card.featured{border-color:rgba(94,234,212,.35);background:linear-gradient(180deg,rgba(94,234,212,.04),var(--surface) 40%)}
325
+ .editor-card .top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
326
+ .editor-card h4{margin:0;font-family:var(--mono);font-size:1rem;color:var(--text)}
327
+ .editor-card .badge{
328
+ font-family:var(--mono);font-size:.68rem;padding:2px 8px;border-radius:999px;
329
+ border:1px solid var(--border);color:var(--text-3);
330
+ }
331
+ .editor-card .badge.cli{color:var(--sky);border-color:rgba(56,189,248,.35);background:rgba(56,189,248,.08)}
332
+ .editor-card .badge.ide{color:var(--accent);border-color:rgba(94,234,212,.35);background:rgba(94,234,212,.08)}
333
+ .editor-card p{margin:0 0 10px;color:var(--text-2);font-size:.9rem}
334
+ .editor-card ol{margin:0;padding-left:18px;color:var(--text-2);font-size:.88rem}
335
+ .editor-card li{margin-bottom:6px}
336
+ .editor-card .cmd{
337
+ margin-top:12px;font-family:var(--mono);font-size:.8rem;color:var(--accent);
338
+ background:var(--surface-2);border:1px solid var(--border-soft);
339
+ padding:8px 12px;border-radius:8px;word-break:break-all;
340
+ }
341
+ .editor-card .note{margin-top:10px;font-size:.82rem;color:var(--text-3);line-height:1.55}
342
+ @media (max-width:820px){.editor-grid{grid-template-columns:1fr}}
343
+
344
+ /* 门禁三栏 */
345
+ .gates{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:28px}
346
+ .gate{border:1px solid var(--border);border-radius:var(--r-md);padding:20px;background:var(--surface);position:relative}
347
+ .gate .lv{font-family:var(--mono);font-size:.72rem;color:var(--accent);letter-spacing:.05em}
348
+ .gate h4{margin:6px 0 8px;font-size:.98rem}
349
+ .gate p{margin:0;color:var(--text-2);font-size:.88rem}
350
+ .gate .f{font-family:var(--mono);font-size:.76rem;color:var(--text-3);margin-top:10px;word-break:break-all}
351
+ @media (max-width:720px){.gates{grid-template-columns:1fr}}
352
+
353
+ /* FAQ */
354
+ .faq{margin-top:30px;display:flex;flex-direction:column;gap:10px}
355
+ .faq-item{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);overflow:hidden}
356
+ .faq-q{
357
+ width:100%;text-align:left;background:none;border:none;color:var(--text);
358
+ font-family:var(--sans);font-size:1rem;font-weight:600;padding:18px 22px;cursor:pointer;
359
+ display:flex;justify-content:space-between;align-items:center;gap:14px;
360
+ }
361
+ .faq-q .chev{color:var(--text-3);transition:transform .2s;flex-shrink:0}
362
+ .faq-item.open .faq-q .chev{transform:rotate(45deg);color:var(--accent)}
363
+ .faq-a{max-height:0;overflow:hidden;transition:max-height .3s ease;color:var(--text-2);font-size:.94rem}
364
+ .faq-item.open .faq-a{max-height:400px}
365
+ .faq-a .inner{padding:0 22px 20px}
366
+ .faq-a .inner p{margin:0 0 8px}
367
+
368
+ /* footer */
369
+ footer{padding:56px 0 72px;border-top:1px solid var(--border-soft);text-align:center;color:var(--text-3);font-size:.9rem}
370
+ footer .brand{justify-content:center;margin-bottom:14px}
371
+ footer a{color:var(--text-2)}
372
+ footer .links{display:flex;gap:22px;justify-content:center;margin-top:14px;flex-wrap:wrap;font-family:var(--mono);font-size:.82rem}
373
+ footer .meta{display:flex;gap:18px;justify-content:center;margin-top:16px;flex-wrap:wrap;font-size:.84rem;color:var(--text-2)}
374
+ footer .meta span{display:inline-flex;align-items:center;gap:6px}
375
+ footer .meta .sep{color:var(--border)}
376
+ .hero-meta{margin-top:20px;font-size:.84rem;color:var(--text-3);display:flex;gap:16px;flex-wrap:wrap;font-family:var(--mono)}
377
+ .hero-meta span{display:inline-flex;align-items:center;gap:6px}
378
+
379
+ /* 滚动揭示 */
380
+ .reveal{opacity:0;transform:translateY(18px);transition:opacity .6s ease,transform .6s ease}
381
+ .reveal.in{opacity:1;transform:none}
382
+
383
+ /* 移动端导航 */
384
+ .menu-btn{display:none;background:none;border:1px solid var(--border);color:var(--text);border-radius:8px;padding:6px 10px;cursor:pointer}
385
+ @media (max-width:760px){
386
+ .menu-btn{display:block;margin-left:auto}
387
+ .nav-links.open{
388
+ display:flex;position:absolute;top:62px;left:0;right:0;flex-direction:column;
389
+ background:var(--surface);border-bottom:1px solid var(--border);padding:12px 24px;gap:2px;
390
+ }
391
+ }
392
+
393
+ /* 窄屏:长内容表格改为可水平滚动,避免撑破 body */
394
+ @media (max-width:720px){
395
+ table.tbl{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch }
396
+ table.tbl thead,table.tbl tbody{ width:100% }
397
+ .tree{ font-size:.78rem }
398
+ }
399
+
400
+ @media (prefers-reduced-motion:reduce){
401
+ *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
402
+ .reveal{opacity:1;transform:none}
403
+ }
404
+ </style>
405
+ </head>
406
+ <body>
407
+
408
+ <!-- 旅程进度轴 -->
409
+ <div class="journey-rail" aria-hidden="true"><div class="fill" id="railFill"></div></div>
410
+
411
+ <!-- 导航 -->
412
+ <header class="nav">
413
+ <div class="wrap nav-inner">
414
+ <div class="brand"><span class="dot"></span><span>kld-sdd</span></div>
415
+ <nav class="nav-links" id="navLinks">
416
+ <a href="#why">为什么</a>
417
+ <a href="#install">安装</a>
418
+ <a href="#workflow">工作流</a>
419
+ <a href="#skills">技能</a>
420
+ <a href="#docs">文档链</a>
421
+ <a href="#structure">目录</a>
422
+ <a href="#editors">编辑器</a>
423
+ <a href="#faq">FAQ</a>
424
+ </nav>
425
+ <a class="nav-cta" href="#install">开始初始化</a>
426
+ <button class="menu-btn" id="menuBtn" aria-label="菜单">☰</button>
427
+ </div>
428
+ </header>
429
+
430
+ <!-- Hero -->
431
+ <section class="hero" id="top">
432
+ <div class="wrap">
433
+ <div class="tag">规格驱动开发 · 一键部署 SDD 工作流</div>
434
+ <h1>kld-sdd<br><span class="grad">从入门到入土</span> <span class="dim">完整指南</span></h1>
435
+ <p class="pitch"><b>SDD(Specification-Driven Development)</b>是一种以文档链驱动 AI 编码的研发方法:先写清楚"要做什么",再让 AI 去实现——避免 AI 乱猜、反复返工。<code>kld-sdd</code> 帮你在项目里一键配好这套工作流所需的全部 AI 技能。</p>
436
+ <div class="ctas">
437
+ <a class="btn btn-primary" href="#install">$ npx kld-sdd</a>
438
+ <a class="btn btn-ghost" href="#workflow">查看完整工作流 →</a>
439
+ </div>
440
+ <div class="hero-meta">
441
+ <span>作者:郑浩天</span>
442
+ <span>更新:2026-07-11</span>
443
+ </div>
444
+
445
+ <div class="term">
446
+ <div class="term-bar">
447
+ <span class="d r"></span><span class="d y"></span><span class="d g"></span>
448
+ <span class="tt">your-project — zsh</span>
449
+ </div>
450
+ <div class="term-body">
451
+ <span class="c"># 1. 进入你的项目目录</span>
452
+ <span class="p">➜</span> <span class="k">cd</span> your-project<br>
453
+ <span class="c"># 2. 一键初始化 SDD 工作流</span>
454
+ <span class="p">➜</span> <span class="k">npx</span> kld-sdd<br>
455
+ <span class="o">╔════════════════════════════════════════╗</span><br>
456
+ <span class="o">║ KLD SDD 项目初始化工具 ║</span><br>
457
+ <span class="o">║ 内置 openSpec 标准模版 ║</span><br>
458
+ <span class="o">╚════════════════════════════════════════╝</span><br>
459
+ <span class="o">请选择您使用的 AI 编辑器(按提示选择即可)</span><br>
460
+ <span class="ok">✅ 初始化完成!已部署 11 个 opsx-* skills</span><span class="cursor"></span>
461
+ </div>
462
+ </div>
463
+
464
+ <div class="stats">
465
+ <div class="stat"><div class="n">10</div><div class="l">opsx skills</div></div>
466
+ <div class="stat"><div class="n">8</div><div class="l">AI 编辑器</div></div>
467
+ <div class="stat"><div class="n">4</div><div class="l">文档契约链</div></div>
468
+ <div class="stat"><div class="n">MIT</div><div class="l">开源协议</div></div>
469
+ </div>
470
+ </div>
471
+ </section>
472
+
473
+ <!-- 为什么是 SDD -->
474
+ <section id="why">
475
+ <div class="wrap">
476
+ <div class="sec-head reveal">
477
+ <span class="sec-num">§ 0</span>
478
+ <h2 class="sec-title">为什么需要 SDD</h2>
479
+ </div>
480
+ <p class="sec-sub reveal">直接让 AI 写代码,AI 会凭空假设大量细节,导致理解错位、反复返工。SDD 强制先把"要做什么"写成精确契约,AI 按契约实现。</p>
481
+
482
+ <div class="compare">
483
+ <div class="cmp bad reveal">
484
+ <span class="label">✕ 传统:直接让 AI 写</span>
485
+ <h4>"帮我加个用户认证"</h4>
486
+ <ul>
487
+ <li>AI 凭空假设认证方式、字段、边界</li>
488
+ <li>第一次跑通,细节全是错的</li>
489
+ <li>来回改 5 趟,越改越乱</li>
490
+ <li>需求散落在对话里,无法复用</li>
491
+ </ul>
492
+ </div>
493
+ <div class="cmp good reveal">
494
+ <span class="label">✓ SDD:先写契约再实现</span>
495
+ <h4>opsx-propose → spec → design → task</h4>
496
+ <ul>
497
+ <li><b>Why</b> 先写业务意图,AI 主动追问</li>
498
+ <li><b>What</b> 技术契约精确到参数/类型/QPS</li>
499
+ <li><b>How</b> 实现方案有据可依</li>
500
+ <li><b>Do</b> 拆成 5 分钟原子任务,按 DAG 执行</li>
501
+ </ul>
502
+ </div>
503
+ </div>
504
+ </div>
505
+ </section>
506
+
507
+ <!-- 安装 -->
508
+ <section id="install">
509
+ <div class="wrap">
510
+ <div class="sec-head reveal">
511
+ <span class="sec-num">§ 1</span>
512
+ <h2 class="sec-title">安装与初始化</h2>
513
+ </div>
514
+ <p class="sec-sub reveal">无需全局安装,进入项目目录后执行 <code>npx kld-sdd</code> 即可。Node.js ≥ 14。</p>
515
+
516
+ <div class="reveal">
517
+ <div class="codeblock">
518
+ <button class="copy" data-copy="cd your-project
519
+ npx kld-sdd">复制</button>
520
+ <pre><span class="k-c"># 进入项目目录,一行命令完成初始化</span>
521
+ <span class="k-p">➜</span> <span class="k-s">cd</span> your-project
522
+ <span class="k-p">➜</span> <span class="k-s">npx</span> <span class="k-f">kld-sdd</span></pre>
523
+ </div>
524
+ </div>
525
+
526
+ <div class="steps">
527
+ <div class="step reveal"><div class="n">1</div><div class="c"><b>选择编辑器</b><div class="d">运行 <code>npx kld-sdd</code> 后,按交互提示选择你使用的 AI 编辑器(如 Cursor、Claude Code、昆仑智码等)即可。</div></div></div>
528
+ <div class="step reveal"><div class="n">2</div><div class="c"><b>运行 openspec init</b><div class="d">自动检测并安装 <code>@fission-ai/openspec</code>,生成变更目录结构。</div></div></div>
529
+ <div class="step reveal"><div class="n">3</div><div class="c"><b>部署 opsx skills</b><div class="d">扁平一层部署到 <code>.*/skills/opsx-*/</code>,清理原生 openspec 命令与旧版嵌套 bundle。</div></div></div>
530
+ <div class="step reveal"><div class="n">4</div><div class="c"><b>部署遥测与门禁</b><div class="d">部署 <code>skywalk-sdd/log.cjs</code>、Git hooks 质量门禁、CI 兜底模板(仅 Git 项目),并初始化全局 <code>overview.md</code>。</div></div></div>
531
+ <div class="step reveal"><div class="n">5</div><div class="c"><b>更新 .gitignore</b><div class="d">自动忽略个人配置、telemetry 数据、worktree 临时目录。</div></div></div>
532
+ </div>
533
+ </div>
534
+ </section>
535
+
536
+ <!-- 工作流管线 -->
537
+ <section id="workflow">
538
+ <div class="wrap">
539
+ <div class="sec-head reveal">
540
+ <span class="sec-num">§ 2</span>
541
+ <h2 class="sec-title">核心工作流</h2>
542
+ </div>
543
+ <p class="sec-sub reveal">8 个阶段技能按顺序串成文档链 → 代码链 → 归档链。点击下方任一阶段,跳转查看详情。</p>
544
+
545
+ <div class="pipeline reveal">
546
+ <div class="pipeline-hint">▼ 点击阶段查看详解 ▼</div>
547
+ <div class="flow" id="flow">
548
+ <div class="stage" data-target="sk-propose"><span class="ic">🎯</span><div class="nm">propose</div><div class="rl">Why</div></div>
549
+ <span class="arrow">→</span>
550
+ <div class="stage" data-target="sk-spec"><span class="ic">📐</span><div class="nm">spec</div><div class="rl">What</div></div>
551
+ <span class="arrow">→</span>
552
+ <div class="stage" data-target="sk-design"><span class="ic">🏗️</span><div class="nm">design</div><div class="rl">How</div></div>
553
+ <span class="arrow">→</span>
554
+ <div class="stage" data-target="sk-task"><span class="ic">🧩</span><div class="nm">task</div><div class="rl">Do</div></div>
555
+ <span class="arrow">→</span>
556
+ <div class="stage" data-target="sk-check"><span class="ic">🔍</span><div class="nm">check</div><div class="rl">Verify</div></div>
557
+ <span class="arrow">→</span>
558
+ <div class="stage" data-target="sk-apply"><span class="ic">⚡</span><div class="nm">apply</div><div class="rl">Apply</div></div>
559
+ <span class="arrow">→</span>
560
+ <div class="stage" data-target="sk-test"><span class="ic">🧪</span><div class="nm">test</div><div class="rl">Test</div></div>
561
+ <span class="arrow">→</span>
562
+ <div class="stage" data-target="sk-archive"><span class="ic">📦</span><div class="nm">archive</div><div class="rl">Archive</div></div>
563
+ </div>
564
+ <div class="helpers">
565
+ <span class="helper"><span class="ic">🧭</span> opsx-explore · 浏览变更状态</span>
566
+ <span class="helper"><span class="ic">📚</span> opsx-knowledge · 业务知识库检索</span>
567
+ <span class="helper"><span class="ic">📜</span> opsx-rules · 生成/更新 Agent 规则</span>
568
+ </div>
569
+ </div>
570
+
571
+ <div class="steps" style="margin-top:36px">
572
+ <div class="step reveal"><div class="n">A</div><div class="c"><b>文档链(规划)</b><div class="d"><code>propose → spec → design → task</code> 把需求逐步精化为可执行契约,每步产出一份 markdown。</div></div></div>
573
+ <div class="step reveal"><div class="n">B</div><div class="c"><b>门禁(验证)</b><div class="d"><code>check</code> 在写代码前验证文档链的完整性/一致性/可执行性——只读检查,不修改文档。</div></div></div>
574
+ <div class="step reveal"><div class="n">C</div><div class="c"><b>实施链(执行)</b><div class="d"><code>apply → test</code> 按 DAG 依赖顺序逐任务实现,编译/测试门禁逐任务拦截,实时更新 tasks.md。</div></div></div>
575
+ <div class="step reveal"><div class="n">D</div><div class="c"><b>归档(收口)</b><div class="d"><code>archive</code> 真实移入 archive 目录,同步正式 specs,生成最终中文度量报告(md+html)。</div></div></div>
576
+ </div>
577
+ </div>
578
+ </section>
579
+
580
+ <!-- 技能详解 -->
581
+ <section id="skills">
582
+ <div class="wrap">
583
+ <div class="sec-head reveal">
584
+ <span class="sec-num">§ 3</span>
585
+ <h2 class="sec-title">11 个技能详解</h2>
586
+ </div>
587
+ <p class="sec-sub reveal">初始化后部署为扁平一层:<code>.claude/skills/opsx-*/SKILL.md</code> → 激活即用 <code>/opsx-propose</code>。</p>
588
+
589
+ <div class="skills-grid">
590
+ <div class="skill reveal" id="sk-propose" style="border-left-color:#5eead4">
591
+ <div class="top"><span class="idx">01</span><h3>opsx-propose <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">Why · 业务意图</span></div>
592
+ <p>创建业务意图文档,明确"为什么要做这件事"。把产品需求转化为结构化的业务意图文档。</p>
593
+ <p>没说清楚时,AI 会主动问 4 个问题:<b>痛点 / 目标 / 影响模块 / 约束</b>,并推导出 kebab-case 变更名(如 <code>add-user-auth</code>),生成 propose.md 后展示摘要让你确认。</p>
594
+ <div class="out">openspec/changes/&lt;name&gt;/propose.md</div>
595
+ </div>
596
+
597
+ <div class="skill reveal" id="sk-spec" style="border-left-color:#38bdf8">
598
+ <div class="top"><span class="idx">02</span><h3>opsx-spec <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">What · 技术契约</span></div>
599
+ <p>创建技术契约文档,明确"要实现什么 API 和规范"。<b>这是代码生成的唯一依据,必须精确无歧义。</b></p>
600
+ <p>读取 propose.md,发现模糊描述时主动追问(如"高性能" → 具体 QPS/RT 是多少?),确认 API 范围、性能指标、安全要求后生成 spec.md。</p>
601
+ <div class="red"><b>质量红线:</b>所有参数有类型、必填标记、范围约束、示例值;性能指标是具体数字(如 <code>&lt; 100ms P99</code>);边界场景覆盖正常流程 + 所有异常流程。</div>
602
+ <div class="out">openspec/changes/&lt;name&gt;/specs/&lt;capability&gt;/spec.md</div>
603
+ </div>
604
+
605
+ <div class="skill reveal" id="sk-design" style="border-left-color:#60a5fa">
606
+ <div class="top"><span class="idx">03</span><h3>opsx-design <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">How · 实现方案</span></div>
607
+ <p>创建技术实现方案,明确"怎么做"——聚焦本业务,不写全局架构。读取 propose + spec,分析约束和设计难点;存在多种方案时列出让你选择。</p>
608
+ <div class="red"><b>质量红线:</b>不写全局中间件或框架选型(那是项目级的事);接口调用明确到具体接口名和调用方式;数据库表结构到字段级别(类型、长度、索引)。</div>
609
+ <p>产出包含:时序图、模块设计、数据表结构、异常处理。</p>
610
+ <div class="out">openspec/changes/&lt;name&gt;/specs/&lt;capability&gt;/design.md</div>
611
+ </div>
612
+
613
+ <div class="skill reveal" id="sk-task" style="border-left-color:#818cf8">
614
+ <div class="top"><span class="idx">04</span><h3>opsx-task <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">Do · 原子任务</span></div>
615
+ <p>将 design.md 拆解为 AI 可执行的原子任务列表。<b>每个任务的标准:AI 能在 5 分钟内完成。</b></p>
616
+ <p>统计需要覆盖的实现点(API 数、模块数、数据表数),预估任务总数并确认拆解策略;发现循环依赖、复杂算法等风险时主动告知。</p>
617
+ <div class="red"><b>质量红线:</b>100% 覆盖 spec 的每个 API 和约束;100% 覆盖 design 的每个模块和接口;每个任务有明确验收标准和单测要求。</div>
618
+ <div class="out">openspec/changes/&lt;name&gt;/specs/&lt;capability&gt;/tasks.md</div>
619
+ </div>
620
+
621
+ <div class="skill reveal" id="sk-check" style="border-left-color:#a78bfa">
622
+ <div class="top"><span class="idx">05</span><h3>opsx-check <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">Verify · 质量门禁</span></div>
623
+ <p>质量门禁检查,验证文档链的完整性、一致性、算法正确性和可执行性。<b>在让 AI 写代码之前,先激活这个 skill。</b></p>
624
+ <ul class="tight">
625
+ <li><b>完整性</b>:4 个文档是否存在,章节是否完整</li>
626
+ <li><b>一致性</b>:spec 的 API 在 design 中是否有对应方案;字段命名是否一致</li>
627
+ <li><b>算法正确性</b>:数据流转无矛盾,异常覆盖边界,性能满足 spec 约束</li>
628
+ <li><b>可执行性</b>:每个任务 ≤ 5 分钟,DAG 无循环依赖,代码锚点存在</li>
629
+ </ul>
630
+ <p>Check 是<b>只读检查</b>,不修改任何文档;发现问题时列出严重问题和警告,并推荐修复命令(不自动执行)。</p>
631
+ <div class="out">结构化检查报告(通过 / 警告 / 失败)+ 修复建议</div>
632
+ </div>
633
+
634
+ <div class="skill reveal" id="sk-apply" style="border-left-color:#c084fc">
635
+ <div class="top"><span class="idx">06</span><h3>opsx-apply <span class="arg">[change-name] [capability-name]</span></h3><span class="role">Apply · 代码实施</span></div>
636
+ <p>针对单一 Capability,按 <b>DAG 依赖顺序</b>逐任务实施代码。这是把文档链变成真实代码的核心阶段。</p>
637
+ <ul class="tight">
638
+ <li><b>渐进式上下文加载</b>:overview → proposal → 当前 capability 的 spec/design/tasks</li>
639
+ <li><b>隔离红线</b>:⛔ 禁止加载同级其他 Capability 的文档</li>
640
+ <li><b>DAG 依赖拦截</b>:前置任务未完成则拦截,同层独立任务可并行派发子代理</li>
641
+ <li><b>逐任务门禁</b>:每完成一个任务,编译检查 + 测试门禁必须通过,立即更新 tasks.md checkbox</li>
642
+ <li><b>可选 worktree 并行</b>:解耦的 capability 各自 worktree 加速,做完按依赖合并回集成分支</li>
643
+ </ul>
644
+ <div class="red"><b>Git 只读策略:</b>禁止为度量自动 <code>git init/add/commit</code> 或创建分支;非 Git 项目用 <code>vcs_mode=no-git</code> 继续执行,不得中断。</div>
645
+ <div class="out">代码文件、测试文件、tasks.md checkbox 更新、telemetry 事件</div>
646
+ </div>
647
+
648
+ <div class="skill reveal" id="sk-test" style="border-left-color:#c4b5fd">
649
+ <div class="top"><span class="idx">07</span><h3>opsx-test</h3><span class="role">Test · 单元测试</span></div>
650
+ <p>执行单元测试并留 telemetry 证据。按 proposal.md 的 <code>test-strategy</code> 决定执行强度:</p>
651
+ <ul class="tight">
652
+ <li><code>tdd</code> → 强制:每个任务先写测试 RED,再实现到 GREEN</li>
653
+ <li><code>impl-first</code> → 警告:强制补跑测试</li>
654
+ <li><code>none</code> → 跳过</li>
655
+ </ul>
656
+ <p>Claude Code 的 <code>sdd-apply-test-gate.cjs</code> 会在 <code>log.cjs end</code>、worktree 收尾、会话 Stop 时自动校验——无真实测试证据则阻断。</p>
657
+ <div class="out">测试执行结果 + telemetry 证据(非占位数据)</div>
658
+ </div>
659
+
660
+ <div class="skill reveal" id="sk-archive" style="border-left-color:#d8b4fe">
661
+ <div class="top"><span class="idx">08</span><h3>opsx-archive <span class="arg">&lt;变更名称&gt;</span></h3><span class="role">Archive · 归档收口</span></div>
662
+ <p>安全结束变更生命周期:真实归档文档、同步正式 specs、记录 archive telemetry,并生成最终中文度量报告。</p>
663
+ <ul class="tight">
664
+ <li>询问归档原因:已完成 / 取消 / 搁置 / 其他</li>
665
+ <li>运行 <code>doctor</code> 自检,<code>severe_issues</code> 阻断归档</li>
666
+ <li>扫描 tasks 完成状态,未勾选项写入报告(不阻断归档)</li>
667
+ <li>一步执行 <code>archive-docs</code>:移动目录 + 同步 specs + 生成报告</li>
668
+ </ul>
669
+ <div class="out">archive/&lt;日期&gt;-&lt;name&gt;/ + report.md + report.html + execution-log.md</div>
670
+ </div>
671
+
672
+ <div class="skill reveal" id="sk-explore" style="border-left-color:#5eead4">
673
+ <div class="top"><span class="idx">09</span><h3>opsx-explore</h3><span class="role">辅助 · 浏览状态</span></div>
674
+ <p>浏览当前变更状态——查看项目里有哪些变更、各变更推进到哪个阶段、tasks 完成度如何。任何阶段都可随时调用,不改变状态。</p>
675
+ <div class="out">变更清单 + 阶段进度 + 任务完成度概览</div>
676
+ </div>
677
+
678
+ <div class="skill reveal" id="sk-knowledge" style="border-left-color:#5eead4">
679
+ <div class="top"><span class="idx">10</span><h3>opsx-knowledge</h3><span class="role">辅助 · 知识库检索</span></div>
680
+ <p>查询 MM/CO 业务知识库,辅助理解业务名词和领域规则。独立使用——编码中遇到不明业务名词时可随时调用,查询失败时继续实施,不偏离 tasks/spec。</p>
681
+ <div class="out">业务名词解释 + 领域规则参考</div>
682
+ </div>
683
+
684
+ <div class="skill reveal" id="sk-rules" style="border-left-color:#5eead4">
685
+ <div class="top"><span class="idx">11</span><h3>opsx-rules</h3><span class="role">辅助 · 规则生成</span></div>
686
+ <p>扫描项目结构后,为已部署的 Agent 生成 5 主题规则(架构/编码/测试/数据安全/Git 提交),或对比现有规则输出更新建议。各 Agent 规则位置与格式不同(.md / .mdc),skill 按落位矩阵自动写入。</p>
687
+ <div class="out">按 Agent 落位的规则文件 + 更新建议表</div>
688
+ </div>
689
+ </div>
690
+ </div>
691
+ </section>
692
+
693
+ <!-- 文档链与产物 -->
694
+ <section id="docs">
695
+ <div class="wrap">
696
+ <div class="sec-head reveal">
697
+ <span class="sec-num">§ 4</span>
698
+ <h2 class="sec-title">文档链与产物</h2>
699
+ </div>
700
+ <p class="sec-sub reveal">每个阶段都有明确的输入与产出,形成可追溯的文档→代码→报告链。</p>
701
+
702
+ <table class="tbl reveal">
703
+ <thead><tr><th>阶段</th><th>回答</th><th>输入</th><th>产出</th></tr></thead>
704
+ <tbody>
705
+ <tr><td class="mono">propose</td><td>Why</td><td>产品需求</td><td class="mono">propose.md</td></tr>
706
+ <tr><td class="mono">spec</td><td>What</td><td class="mono">propose.md</td><td class="mono">spec.md</td></tr>
707
+ <tr><td class="mono">design</td><td>How</td><td class="mono">propose + spec</td><td class="mono">design.md</td></tr>
708
+ <tr><td class="mono">task</td><td>Do</td><td class="mono">design.md</td><td class="mono">tasks.md</td></tr>
709
+ <tr><td class="mono">check</td><td>Verify</td><td class="mono">四文档链</td><td>检查报告(通过/警告/失败)</td></tr>
710
+ <tr><td class="mono">apply</td><td>Apply</td><td class="mono">overview→proposal→spec/design/tasks</td><td>代码 + 测试 + checkbox 更新</td></tr>
711
+ <tr><td class="mono">test</td><td>Test</td><td>代码 + test-strategy</td><td>测试证据(telemetry)</td></tr>
712
+ <tr><td class="mono">archive</td><td>Archive</td><td>变更全量</td><td class="mono">archive/ + report.md/.html + execution-log.md</td></tr>
713
+ </tbody>
714
+ </table>
715
+ </div>
716
+ </section>
717
+
718
+ <!-- 目录结构 -->
719
+ <section id="structure">
720
+ <div class="wrap">
721
+ <div class="sec-head reveal">
722
+ <span class="sec-num">§ 5</span>
723
+ <h2 class="sec-title">初始化后的目录结构</h2>
724
+ </div>
725
+ <p class="sec-sub reveal">运行 <code>npx kld-sdd</code> 后,你的项目会长出这些目录。</p>
726
+
727
+ <div class="tree reveal"><span class="dir">your-project/</span>
728
+ ├── <span class="dir">openspec/</span>
729
+ │ ├── <span class="dir">specs/</span>
730
+ │ │ └── <span class="file">overview.md</span> <span class="cmt"># 全局架构约束(数据字典、接口规范)</span>
731
+ │ └── <span class="dir">changes/</span> <span class="cmt"># 变更工作区</span>
732
+ │ └── <span class="dir">&lt;change-name&gt;/</span> <span class="cmt"># propose/spec/design/tasks 落在此处</span>
733
+ ├── <span class="dir">openspec-templates/</span> <span class="cmt"># 四文档参考模版(供参考)</span>
734
+ │ ├── <span class="file">propose.md</span>
735
+ │ ├── <span class="file">spec.md</span>
736
+ │ ├── <span class="file">design.md</span>
737
+ │ └── <span class="file">tasks.md</span>
738
+ ├── <span class="dir">.claude/</span>
739
+ │ ├── <span class="dir">skills/opsx-*/</span> <span class="cmt"># SDD skills(扁平一层,Claude 可识别)</span>
740
+ │ ├── <span class="dir">hooks/sdd-*.cjs</span> <span class="cmt"># Claude Code 门禁 hook(可选增强)</span>
741
+ │ └── <span class="file">settings.json</span> <span class="cmt"># hook 配置(含三层门禁绑定)</span>
742
+ ├── <span class="dir">.cursor/skills/opsx-*/</span> <span class="cmt"># Cursor 技能</span>
743
+ ├── <span class="dir">.codebuddy/skills/opsx-*/</span> <span class="cmt"># CodeBuddy 技能</span>
744
+ ├── <span class="dir">.kunlunzhima/</span> <span class="cmt"># 昆仑智码</span>
745
+ │ ├── <span class="dir">skills/opsx-*/</span> <span class="cmt"># SDD skills(扁平一层)</span>
746
+ │ └── <span class="dir">commands/opsx/</span> <span class="cmt"># OPSX command bridge(轻量入口,指向对应 Skill)</span>
747
+ ├── <span class="dir">.agents/skills/opsx-*/</span> <span class="cmt"># Codex 项目级技能</span>
748
+ └── <span class="dir">skywalk-sdd/</span> <span class="cmt"># Telemetry 数据目录</span>
749
+ ├── <span class="file">log.cjs</span> <span class="cmt"># 本地 Telemetry CLI</span>
750
+ ├── <span class="dir">events/</span> <span class="cmt"># 事件数据(gitignored)</span>
751
+ ├── <span class="dir">state/</span> <span class="cmt"># 活跃阶段状态(gitignored)</span>
752
+ └── <span class="dir">git-hooks/ · ci/</span> <span class="cmt"># 质量门禁 / CI 兜底模板</span></div>
753
+
754
+ <p class="lead reveal" style="margin-top:24px;font-size:.9rem">提示:Claude Code 只识别 <code>.claude/skills/&lt;skill-name&gt;/SKILL.md</code> 这一层;嵌套在 <code>skills/kld-sdd/opsx-*</code> 下不会被 <code>/</code> 菜单发现,所以 kld-sdd 部署时强制扁平化并清理旧版嵌套 bundle。昆仑智码用户可在 IDE 中使用 <code>.kunlunzhima/commands/opsx/</code> 下的 OPSX 命令入口。</p>
755
+ </div>
756
+ </section>
757
+
758
+ <!-- 编辑器 -->
759
+ <section id="editors">
760
+ <div class="wrap">
761
+ <div class="sec-head reveal">
762
+ <span class="sec-num">§ 6</span>
763
+ <h2 class="sec-title">支持的 AI 编辑器</h2>
764
+ </div>
765
+ <p class="sec-sub reveal">8 个编辑器统一使用 <code>SKILL.md</code> 技能格式,初始化时自动创建目录。下方为各编辑器的简要上手方式。</p>
766
+
767
+ <table class="tbl reveal">
768
+ <thead><tr><th>编辑器</th><th>技能目录</th><th>技能支持</th><th>自动创建</th></tr></thead>
769
+ <tbody>
770
+ <tr><td>Cursor</td><td class="mono">.cursor/skills/</td><td class="yes">✅</td><td>已存在时</td></tr>
771
+ <tr><td>Claude Code</td><td class="mono">.claude/skills/</td><td class="yes">✅</td><td>已存在时</td></tr>
772
+ <tr><td>CodeBuddy</td><td class="mono">.codebuddy/skills/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
773
+ <tr><td>Qoder</td><td class="mono">.qoder/skills/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
774
+ <tr><td>OpenCode</td><td class="mono">.opencode/skills/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
775
+ <tr><td>昆仑智码(KunlunZhima)</td><td class="mono">.kunlunzhima/skills/ + commands/opsx/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
776
+ <tr><td>WorkBuddy</td><td class="mono">.workbuddy/skills/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
777
+ <tr><td>Codex</td><td class="mono">.agents/skills/</td><td class="yes">✅</td><td class="yes">自动</td></tr>
778
+ </tbody>
779
+ </table>
780
+
781
+ <div class="editor-grid">
782
+ <div class="editor-card reveal" id="ed-cursor">
783
+ <div class="top"><h4>Cursor</h4><span class="badge ide">IDE</span></div>
784
+ <p>在项目根目录打开 Cursor,进入 Agent 对话即可使用 SDD 技能。</p>
785
+ <ol>
786
+ <li>打开项目后新建 Agent 对话</li>
787
+ <li>输入 <code>/opsx-propose &lt;变更名&gt;</code> 开始文档链</li>
788
+ <li>按工作流依次执行 spec → design → task → check → apply</li>
789
+ </ol>
790
+ <div class="cmd">/opsx-propose add-user-auth</div>
791
+ <p class="note">技能从 <code>.cursor/skills/opsx-*/</code> 自动加载;未部署自动 Hook,apply 前请确认已完成 check。</p>
792
+ </div>
793
+
794
+ <div class="editor-card reveal" id="ed-claude">
795
+ <div class="top"><h4>Claude Code</h4><span class="badge cli">CLI</span></div>
796
+ <p>终端自主编程环境,斜杠命令直接激活 Skill。</p>
797
+ <ol>
798
+ <li>在项目目录运行 <code>claude</code> 进入会话</li>
799
+ <li>输入 <code>/opsx-propose &lt;变更名&gt;</code> 创建业务意图</li>
800
+ <li>按顺序走完 propose → spec → design → task → check → apply → archive</li>
801
+ </ol>
802
+ <div class="cmd">/opsx-propose add-user-auth</div>
803
+ <p class="note">已部署 <code>.claude/hooks/</code> 三层门禁(L1 Skill / L2 写入 / L3 自检),apply 前自动校验 check 状态。</p>
804
+ </div>
805
+
806
+ <div class="editor-card featured reveal" id="ed-codebuddy">
807
+ <div class="top"><h4>CodeBuddy</h4><span class="badge cli">CLI</span></div>
808
+ <p>终端自主编程 Agent,与昆仑智码 CLI 同源;可自主读文件、执行命令、改代码。</p>
809
+ <ol>
810
+ <li>安装 CLI:<code>npm install -g @tencent-ai/codebuddy-code</code></li>
811
+ <li>在项目目录运行 <code>codebuddy</code>,企业环境选择 Enterprise Domain 登录</li>
812
+ <li>输入 <code>/opsx-propose &lt;变更名&gt;</code> 开始 SDD;<code>/skills</code> 查看已加载技能</li>
813
+ <li>初始化后运行 <code>/hooks</code> 审核 SDD Hook Pack,审批后门禁生效</li>
814
+ </ol>
815
+ <div class="cmd">/opsx-propose add-user-auth</div>
816
+ <p class="note">项目 Skills 在 <code>.codebuddy/skills/</code>,上下文文件为 <code>CODEBUDDY.md</code>。Windows 可用 <code>Alt+M</code> 切换权限模式;Hooks 比 Prompt 更可靠,适合 lint/test 门禁。</p>
817
+ </div>
818
+
819
+ <div class="editor-card featured reveal" id="ed-kunlunzhima">
820
+ <div class="top"><h4>昆仑智码</h4><span class="badge ide">IDE</span></div>
821
+ <p>企业级 AI 编程平台,覆盖 VSCode / IDEA 插件;Craft 模式适合多文件 SDD 实施。</p>
822
+ <ol>
823
+ <li>从企业平台安装 VSIX 插件,登录后打开项目</li>
824
+ <li>切换到 <b>Craft</b> 模式(Win: <code>Alt+I</code>)进行多文件编码</li>
825
+ <li>在对话中输入 <code>/opsx-propose</code> 等 OPSX 命令,或从 <code>.kunlunzhima/commands/opsx/</code> 入口调用</li>
826
+ <li>设置 → Skills 可查看/管理已加载的项目技能</li>
827
+ </ol>
828
+ <div class="cmd">/opsx-propose add-user-auth</div>
829
+ <p class="note">项目 Skills 在 <code>.kunlunzhima/skills/</code>,命令 bridge 在 <code>.kunlunzhima/commands/opsx/</code>(指向对应 SKILL.md)。项目上下文文件为 <code>KunLunZhiMa.md</code>;IDE 无自动 Hook,质量靠 Skill 自检与 check 阶段保障。纯问答用 Ask 模式(<code>Alt+L</code>)。</p>
830
+ </div>
831
+
832
+ <div class="editor-card reveal" id="ed-qoder">
833
+ <div class="top"><h4>Qoder</h4><span class="badge ide">IDE</span></div>
834
+ <p>IDE 内对话激活 Skill,适合编辑器内 SDD 文档编写与代码实施。</p>
835
+ <ol>
836
+ <li>在 Qoder 中打开已初始化的项目</li>
837
+ <li>新建对话,输入 <code>/opsx-propose &lt;变更名&gt;</code></li>
838
+ <li>按工作流推进各阶段技能</li>
839
+ </ol>
840
+ <div class="cmd">/opsx-propose add-user-auth</div>
841
+ <p class="note">技能从 <code>.qoder/skills/opsx-*/</code> 加载;未部署自动 Hook。</p>
842
+ </div>
843
+
844
+ <div class="editor-card reveal" id="ed-opencode">
845
+ <div class="top"><h4>OpenCode</h4><span class="badge cli">CLI</span></div>
846
+ <p>终端 Agent,通过 skill 斜杠命令驱动 SDD(无需独立 command 文件)。</p>
847
+ <ol>
848
+ <li>在项目目录启动 <code>opencode</code></li>
849
+ <li>输入 <code>/opsx-propose &lt;变更名&gt;</code>(skill 名即命令名)</li>
850
+ <li>不确定 skill 名时用 <code>/skills</code> 或 <code>Ctrl+P</code> 搜索;新版本可用 <code>$</code> 插入 skill pill</li>
851
+ <li>按 propose → spec → design → task → check → apply 推进</li>
852
+ </ol>
853
+ <div class="cmd">/opsx-propose add-user-auth</div>
854
+ <p class="note">技能在 <code>.opencode/skills/opsx-*/</code>;OpenCode 将 skill 注册为 <code>/opsx-*</code> 斜杠命令。未部署 Hook。若同时 init Claude/Codex,OpenCode 也会读取 <code>.claude/skills</code> / <code>.agents/skills</code>,同名 skill 可能冲突;纯 OpenCode 可设 <code>OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=true</code>。</p>
855
+ </div>
856
+
857
+ <div class="editor-card reveal" id="ed-workbuddy">
858
+ <div class="top"><h4>WorkBuddy</h4><span class="badge ide">IDE</span></div>
859
+ <p>IDE 助手,对话中激活 opsx 技能完成 SDD 流程。</p>
860
+ <ol>
861
+ <li>在 WorkBuddy 中打开项目</li>
862
+ <li>对话输入 <code>/opsx-propose &lt;变更名&gt;</code></li>
863
+ <li>按 propose → spec → design → task → check → apply 推进</li>
864
+ </ol>
865
+ <div class="cmd">/opsx-propose add-user-auth</div>
866
+ <p class="note">技能从 <code>.workbuddy/skills/opsx-*/</code> 加载。</p>
867
+ </div>
868
+
869
+ <div class="editor-card reveal" id="ed-codex">
870
+ <div class="top"><h4>Codex</h4><span class="badge cli">CLI</span></div>
871
+ <p>项目级 Agent,skills 部署在 <code>.agents/skills/</code> 供 Codex 会话引用。</p>
872
+ <ol>
873
+ <li>在项目根启动 Codex Agent 会话</li>
874
+ <li>输入 <code>/opsx-propose &lt;变更名&gt;</code> 或引用对应 Skill</li>
875
+ <li>按 SDD 工作流逐阶段执行</li>
876
+ </ol>
877
+ <div class="cmd">/opsx-propose add-user-auth</div>
878
+ <p class="note">初始化会自动创建 <code>.agents/skills/opsx-*/</code>;未部署自动 Hook。</p>
879
+ </div>
880
+ </div>
881
+ </div>
882
+ </section>
883
+
884
+ <!-- 团队协作 -->
885
+ <section id="team">
886
+ <div class="wrap">
887
+ <div class="sec-head reveal">
888
+ <span class="sec-num">§ 7</span>
889
+ <h2 class="sec-title">团队协作流程</h2>
890
+ </div>
891
+ <p class="sec-sub reveal">一次初始化,全员复用。规范随 Git 提交,新成员 clone 即得一致环境。</p>
892
+
893
+ <div class="roles">
894
+ <div class="role reveal">
895
+ <h4>👤 架构师 / TL <span class="em">(配置一次)</span></h4>
896
+ <ol>
897
+ <li>在项目中运行 <code>npx kld-sdd</code></li>
898
+ <li>将团队规范文档放入 <code>team-configs/</code></li>
899
+ <li>将自定义 skills 放入 <code>.*/skills/</code></li>
900
+ <li>提交到 Git</li>
901
+ </ol>
902
+ </div>
903
+ <div class="role reveal">
904
+ <h4>🌱 新成员 <span class="em">(onboarding)</span></h4>
905
+ <ol>
906
+ <li><code>git clone &lt;project&gt;</code></li>
907
+ <li><code>npm install</code></li>
908
+ <li><code>npx kld-sdd</code> 一键配置所有 AI 工具</li>
909
+ <li>激活 <code>/opsx-propose</code> 开始工作</li>
910
+ </ol>
911
+ </div>
912
+ </div>
913
+ </div>
914
+ </section>
915
+
916
+ <!-- 度量与门禁 -->
917
+ <section id="telemetry">
918
+ <div class="wrap">
919
+ <div class="sec-head reveal">
920
+ <span class="sec-num">§ 8</span>
921
+ <h2 class="sec-title">度量与三层门禁</h2>
922
+ </div>
923
+ <p class="sec-sub reveal">SkyWalk-SDD 把度量嵌入 skill 流程自动采集,无需配置 MCP;apply 前置三层门禁确保变更已通过 check。</p>
924
+
925
+ <p class="lead reveal" style="margin-top:24px"><b>SkyWalk-SDD Telemetry</b>:事件落 <code>skywalk-sdd/events/</code>(gitignored),最终报告落 <code>openspec/changes/&lt;change&gt;/reports/</code>,执行日志随 change 提交。</p>
926
+ <div class="codeblock reveal">
927
+ <button class="copy" data-copy="node skywalk-sdd/log.cjs start --command=propose --project=. --change=xxx
928
+ node skywalk-sdd/log.cjs end --event-id=evt_xxx --result=success --summary=&quot;...&quot;
929
+ node skywalk-sdd/log.cjs metrics --project=.">复制</button>
930
+ <pre><span class="k-c"># 阶段开始 / 结束 / 查看四维度指标</span>
931
+ <span class="k-p">➜</span> <span class="k-s">node</span> skywalk-sdd/log.cjs <span class="k-f">start</span> --command=propose --project=. --change=xxx
932
+ <span class="k-p">➜</span> <span class="k-s">node</span> skywalk-sdd/log.cjs <span class="k-f">end</span> --event-id=evt_xxx --result=success --summary=<span class="k-o">"..."</span>
933
+ <span class="k-p">➜</span> <span class="k-s">node</span> skywalk-sdd/log.cjs <span class="k-f">metrics</span> --project=.</pre>
934
+ </div>
935
+
936
+ <p class="lead reveal" style="margin-top:32px"><b>apply 前三层门禁体系</b>:</p>
937
+ <div class="gates">
938
+ <div class="gate reveal">
939
+ <div class="lv">L1 · SKILL 级</div>
940
+ <h4>PreToolUse(Skill) 阻断</h4>
941
+ <p>在 Skill 被调用的瞬间阻断:指定 change 精确检查是否完成 check;未指定则扫描所有变更,至少一个完成 check 才放行。</p>
942
+ <div class="f">sdd-skill-apply-gate.cjs</div>
943
+ </div>
944
+ <div class="gate reveal">
945
+ <div class="lv">L2 · 文件写入</div>
946
+ <h4>PreToolUse(Write|Edit) 阻断</h4>
947
+ <p>在文件写入操作时阻断,防止未通过 check 的变更直接落代码。与 L1 形成双重保障。</p>
948
+ <div class="f">sdd-apply-gate.cjs</div>
949
+ </div>
950
+ <div class="gate reveal">
951
+ <div class="lv">L3 · SKILL 自检</div>
952
+ <h4>技能内部自检</h4>
953
+ <p>opsx-apply SKILL.md Step 1.2 作为最后一道防线,主动确认 check 已完成,未完成强制拒绝。</p>
954
+ <div class="f">opsx-apply/SKILL.md §1.2</div>
955
+ </div>
956
+ </div>
957
+ </div>
958
+ </section>
959
+
960
+ <!-- FAQ -->
961
+ <section id="faq">
962
+ <div class="wrap">
963
+ <div class="sec-head reveal">
964
+ <span class="sec-num">§ 9</span>
965
+ <h2 class="sec-title">常见问题</h2>
966
+ </div>
967
+ <div class="faq">
968
+ <div class="faq-item reveal">
969
+ <button class="faq-q">openspec 是什么,必须安装吗?<span class="chev">+</span></button>
970
+ <div class="faq-a"><div class="inner"><p><code>openspec</code> 是管理 SDD 变更目录的 CLI 工具(负责创建变更目录和读取指导规则)。运行 <code>npx kld-sdd</code> 时会自动安装;若安装失败,手动创建 <code>openspec/changes/&lt;name&gt;/</code> 目录后 skills 仍然可用。</p></div></div>
971
+ </div>
972
+ <div class="faq-item reveal">
973
+ <button class="faq-q">我用 CodeBuddy 或 Codex,目录不存在怎么办?<span class="chev">+</span></button>
974
+ <div class="faq-a"><div class="inner"><p>不用担心,运行 <code>npx kld-sdd</code> 会自动创建 <code>.codebuddy/skills/</code>、<code>.kunlunzhima/</code>、<code>.agents/skills/</code> 等目录。只需在初始化时按提示选择对应编辑器即可。</p></div></div>
975
+ </div>
976
+ <div class="faq-item reveal">
977
+ <button class="faq-q">opsx-propose 和直接让 AI 写代码有什么区别?<span class="chev">+</span></button>
978
+ <div class="faq-a"><div class="inner"><p>直接让 AI 写代码,AI 会凭空假设很多细节,导致返工。SDD 流程强制先把"要做什么"写清楚——propose 问清意图、spec 写成精确契约、design 定方案、task 拆成原子任务,AI 按契约实现,减少歧义和返工。</p></div></div>
979
+ </div>
980
+ <div class="faq-item reveal">
981
+ <button class="faq-q">团队规范已经有了,怎么让 AI 每次都遵守?<span class="chev">+</span></button>
982
+ <div class="faq-a"><div class="inner"><p>将规范文档转为 skill 文件,部署到 <code>.*/skills/</code> 目录后,AI 编辑器激活该 skill 时会自动遵守这些规范。规范随 Git 提交,全员一致。</p></div></div>
983
+ </div>
984
+ <div class="faq-item reveal">
985
+ <button class="faq-q">check 阶段会修改我的文档吗?<span class="chev">+</span></button>
986
+ <div class="faq-a"><div class="inner"><p>不会。check 是<b>只读检查</b>,即使发现代码相关问题也只记录在检查报告中,不自动修复。文档修复由你决定,推荐运行对应的 <code>/opsx-spec</code> 或 <code>/opsx-design</code> 修复;代码修复在 <code>/opsx-apply</code> 阶段进行。</p></div></div>
987
+ </div>
988
+ <div class="faq-item reveal">
989
+ <button class="faq-q">apply 会自动帮我 git commit 吗?<span class="chev">+</span></button>
990
+ <div class="faq-a"><div class="inner"><p>不会。apply 遵循 <b>Git 只读策略</b>——禁止为度量自动 <code>git init/add/commit</code> 或创建分支;Git 仅作为可选度量数据源(只读 <code>git rev-parse HEAD</code> 等)。非 Git 项目用 <code>vcs_mode=no-git</code> 继续执行。只有用户明确要求时才允许提交。</p></div></div>
991
+ </div>
992
+ </div>
993
+ </div>
994
+ </section>
995
+
996
+ <!-- footer -->
997
+ <footer>
998
+ <div class="wrap">
999
+ <div class="brand"><span class="dot"></span><span>kld-sdd</span></div>
1000
+ <p>规格驱动开发 · 从入门到入土完整指南</p>
1001
+ <div class="meta">
1002
+ <span>作者:郑浩天</span>
1003
+ <span class="sep">·</span>
1004
+ <span>更新日期:2026-07-12</span>
1005
+ </div>
1006
+ <div class="links">
1007
+ <a href="https://www.npmjs.com/package/@hunterzheng/kld-sdd" target="_blank" rel="noopener">npm</a>
1008
+ <a href="#top">回到顶部 ↑</a>
1009
+ </div>
1010
+ <p style="margin-top:18px;opacity:.6">MIT License · 本页基于 kld-sdd 真实 README 与 SKILL.md 生成</p>
1011
+ </div>
1012
+ </footer>
1013
+
1014
+ <script>
1015
+ (function(){
1016
+ var reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
1017
+
1018
+ /* ── 旅程进度轴填充 ── */
1019
+ var rail = document.getElementById('railFill');
1020
+ function updateRail(){
1021
+ var h = (window.scrollY / Math.max(1, document.body.scrollHeight - window.innerHeight)) * 100;
1022
+ rail.style.height = Math.min(100, Math.max(0, h)) + '%';
1023
+ }
1024
+ updateRail();
1025
+ window.addEventListener('scroll', updateRail, {passive:true});
1026
+ window.addEventListener('resize', updateRail);
1027
+
1028
+ /* ── 滚动揭示 ── */
1029
+ if (reduce) {
1030
+ document.querySelectorAll('.reveal').forEach(function(el){ el.classList.add('in'); });
1031
+ } else if ('IntersectionObserver' in window) {
1032
+ var io = new IntersectionObserver(function(entries){
1033
+ entries.forEach(function(e){ if (e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); } });
1034
+ }, {threshold:0.08, rootMargin:'0px 0px -40px 0px'});
1035
+ document.querySelectorAll('.reveal').forEach(function(el){ io.observe(el); });
1036
+ } else {
1037
+ document.querySelectorAll('.reveal').forEach(function(el){ el.classList.add('in'); });
1038
+ }
1039
+
1040
+ /* ── 导航 active 高亮 ── */
1041
+ var navLinks = Array.prototype.slice.call(document.querySelectorAll('.nav-links a'));
1042
+ var sections = navLinks.map(function(a){ return document.querySelector(a.getAttribute('href')); }).filter(Boolean);
1043
+ if ('IntersectionObserver' in window) {
1044
+ var spy = new IntersectionObserver(function(entries){
1045
+ entries.forEach(function(e){
1046
+ if (e.isIntersecting){
1047
+ var id = '#' + e.target.id;
1048
+ navLinks.forEach(function(a){
1049
+ a.style.color = (a.getAttribute('href') === id) ? 'var(--accent)' : '';
1050
+ a.style.background = (a.getAttribute('href') === id) ? 'var(--surface-2)' : '';
1051
+ });
1052
+ }
1053
+ });
1054
+ }, {rootMargin:'-45% 0px -50% 0px'});
1055
+ sections.forEach(function(s){ spy.observe(s); });
1056
+ }
1057
+
1058
+ /* ── 移动端菜单 ── */
1059
+ var menuBtn = document.getElementById('menuBtn');
1060
+ var navLinksEl = document.getElementById('navLinks');
1061
+ menuBtn && menuBtn.addEventListener('click', function(){ navLinksEl.classList.toggle('open'); });
1062
+ navLinksEl && navLinksEl.addEventListener('click', function(e){
1063
+ if (e.target.tagName === 'A') navLinksEl.classList.remove('open');
1064
+ });
1065
+
1066
+ /* ── 管线阶段点击跳转 + 高亮 ── */
1067
+ document.querySelectorAll('.stage').forEach(function(stage){
1068
+ stage.addEventListener('click', function(){
1069
+ var id = stage.getAttribute('data-target');
1070
+ var target = document.getElementById(id);
1071
+ if (!target) return;
1072
+ document.querySelectorAll('.stage').forEach(function(s){ s.classList.remove('active'); });
1073
+ stage.classList.add('active');
1074
+ var top = target.getBoundingClientRect().top + window.scrollY - 80;
1075
+ window.scrollTo({top: top, behavior: reduce ? 'auto' : 'smooth'});
1076
+ /* 短暂高亮目标卡 */
1077
+ target.style.boxShadow = '0 0 0 2px var(--accent)';
1078
+ setTimeout(function(){ target.style.boxShadow = ''; }, 1600);
1079
+ });
1080
+ });
1081
+
1082
+ /* ── FAQ 折叠 ── */
1083
+ document.querySelectorAll('.faq-q').forEach(function(btn){
1084
+ btn.addEventListener('click', function(){
1085
+ var item = btn.parentElement;
1086
+ var wasOpen = item.classList.contains('open');
1087
+ document.querySelectorAll('.faq-item').forEach(function(i){ i.classList.remove('open'); });
1088
+ if (!wasOpen) item.classList.add('open');
1089
+ });
1090
+ });
1091
+
1092
+ /* ── 代码块复制 ── */
1093
+ document.querySelectorAll('.copy').forEach(function(btn){
1094
+ btn.addEventListener('click', function(){
1095
+ var text = btn.getAttribute('data-copy') || '';
1096
+ /* 去掉行首 prompt 装饰,复制纯净命令 */
1097
+ var clean = text.replace(/➜\s*/g, '').replace(/#\s.*$/gm, '').trim();
1098
+ if (navigator.clipboard) {
1099
+ navigator.clipboard.writeText(clean).then(function(){
1100
+ var orig = btn.textContent; btn.textContent = '已复制 ✓';
1101
+ setTimeout(function(){ btn.textContent = orig; }, 1400);
1102
+ });
1103
+ }
1104
+ });
1105
+ });
1106
+ })();
1107
+ </script>
1108
+ </body>
1109
+ </html>